【问题标题】:Stream audio bytes to MediaPlayer将音频字节流式传输到 MediaPlayer
【发布时间】:2026-02-18 15:45:01
【问题描述】:

有没有办法将字节直接流式传输到Android.Media.MediaPlayer?所以当我收到一堆字节时,我可以把它们扔到这个班级并播放它们并重复?我找不到任何用字节喂 MediaPlayer 的例子,这似乎是最合理的方法。

目前我正在尝试将每个数据包存储为临时文件,因此我可以播放一小部分音乐并立即处理它,但我还没有让它工作,感觉就像一个糟糕的方法.

这是我迄今为止尝试过的。我收到一小部分声音 (bArray),然后将 .wav 标头附加到它上面,以便我可以播放它。我对收到的每个数据包都执行​​此操作。此标头与我收到的数据匹配(我使用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 无法做到这一点。您应该改用AudioTrack 类,它当然可以播放连续流。
  • 我看了一眼,它看起来很有希望。谢谢,我会对此进行测试并回复您:)

标签: c# xamarin stream android-mediaplayer


【解决方案1】:

据我所知,MediaPlayer 无法播放连续流(不是为此而设计的)。但是,还有更多的低级类 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 或采样率)才能正确实施。

【讨论】:

  • 抱歉耽搁了,我必须将输入转换为 16 位。它工作得很好,我什至不必用十六进制写我自己的 .wav 标头哈哈。现在我可以专注于压缩和优化。谢谢。
最近更新 更多