如何以编程方式从.opus音频文件中获取.m4a音频文件

时间:2017-09-10 22:21:16

标签: android audio m4a opus

我正在开发一个管理Whatsapp语音笔记的应用程序。 前段时间WhatsApp开始使用 opus 文件格式保存语音笔记,而不是像以前那样使用 aac

我的应用程序获取一个URI(通过隐式意图),该URI指向存储在WhatsApp文件夹中的 opus 语音笔记。

由于 opus 音频文件无法在许多设备和许多应用程序(例如Viber)上播放,我想在单独的文件中创建 m4a 格式我从WhatsApp获得的 opus 音频文件的版本。

我试图做的是: 我使用ContentResolver和openInputStream()来获取由Uri表示的内容的InputStream,我通过隐式intent获取。然后我在我的应用程序文件夹中的文件上创建了一个FileOutputStream。 我使用了一条完成了" .m4a"而不是" .opus"。

像这样:

try {
                InputStream inputStream = getContentResolver().openInputStream(uriFromExternalIntent);
                String OUTPUT_DIRECTORY = Environment.getExternalStorageDirectory() + "/Audios/recordings/";


                boolean exists = (new File(OUTPUT_DIRECTORY)).exists();
                if (!exists) {
                    new File(OUTPUT_DIRECTORY).mkdirs();
                }

                Calendar c = Calendar.getInstance();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
                String strDate = sdf.format(c.getTime());
                //Setting the output file complete final path
                String OUTPUT_FILE = OUTPUT_DIRECTORY + strDate + ".m4a";
                File outputFile = new File(OUTPUT_FILE);
                OutputStream out = null;
                try {
                    out = new FileOutputStream(outputFile);
                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = inputStream.read(buf)) > 0) {
                        out.write(buf, 0, len);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (out != null) {
                            out.close();
                        }
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

将文件保存在以" .m4a"结尾的路径中。在API 24设备上,我能够在我的应用程序内以及WhatsApp,Viber或Telegram等应用程序中播放文件。 但是在API 23上,除了WhatsApp之外,相同的代码在每个应用程序上都会出错。

总结一下,我正在寻找一种方法,以编程方式从指向.opus音频文件的URI中获取.m4a音频文件。

有些应用程序能够在不显示任何转换的情况下执行此操作,因此我想有一个技巧可以轻松完成而无需转换。 有什么建议吗?

1 个答案:

答案 0 :(得分:1)

使用不同的扩展程序复制文件绝对不是可行的方法。

根据您希望应用程序的强大程度以及您愿意投入多少工作,您有几个选择。

便宜而简单的方法是找到一个免费的在线文件转换工具,您可以尝试在您的应用中使用它。我不打算链接任何特定的服务,因为我不推荐这种方法。您的应用程序将受到您为稳定性而选择的服务的支配。它很可能是可行的,但它也非常难看。

更合理的方法是在应用程序中实际转换文件。最简单的方法是找到一个能够在目标和源格式之间进行转换的库。我不知道任何Android / Java音频转换库,但我知道一个名为SoX的体面C库,它有几个Java包装器可用(例如,herehere) 。第一个链接(Guardian项目)是为Android设计的,包括SoX和FFMpeg。它不是特别轻便。第二个似乎不适用于Android,因此您可能需要处理寻找合适的二进制文件或自己构建SoX(提示:Guardian项目中的二进制文件是“res / raw”)。我查看了SoX以确认它支持Opus格式。另外,FFMpeg也支持Opus。一旦你在项目中得到SoX或FFMpeg和Java包装器,你应该可以使用它们来转换文件。根据您的使用情况,您应该注意您选择使用的库的许可证。

转换文件的难点是编写自己的编解码器。您可以使用MediaCodec类在Android Java中执行此操作,但Android MediaExtractor不了解Opus(据我所知),因此这不是一项简单的尝试。我怀疑你想走这条路。