android - 在 Android 中播放内存流中的 WAV 音频
问题描述
我将从 REST 服务接收非常短的音频数据。它们将以 WAV 格式到达。然后我需要在 Android 设备上播放它们。我想在不将数据保存到文件的情况下做到这一点——它只会让它变得比需要的更复杂。但是我不能让它从内存流中工作。下面是我正在使用的测试代码(使用资产文件夹中的 .wav 文件):
public void PlayAudioFile(string fileName)
{
bool useMemoryStream = true;
if (useMemoryStream)
{
//this doesn't work
MemoryStream ms = GetMS(fileName);
byte[] msData = new byte[ms.Length];
ms.Position = 0;
ms.Read(msData, 0, (int)ms.Length);
String base64EncodedString = Base64.EncodeToString(msData, Base64Flags.Default);
String url = "data:audio/wav;base64," + base64EncodedString;
MediaPlayer player = new MediaPlayer();
player.Prepared += (s, e) =>
{
player.Start();
};
player.SetDataSource(url);
player.Prepare();
}
else
{
//this works
MediaPlayer player = new MediaPlayer();
var fd = global::Android.App.Application.Context.Assets.OpenFd(fileName);
player.Prepared += (s, e) =>
{
player.Start();
};
player.SetDataSource(fd.FileDescriptor, fd.StartOffset, fd.Length);
player.Prepare();
}
}
private MemoryStream GetMS(string fileName)
{
MemoryStream ms = new MemoryStream();
Context context = Android.App.Application.Context;
using (System.IO.Stream stream = context.Assets.Open(fileName))
{
stream.CopyTo(ms);
}
return ms;
}
当我从文件中播放它时它很好,但是内存流方法给了我一个 IOException Prepare Failed 错误。我怀疑问题可能出在音频/wav 值上。我找不到任何有关此支持值的文档。当我尝试使用 MP3 文件并将其更改为音频/mp3 时,它可以从内存流中正常工作。有任何想法吗!
解决方案
您应该使用AudioTrack。
在这种情况下,您可以为您的 wav 文件指定音频参数:
- 采样率(HZ)
- 编码类型(例如 8bit 或 16bit pcm)
- 通道(单声道\立体声)
然后设置缓冲区大小和传输模式。打电话玩。
例子:
int minBufferSize = AudioTrack.getMinBufferSize(16000, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack.Builder().setAudioFormat(new AudioFormat.Builder()
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setSampleRate(44100)
.build())
.setTransferMode(AudioTrack.MODE_STREAM)
.setBufferSizeInBytes(minBufferSize)
.build();
track.play();
如果一切正常。您可以开始将数据写入缓冲区(为此使用后台线程)。
int size = 512;//(for example)
byte[] veryShortPiecesOfAudioAataFromRESTService = new byte[size];
track.write(veryShortPiecesOfAudioAataFromRESTService, 0, size);
推荐阅读
- indexing - 索引 1000 个 Pdf 文件并进行索引全文搜索
- c++ - 如何将 reduce OpenACC 指令应用于多维向量?
- c++ - 使用函数指针数组调用类的方法
- python - 为什么这不返回正确的除数?
- php - 如何在 PHP 中使用 SQL REVOKE、GRANT 和 ALTER 命令作为准备好的语句
- wxpython - 滚动窗格中大量图像的性能问题
- javascript - 遍历嵌套的 JSON 对象
- c# - 如何在控制器类层返回错误请求?
- react-native - Fitbit URL 回调给出 NULL 响应
- r - mRpostman - 自特定日期时间以来搜索电子邮件