简单实用的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 }
预告:下一篇简单讲一下音频流网络传输时压缩与解压(基于NSpeex的音频10倍压缩,肉耳听不出损耗)