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

2022-10-17,,

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

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倍压缩,肉耳听不出损耗)

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

下载本文的Word格式文档,以方便收藏与打印。