Android 如何以编程方式从.opus音频文件获取.m4a音频文件
我正在开发一个管理Whatsapp语音笔记的应用程序。 不久前,WhatsApp开始使用opus文件格式保存语音备忘,而不是像以前那样使用aac 我的应用程序获得一个URI(通过隐式意图),该URI指向存储在WhatsApp文件夹中的opus语音备忘 由于opus音频文件不可能在许多设备和应用程序中播放(例如Viber),因此我想在一个单独的文件中创建一个m4a格式的opus音频文件,该文件是我从WhatsApp获得的 我想做的是: 我使用ContentResolver和openInputStream()在通过隐式意图获取的Uri表示的内容上获取InputStream。然后,我在我的应用程序文件夹中的一个文件上创建了一个FileOutputStream。 我使用了一条以“.m4a”结尾的路径,而不是“.opus” 像这样:Android 如何以编程方式从.opus音频文件获取.m4a音频文件,android,audio,m4a,opus,Android,Audio,M4a,Opus,我正在开发一个管理Whatsapp语音笔记的应用程序。 不久前,WhatsApp开始使用opus文件格式保存语音备忘,而不是像以前那样使用aac 我的应用程序获得一个URI(通过隐式意图),该URI指向存储在WhatsApp文件夹中的opus语音备忘 由于opus音频文件不可能在许多设备和应用程序中播放(例如Viber),因此我想在一个单独的文件中创建一个m4a格式的opus音频文件,该文件是我从WhatsApp获得的 我想做的是: 我使用ContentResolver和openInputStr
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等应用程序中播放该文件。
但在API23上,除了WhatsApp之外,每个应用程序都会出现相同的代码错误
总而言之,我正在寻找一种从指向.opus音频文件的URI以编程方式获取.m4a音频文件的方法
有一些应用程序能够做到这一点,而不显示任何类型的转换,所以我想有一个技巧可以轻松做到这一点,而不转换。
有什么建议吗?用不同的扩展名复制文件肯定不是一种好办法 你有几个选择,这取决于你希望你的应用程序有多强大,以及你愿意投入多少工作 便宜而简单的方法是找到一个免费的在线文件转换工具,你可以尝试在你的应用程序中利用它。我不会费心去链接任何特定的服务,因为我不推荐这种方法。你的应用程序的稳定性将取决于你选择的服务。这很可能是可行的,但也很难看 更合理的方法是在应用程序中实际转换文件。最简单的方法是找到一个能够在目标格式和源格式之间转换的库。我不知道有任何Android/Java音频转换库,但我知道有一个叫做C的不错的库,它有几个Java包装器(例如,和)。第一个链接(Guardian项目)是为Android制作的,包括SoX和FFMpeg。它不是特别轻。第二个似乎不适用于Android,因此您可能需要自己寻找合适的二进制文件或构建SoX(提示:Guardian项目中的二进制文件位于“res/raw”中)。我查看了SoX以确认它支持Opus格式。另外,FFMpeg还支持Opus。在项目中适当地连接SoX或FFMpeg和Java包装器之后,您应该能够使用它们来转换文件。根据您的用例,您应该注意您选择使用的库的许可证
转换文件的困难方法是编写自己的编解码器。您可以使用该类在Android Java中实现这一点,但Android不理解Opus(据我所知),因此这不是一个简单的尝试。我怀疑你是否想走这条路。用不同的扩展名复制文件肯定不是一条路 你有几个选择,这取决于你希望你的应用程序有多强大,以及你愿意投入多少工作 便宜而简单的方法是找到一个免费的在线文件转换工具,你可以尝试在你的应用程序中利用它。我不会费心去链接任何特定的服务,因为我不推荐这种方法。你的应用程序的稳定性将取决于你选择的服务。这很可能是可行的,但也很难看 更合理的方法是在应用程序中实际转换文件。最简单的方法是找到一个能够在目标格式和源格式之间转换的库。我不知道有任何Android/Java音频转换库,但我知道有一个叫做C的不错的库,它有几个Java包装器(例如,和)。第一个链接(Guardian项目)是为Android制作的,包括SoX和FFMpeg。它不是特别轻。第二个似乎不适用于Android,因此您可能需要自己寻找合适的二进制文件或构建SoX(提示:Guardian项目中的二进制文件位于“res/raw”中)。我查看了SoX以确认它支持Opus格式。另外,FFMpeg还支持Opus。在项目中适当地连接SoX或FFMpeg和Java包装器之后,您应该能够使用它们来转换文件。根据您的用例,您应该注意您选择使用的库的许可证
转换文件的困难方法是编写自己的编解码器。您可以使用该类在Android Java中实现这一点,但Android不理解Opus(据我所知),因此这不是一个简单的尝试。我怀疑你是否愿意走这条路。谢谢你@Dave,我将进一步研究这些图书馆。出于好奇:当我复制扩展名为.m4a的.opus文件时,API 24上的一切工作正常吗?它是否能够在不更改扩展名的情况下在API 24上播放.opus文件?我的第一个想法是,它能够播放Opus格式,并查看文件数据以确定它是什么类型的文件,而不是扩展名。在API 24上,当我从应用程序共享到Viber或用.m4a扩展名发送Opus音频时,我能够在聊天室中的两个应用程序上播放它。相反,当文件扩展名为.opus时,两个应用程序都会要求外部opus播放器播放该文件(因此扩展名似乎是相关的)。但同样的事情在API 23上不起作用:当我尝试在Vib上打开扩展名为.m4a的opus文件时