Android: 从文件uri读取音频数据
Android: Read audio data from file uri
我想分析一个音频文件(尤其是 mp3),用户可以 select 并确定播放的音符、播放时间以及播放频率。
我的电脑上已经有了一些工作代码,但我希望也能在我的 phone 上使用它。
然而,为了做到这一点,我需要访问音频文件的字节。在我的电脑上,我可以打开一个流并使用 AudioFormat 对其进行解码,然后逐帧读取()字节。
查看 Android 开发者论坛,我只能找到 类 和播放文件(无法访问字节)或记录到文件(我想从文件中读取)的示例).
我非常有信心可以设置文件选择器,但是一旦我从中获得 Uri,我就不知道如何获取流或字节了。
任何帮助将不胜感激:)
编辑:是否有类似的解决方案? Android - Read a File
我不知道我是否可以用这种方式解码音频文件,或者 Android API...
是否会有任何问题
所以我通过以下方式解决了:
使用
获取一个 InputStream
final InputStream inputStream = getContentResolver().openInputStream(selectedUri);
然后将其传递到此函数中并使用 JLayer 中的 类 对其进行解码:
private synchronized void decode(InputStream in)
throws BitstreamException, DecoderException {
ArrayList<Short> output = new ArrayList<>(1024);
Bitstream bitstream = new Bitstream(in);
Decoder decoder = new Decoder();
float total_ms = 0f;
float nextNotify = -1f;
boolean done = false;
while (! done) {
Header frameHeader = bitstream.readFrame();
if (total_ms > nextNotify) {
mListener.OnDecodeUpdate((int) total_ms);
nextNotify += 500f;
}
if (frameHeader == null) {
done = true;
} else {
total_ms += frameHeader.ms_per_frame();
SampleBuffer buffer = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream); // CPU intense
if (buffer.getSampleFrequency() != 44100 || buffer.getChannelCount() != 2) {
throw new DecoderException("mono or non-44100 MP3 not supported", null);
}
short[] pcm = buffer.getBuffer();
for (int i = 0; i < pcm.length-1; i += 2) {
short l = pcm[i];
short r = pcm[i+1];
short mono = (short) ((l + r) / 2f);
output.add(mono); // RAM intense
}
}
bitstream.closeFrame();
}
bitstream.close();
mListener.OnDecodeComplete(output);
}
完整的项目(如果您想查看详情)可以在这里找到:
https://github.com/S7uXN37/MusicInterpreterStudio/
我想分析一个音频文件(尤其是 mp3),用户可以 select 并确定播放的音符、播放时间以及播放频率。
我的电脑上已经有了一些工作代码,但我希望也能在我的 phone 上使用它。
然而,为了做到这一点,我需要访问音频文件的字节。在我的电脑上,我可以打开一个流并使用 AudioFormat 对其进行解码,然后逐帧读取()字节。
查看 Android 开发者论坛,我只能找到 类 和播放文件(无法访问字节)或记录到文件(我想从文件中读取)的示例).
我非常有信心可以设置文件选择器,但是一旦我从中获得 Uri,我就不知道如何获取流或字节了。
任何帮助将不胜感激:)
编辑:是否有类似的解决方案? Android - Read a File 我不知道我是否可以用这种方式解码音频文件,或者 Android API...
是否会有任何问题所以我通过以下方式解决了:
使用
获取一个 InputStreamfinal InputStream inputStream = getContentResolver().openInputStream(selectedUri);
然后将其传递到此函数中并使用 JLayer 中的 类 对其进行解码:
private synchronized void decode(InputStream in)
throws BitstreamException, DecoderException {
ArrayList<Short> output = new ArrayList<>(1024);
Bitstream bitstream = new Bitstream(in);
Decoder decoder = new Decoder();
float total_ms = 0f;
float nextNotify = -1f;
boolean done = false;
while (! done) {
Header frameHeader = bitstream.readFrame();
if (total_ms > nextNotify) {
mListener.OnDecodeUpdate((int) total_ms);
nextNotify += 500f;
}
if (frameHeader == null) {
done = true;
} else {
total_ms += frameHeader.ms_per_frame();
SampleBuffer buffer = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream); // CPU intense
if (buffer.getSampleFrequency() != 44100 || buffer.getChannelCount() != 2) {
throw new DecoderException("mono or non-44100 MP3 not supported", null);
}
short[] pcm = buffer.getBuffer();
for (int i = 0; i < pcm.length-1; i += 2) {
short l = pcm[i];
short r = pcm[i+1];
short mono = (short) ((l + r) / 2f);
output.add(mono); // RAM intense
}
}
bitstream.closeFrame();
}
bitstream.close();
mListener.OnDecodeComplete(output);
}
完整的项目(如果您想查看详情)可以在这里找到: https://github.com/S7uXN37/MusicInterpreterStudio/