• 简单实用的PCM音频播放器--沉寂几年之后回归的第一份笔记


    ---恢复内容开始---

    PCM音频网络流播放,至于用处,就不多解释了。

    一个简单的类,基于NAudio,一个简单的拼装类,实例化时三个参数,依次是采样率,系统播放设备Index,播放声道,调用PlayData方法传入PCM的音频流即可,有流就传进去,数据断了,播放自动停。

    接下来把代码贴出来:

     1 public class PCMPlayer
     2     {
     3         private MonoToStereoProvider16 monoToStereoProvider16;
     4         private BufferedWaveProvider bufferedWaveProvider;
     5         private WaveOut waveOut;
     6         private bool isRunning = false;
     7         private PCMPlayerChannel currentChannel;
     8 
     9         /// <summary>
    10         /// 
    11         /// </summary>
    12         /// <param name="sampleRate">采样率8K至64K</param>
    13         /// <param name="deviceNumber">通过GetPlayDevices来获取字典的KEY值</param>
    14         /// <param name="playerChannel">初始化时播放的声道</param>
    15         public PCMPlayer(int sampleRate, int deviceNumber = 0, PCMPlayerChannel playerChannel = PCMPlayerChannel.Both)
    16         {
    17             currentChannel = playerChannel;
    18             WaveFormat = new WaveFormat(sampleRate, 16, 1);
    19             bufferedWaveProvider = new BufferedWaveProvider(WaveFormat);
    20             monoToStereoProvider16 = new MonoToStereoProvider16(bufferedWaveProvider);
    21             waveOut = new WaveOut();
    22             waveOut.DeviceNumber = deviceNumber;
    23             waveOut.Init(monoToStereoProvider16);
    24             waveOut.Play();
    25             isRunning = true;
    26         }
    27 
    28         public void PlayData(byte[] data)
    29         {
    30             if (!isRunning) return;
    31             bufferedWaveProvider.AddSamples(data, 0, data.Length);
    32         }
    33 
    34         public void ClosePlay()
    35         {
    36             isRunning = false;
    37             waveOut.Stop();
    38             waveOut.Dispose();
    39         }
    40 
    41         public bool SetPlayChannel(PCMPlayerChannel playerChannel)
    42         {
    43             if (!isRunning || waveOut == null || monoToStereoProvider16 == null) return false;
    44             switch (playerChannel)
    45             {
    46                 case PCMPlayerChannel.Left:
    47                     {
    48                         monoToStereoProvider16.LeftVolume = 1.0f;
    49                         monoToStereoProvider16.RightVolume = 0.0f;
    50                     }
    51                     break;
    52                 case PCMPlayerChannel.Right:
    53                     {
    54                         monoToStereoProvider16.LeftVolume = 0.0f;
    55                         monoToStereoProvider16.RightVolume = 1.0f;
    56                     }
    57                     break;
    58                 case PCMPlayerChannel.Both:
    59                     {
    60                         monoToStereoProvider16.LeftVolume = 1.0f;
    61                         monoToStereoProvider16.RightVolume = 1.0f;
    62                     }
    63                     break;
    64                 default: return false;
    65             }
    66             return true;
    67         }
    68 
    69         public WaveFormat WaveFormat { get; private set; }
    70 
    71         public static Dictionary<int, WaveOutCapabilities> GetPlayDevices
    72         {
    73             get
    74             {
    75                 Dictionary<int, WaveOutCapabilities> result = new Dictionary<int, WaveOutCapabilities>();
    76                 try
    77                 {
    78                     int count = WaveOut.DeviceCount;
    79                     for (int i = 0; i < count; i++)
    80                     {
    81                         var item = WaveOut.GetCapabilities(i);
    82                         result.Add(i, item);
    83                     }
    84                 }
    85                 catch { }
    86                 return result;
    87             }
    88         }
    89     }
    90 
    91     public enum PCMPlayerChannel
    92     {
    93         Left,
    94         Right,
    95         Both
    96     }
    View Code

    预告:下一篇简单讲一下音频流网络传输时压缩与解压(基于NSpeex的音频10倍压缩,肉耳听不出损耗)

  • 相关阅读:
    ​Docker 数据卷的管理及自动构建docker镜像
    写代码有这16个好习惯,可以减少80%非业务的bug
    启动Docker“Got permission denied while trying to connect to the Docker daemon socket“问题(亲测可用)
    Docker从入门到干活,看这一篇足矣 [建议收藏]
    docker技术入门与精通(2020.12笔记总结)
    MySQL相关 死锁的发生和避免
    使用docker运行zabbixserver
    Cloudflare 是谁?
    扛得住的MySQL数据库架构
    好未来第一届PHP开源技术大会资料分享
  • 原文地址:https://www.cnblogs.com/yunxizfj/p/11402538.html
Copyright © 2020-2023  润新知