首页 文章

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

提问于
浏览
1

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

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

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

我试图做的是:我使用ContentResolver和openInputStream()来获取由Uri表示的内容的InputStream,我通过隐式意图获得 . 然后我在我的应用程序文件夹中的文件上创建了一个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();
                    }
                }

通过在API 24设备上以“.m4a”结尾的路径保存文件,我可以在我的应用程序内以及WhatsApp,Viber或Telegram等应用程序中播放该文件 . 但是在API 23上,相同的代码在WhatsApp之外的每个应用程序上都会出错 .

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

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

1 回答

  • 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(据我所知),因此这不是一个简单的尝试 . 我怀疑你想走这条路 .

相关问题