将音频字节流式传输到 MediaPlayer
Stream audio bytes to MediaPlayer
有没有办法将字节直接流式传输到 Android.Media.MediaPlayer
?所以当我收到一堆字节时,我可以将它们扔到这个 class 并播放它们并重复?我找不到任何用字节喂养 MediaPlayer
的例子,这似乎是最合理的方法。
目前我正在尝试将每个数据包存储为一个临时文件,这样我就可以播放一小部分音乐并立即处理它,但我还没有让它工作,感觉就像可怕的方法。
这是我目前尝试过的方法。我收到了一小部分声音 (bArray
),我将 .wav
header 添加到它,以便我可以播放它。我对收到的每个数据包都这样做。这个 header 匹配我收到的数据(我使用 NAudio
库来录制声音):
public void PlayAudio(byte[] bArray)
{
var player = new MediaPlayer();
player.Prepared += (sender, args) =>
{
player.Start();
};
var header = new byte[]
{
0x52, 0x49, 0x46, 0x46, // b Chunk ID (RIFF)
//0x24, 0xDC, 0x05, 0x00, // l Chunk size
0x32, 0x4B, 0x00, 0x00,
0x57, 0x41, 0x56, 0x45, // b Format WAVE
0x66, 0x6d, 0x74, 0x20, // b Subchunk 1 id
0x12, 0x00, 0x00, 0x00, // l Subchunk 1 size (size of the rest of the header) = 16
0x03, 0x00, // l Audio format, 1 = Linear Quantization, others = compression
0x02, 0x00, // l Number of channels, 1 = mono, 2 = stereo
0x80, 0xBB, 0x00, 0x00, // l Sample rate
0x00, 0xDC, 0x05, 0x00, // l Byte rate (SampleRate * NumChannels * BitsPerSample / 8)
0x08, 0x00, // l Block align (NumChannels * BitsPerSample / 8)
0x20, 0x00, // l Bits per sample
0x00, 0x00, 0x66, 0x61, // compression data
0x63, 0x74, 0x04, 0x00, // compression data
0x00, 0x00, 0x60, 0x09, // compression data
0x00, 0x00, // compression data
0x64, 0x61, 0x74, 0x61, // b Subchunk 2 id (Contains the letters "data")
0x00, 0x4B, 0x00, 0x00, // l Subchunk 2 Size
};
var file = File.CreateTempFile("example", ".wav");
var fos = new FileOutputStream(file);
fos.Write(header);
fos.Write(bArray);
fos.Close();
player.Reset();
var fis = new FileInputStream(file);
player.SetDataSource(fis.FD);
player.Prepare();
}
显然这段代码没有优化,但我什至不能让它工作而且我花了很多时间在上面,所以希望有一个不同的解决方案来解决这个问题。
据我所知,MediaPlayer
无法播放连续流(不是为此设计的)。但是,还有low-levelclass、AudioTrack
可以做到这一点
这是我的一个项目中的小样本:
private int _bufferSize;
private AudioTrack _output;
// in constructor
_bufferSize = AudioTrack.GetMinBufferSize(8000, ChannelOut.Mono, Encoding.Pcm16bit);
// when starting to play audio
_output = new AudioTrack(Stream.Music, 8000, ChannelOut.Mono, Encoding.Pcm16bit, _bufferSize, AudioTrackMode.Stream);
_output.Play();
// when data arrives via UDP socket
byte[] decoded = _codec.Decode(decrypted, 0, decrypted.Length);
// just write to AudioTrack
_output.Write(decoded, 0, decoded.Length);
当然,您需要了解所有这些参数的含义(例如 Pcm16bit
或采样率)才能正确实施它。
有没有办法将字节直接流式传输到 Android.Media.MediaPlayer
?所以当我收到一堆字节时,我可以将它们扔到这个 class 并播放它们并重复?我找不到任何用字节喂养 MediaPlayer
的例子,这似乎是最合理的方法。
目前我正在尝试将每个数据包存储为一个临时文件,这样我就可以播放一小部分音乐并立即处理它,但我还没有让它工作,感觉就像可怕的方法。
这是我目前尝试过的方法。我收到了一小部分声音 (bArray
),我将 .wav
header 添加到它,以便我可以播放它。我对收到的每个数据包都这样做。这个 header 匹配我收到的数据(我使用 NAudio
库来录制声音):
public void PlayAudio(byte[] bArray)
{
var player = new MediaPlayer();
player.Prepared += (sender, args) =>
{
player.Start();
};
var header = new byte[]
{
0x52, 0x49, 0x46, 0x46, // b Chunk ID (RIFF)
//0x24, 0xDC, 0x05, 0x00, // l Chunk size
0x32, 0x4B, 0x00, 0x00,
0x57, 0x41, 0x56, 0x45, // b Format WAVE
0x66, 0x6d, 0x74, 0x20, // b Subchunk 1 id
0x12, 0x00, 0x00, 0x00, // l Subchunk 1 size (size of the rest of the header) = 16
0x03, 0x00, // l Audio format, 1 = Linear Quantization, others = compression
0x02, 0x00, // l Number of channels, 1 = mono, 2 = stereo
0x80, 0xBB, 0x00, 0x00, // l Sample rate
0x00, 0xDC, 0x05, 0x00, // l Byte rate (SampleRate * NumChannels * BitsPerSample / 8)
0x08, 0x00, // l Block align (NumChannels * BitsPerSample / 8)
0x20, 0x00, // l Bits per sample
0x00, 0x00, 0x66, 0x61, // compression data
0x63, 0x74, 0x04, 0x00, // compression data
0x00, 0x00, 0x60, 0x09, // compression data
0x00, 0x00, // compression data
0x64, 0x61, 0x74, 0x61, // b Subchunk 2 id (Contains the letters "data")
0x00, 0x4B, 0x00, 0x00, // l Subchunk 2 Size
};
var file = File.CreateTempFile("example", ".wav");
var fos = new FileOutputStream(file);
fos.Write(header);
fos.Write(bArray);
fos.Close();
player.Reset();
var fis = new FileInputStream(file);
player.SetDataSource(fis.FD);
player.Prepare();
}
显然这段代码没有优化,但我什至不能让它工作而且我花了很多时间在上面,所以希望有一个不同的解决方案来解决这个问题。
据我所知,MediaPlayer
无法播放连续流(不是为此设计的)。但是,还有low-levelclass、AudioTrack
可以做到这一点
这是我的一个项目中的小样本:
private int _bufferSize;
private AudioTrack _output;
// in constructor
_bufferSize = AudioTrack.GetMinBufferSize(8000, ChannelOut.Mono, Encoding.Pcm16bit);
// when starting to play audio
_output = new AudioTrack(Stream.Music, 8000, ChannelOut.Mono, Encoding.Pcm16bit, _bufferSize, AudioTrackMode.Stream);
_output.Play();
// when data arrives via UDP socket
byte[] decoded = _codec.Decode(decrypted, 0, decrypted.Length);
// just write to AudioTrack
_output.Write(decoded, 0, decoded.Length);
当然,您需要了解所有这些参数的含义(例如 Pcm16bit
或采样率)才能正确实施它。