NAudio 播放流、字节数组(非wav、mp3、aiff格式)

NAudio 播放流、字节数组(非wav、mp3、aiff格式)

1. 问题

http或websocket通信返回的音频数据流,导出到音频文件,然后再用AudioFileReader读取文件流,可以播放比较多格式的音频(例如:webm)。但是如果不创建临时文件,改如何直接播放流MemoryStream?

2. 举例

  • 1、返回的音频流是webm时,临时文件法可以正常播放,猜测可以分析读取文件流的方式,取消掉多余的步骤;
var filename = "./tmp.webm";
using (var audioFile = new AudioFileReader(filename))
	using (var waveOut = new WaveOutEvent())
	{
	    waveOut.Init(audioFile);
	    waveOut.Play();
	    while (waveOut.PlaybackState == PlaybackState.Playing)
	        Thread.Sleep(100);
	}
  • 2、查看AudioFileReader构造函数,其中CreateReaderStream方法是成功播放wav、mp3、aiff这3类音频的关键,所以需要找到能MediaFoundationReader相关联的类;
// 摘要:
//     Creates the reader stream, supporting all filetypes in the core NAudio library,
//     and ensuring we are in PCM format
//
// 参数:
//   fileName:
//     File Name
private void CreateReaderStream(string fileName)
{
    if (fileName.EndsWith(".wav", StringComparison.OrdinalIgnoreCase))
    {
        readerStream = new WaveFileReader(fileName);
        if (readerStream.WaveFormat.Encoding != WaveFormatEncoding.Pcm && readerStream.WaveFormat.Encoding != WaveFormatEncoding.IeeeFloat)
        {
            readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream);
            readerStream = new BlockAlignReductionStream(readerStream);
        }
    }
    else if (fileName.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase))
    {
        if (Environment.OSVersion.Version.Major < 6)
        {
            readerStream = new Mp3FileReader(fileName);
        }
        else
        {
            readerStream = new MediaFoundationReader(fileName);
        }
    }
    else if (fileName.EndsWith(".aiff", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".aif", StringComparison.OrdinalIgnoreCase))
    {
        readerStream = new AiffFileReader(fileName);
    }
    else
    {
    	// 一切其他格式音频IO流读取方式
        readerStream = new MediaFoundationReader(fileName);
    }
}
  • 3、借助vs代码智能提示,找到了MediaFoundationReader的子类StreamMediaFoundationReader
public class StreamMediaFoundationReader : MediaFoundationReader
{
    private readonly Stream stream;
    public StreamMediaFoundationReader(Stream stream, MediaFoundationReaderSettings settings = null)
    {
        this.stream = stream;
        Init(settings);
    }
    // 省略
}

3. 代码修改

byte[] buffer;
using (var ms = new MemoryStream(buffer))
	using (var media = new StreamMediaFoundationReader(ms))
	    using (var waveOut = new WaveOutEvent())
	    {
	        waveOut.Init(media);
	        waveOut.Play();
	        while (waveOut.PlaybackState == PlaybackState.Playing)
	            Thread.Sleep(100);
	    }
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值