实时录制音频和播放amr格式音频

文章详细介绍了如何使用C#的Naudio库进行音频录制,包括设置参数、选择录音设备、记录数据以及播放录音。还提到将录音数据实时上传到后台和使用FFmpeg实现实时播放不同格式音频的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用Naudio录制音频,以下代码是把录音数据写入到一个音频文件中,然后打开播放

 public class RecordController
    {
        WaveIn mWavIn;
        WaveFileWriter mWavWriter;
        
        public RecordController()
        {
           
        }
        /// <summary>
        /// 开始录音
        /// </summary>
        /// <param name="filePath">录音文件路径</param>
        public int StartRecord(string filePath)
        {
            //录音文件路径
            mWavIn = new WaveIn();
            // 设置录音参数
            mWavIn.WaveFormat = new WaveFormat(16000, 16, 1);
            // 添加DataAvailable事件处理程序
            mWavIn.DataAvailable += MWavIn_DataAvailable;

            // 创建WaveFileWriter对象
            mWavWriter = new WaveFileWriter(filePath, mWavIn.WaveFormat);
            if (WaveInEvent.DeviceCount > 0)
            {
                //遍历录音设备
                for (int i = 0; i < WaveInEvent.DeviceCount; i++)
                {
                    var capabilities = WaveInEvent.GetCapabilities(i);
                    Console.WriteLine($"设备 {i}: {capabilities.ProductName} - {capabilities.Channels} 个声道");
                }
                //mWavIn.DeviceNumber 选择录音设备
                // 开始录音
                mWavIn.StartRecording();

                return 1;
            }
            else
            {
                return 0;
            }

        }
        /// <summary>
        /// 停止录音
        /// </summary>
        public void StopRecord()
        {
            // 停止录音
            mWavIn?.StopRecording();
            // 释放WaveIn对象
            mWavIn?.Dispose();
            mWavIn = null;
            // 关闭WaveFileWriter对象
            mWavWriter?.Close();
            mWavWriter = null;

        }

        /// <summary>
        /// DataAvailable事件处理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MWavIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            // 写入录音数据
            mWavWriter.Write(e.Buffer, 0, e.BytesRecorded);

            

        }

        //播放录音
        public void PlayAudio(MemoryStream stream) 
        {
            WaveStream waveStream = new RawSourceWaveStream(stream, new WaveFormat(16000, 16, 1));

            // 创建一个输出设备
            IWavePlayer waveOut = new WaveOut();

            // 播放音频
            waveOut.Init(waveStream);
            waveOut.Play();

        }
    }

如果是要把录音数据实时上传到后台可在MWavIn_DataAvailable方法中写入以下代码

 byte[] bt = e.Buffer;
            StreamASR streamASR = new StreamASR();
            streamASR.action = "类型";
            streamASR.audio_data = bt;
            string str = JsonConvert.SerializeObject(streamASR);
            //把str数据上传

如果要实时播放录音数据不限制格式,可使用ffplay来实现如:

 Stream stream;  


//把这段代码放置初始化中
ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    FileName = "ffplay",
                  
                    Arguments = " -f s16le -ar 16000 -ac 1  -i -",
                  
                    UseShellExecute = false,
                    RedirectStandardInput = true,
                    CreateNoWindow = true
                };
                Process ffplayProcess = Process.Start(startInfo);
                stream = ffplayProcess.StandardInput.BaseStream;


//把获取到的数据实时写入到通道中
            stream.Write(e.Buffer, 0, e.BytesRecorded);
            stream.flush();


//结束播放后关闭
stream?.close();

如果要实时播放amr格式的音频需要写入amr格式的头部字段

Stream stream;
//实时播放amr音频格式 
ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    FileName = "ffplay",
                   
                    Arguments = "-fflags nobuffer -nodisp -probesize 32 -analyzeduration 0 -f amr -i  -",//showmode 0 会导致声音有时播放不了
                   
                    UseShellExecute = false,
                    RedirectStandardInput = true,
                    CreateNoWindow = true
                };
                Process ffplayProcess = Process.Start(startInfo);
                stream = ffplayProcess.StandardInput.BaseStream;
//写入amr头部数据
                string[] str = { "23", "21", "41", "4d", "52", "0a" };
                byte[] bts = new byte[6];
                for (int i = 0; i < str.Length; i++)
                {
                    bts[i] = Convert.ToByte(str[i], 16);
                }
                stream.Write(bts, 0, bts.Length);
//输入一段无效的音频数据,防止播放延时严重

                string[] str2 = { "3c", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00" };
                byte[] bts2 = new byte[32];
                for (int i = 0; i < str2.Length; i++)
                {
                    bts2[i] = Convert.ToByte(str2[i], 16);
                }
                stream.Write(bts2, 0, bts2.Length);
 stream.Write(bts2, 0, bts2.Length);
stream.flush();//处理播放声音延迟

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值