我正在开发一个管理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 回答
使用不同的扩展名复制文件绝对不是可行的方法 .
您有几个选项,具体取决于您希望应用程序的强大程度以及您愿意投入多少工作量 .
便宜而简单的方法是找到一个免费的在线文件转换工具,您可以尝试在您的应用程序中利用它 . 我不打算链接任何特定的服务,因为我不推荐这种方法 . 您的应用程序将受到您为稳定性而选择的服务的支配 . 它很可能是可行的,但它也非常难看 .
更合理的方法是在应用程序中实际转换文件 . 最简单的方法是找到一个能够在目标和源格式之间进行转换的库 . 我不知道任何Android / Java音频转换库,但我知道一个名为SoX的体面C库,它有几个Java包装器可用(例如,here和here) . 第一个链接(Guardian项目)是为Android设计的,包括SoX和FFMpeg . 它似乎不适用于Android,因此您可能需要处理寻找合适的二进制文件或自己构建SoX(提示:Guardian项目中的二进制文件位于"res/raw") . 我查看了SoX以确认它支持Opus格式 . 另外,FFMpeg也支持Opus . 一旦你在项目中得到SoX或FFMpeg和Java包装器,你应该可以使用它们来转换文件 . 根据您的使用情况,您应该注意您选择使用的库的许可证 .
转换文件的难点是编写自己的编解码器 . 您可以使用MediaCodec类在Android Java中执行此操作,但Android MediaExtractor不了解Opus(据我所知),因此这不是一个简单的尝试 . 我怀疑你想走这条路 .