小Q的博客

  • 首页
  • net编程
    • 产品和框架
    • 开发实例
    • 经验技巧
    • 开源组件
  • wp独立站
  • 自媒体
  • 日记本
  • 工具箱
每个程序员,都应该有一个自己的博客站
  1. 首页
  2. net编程
  3. 经验技巧
  4. 正文

net中c#如何录制音频?推荐使用NAudio组件

2022年12月21日 400点热度 0人点赞 0条评论

上一篇博客实现录制视频,今天这篇讲的是net中c#实现录制音频?这里推荐使用NAudio这个组件。它是相对成熟、开源的C#音频开发工具,包含录音、播放录音、格式转换、混音调整等功能。今天这篇只展示了它的录音功能

 

1、录音代码

public partial class FormAudioRecordBill : FormBase
{
    private string waveFolder = null;
    private string waveFileName = null;
    public WaveIn waveSource = null;
    public WaveFileWriter waveFile = null;
    private BindingList<AudioRecordBillModel> blistModel = null;
    private DateTime? dtmStart = null;

    public FormAudioRecordBill()
    {
        InitializeComponent();
    }

    public override void LoadData()
    {
        //加载工具栏
        List<ToolItemModel> toolItems = new List<ToolItemModel>();
        toolItems.Add(new ToolItemModel() { ButtonID = "Close", ButtonText = "关闭", ButtonParentID = "Root", EditType = ToolItemEditType.Button.ToString(), ImageKey = IconName.ToolItemClose.ToString(), HAlign = HAlignment.Right.ToString() });
        FormUIHelper.CreateToolBar(this, this.toolBar, toolItems, this.ImageList16, false);

        //加载Grid栏目
        List<GridColumnModel> gridColumns = new List<GridColumnModel>();
        gridColumns.Add(new GridColumnModel() { ColumnID = "FileName", ColumnParentID = "Root", ColumnText = "文件名", Width = "160", EditType = GridColumnEditType.TextBox.ToString() });
        gridColumns.Add(new GridColumnModel() { ColumnID = "FileNameNoExt", ColumnParentID = "Root", ColumnText = "文件名(无扩展名)", Width = "160", EditType = GridColumnEditType.TextBox.ToString(), IsHidden = true.ToString(), });
        gridColumns.Add(new GridColumnModel() { ColumnID = "FullName", ColumnParentID = "Root", ColumnText = "完整名称", Width = "180", EditType = GridColumnEditType.TextBox.ToString(), IsHidden = true.ToString(), });
        gridColumns.Add(new GridColumnModel() { ColumnID = "Extension", ColumnParentID = "Root", ColumnText = "格式", Width = "75", EditType = GridColumnEditType.TextBox.ToString(), IsHidden = true.ToString(), });
        gridColumns.Add(new GridColumnModel() { ColumnID = "FileSize", ColumnParentID = "Root", ColumnText = "大小", Width = "75", EditType = GridColumnEditType.TextBox.ToString() });
        gridColumns.Add(new GridColumnModel() { ColumnID = "AudioDuration", ColumnParentID = "Root", ColumnText = "时长", Width = "110", EditType = GridColumnEditType.TextBox.ToString() });
        gridColumns.Add(new GridColumnModel() { ColumnID = "Button_Action", ColumnParentID = "Root", ColumnText = "操作", Width = "110", EditType = GridColumnEditType.Button.ToString(), });
        FormUIHelper.InitGridColumn(this.gridviewFile, gridColumns);
        GridOptionModel gridOption = new GridOptionModel()
        {
            ShowDetailTabs = false,
            ShowGroupPanel = false,
            ShowAutoFilterRow = true,
            AllowFilter = true,
            EditorShowMode = GridEditorShowMode.MouseUp,
            IndicatorWidth = 40,
            MultiSelect = true
        };
        FormUIHelper.SetGridStyle(this.gridviewFile, GridStyle.List, gridOption);
        //this.gridviewFile.RowHeight = 40;

        //Grid中加载按钮.注:需改为可编辑
        Dictionary<object, string> dicButton = new Dictionary<object, string>();
        dicButton.Add("playeraudio", "播放");
        dicButton.Add("openfolder", "打开");            
        dicButton.Add("delete", "删除");
        RepositoryItemButtonEdit ribeFile = FormUIHelper.CreateGridColumnToButtonEdit(dicButton);
        ribeFile.ButtonClick += OnDevGridColumnButtonEditButtonClickEventHandler;
        GridColumn gcAction = this.gridviewFile.Columns["Button_Action"];
        gcAction.ColumnEdit = ribeFile;
        FormUIHelper.SetGridColumnAllowUpdate(this.gridviewFile, "Button_Action", true);

        //加载音频播放组件
        ControlAudioPreview conAudioPreview = new ControlAudioPreview();
        conAudioPreview.Dock = DockStyle.Fill;
        this.panelPlayer.Controls.Add(conAudioPreview);

        //加载下拉菜单控件
        DataTable dtFileExt = DataTableHelper.GetTableByString("wav,wav|mp3,mp3");
        FormUIHelper.SetComboBoxEditDataSource(this.fmExportFileExt, dtFileExt, "CodeID", "CodeName", false, false, "wav");

        DataTable dtSource = DataTableHelper.GetTableByString("all,全部|system,仅系统声音|mic,仅麦克风声音");
        FormUIHelper.SetComboBoxEditDataSource(this.fmAudioSource, dtSource, "CodeID", "CodeName", false, false, "mic");
        this.fmAudioSource.Properties.ReadOnly = true;

        //绑定控件事件
        this.gridviewFile.CustomDrawRowIndicator += this.OnDevGridCustomDrawRowIndicatorEventHandler;
        this.btnStart.Click += this.OnDevButtonClickEventHandler;
        this.btnStop.Click += this.OnDevButtonClickEventHandler;
        this.btnOpenSaveFolder.Click += this.OnDevButtonClickEventHandler;
        this.btnChangeSaveFolder.Click += this.OnDevButtonClickEventHandler;

        //设置定时器
        this.timer1.Interval = 1000 * 1;    //间隔时间:1秒
        this.timer1.Tick += timer1_Tick;

        //加载Grid控件数据
        this.BindGrid();

        //设置默认值
        this.fmSaveFolder.Text = SystemHelper.GetSystemPath(SystemFolderName.Desktop);            
    }

    public override void BindGrid()
    {
        List<AudioRecordBillModel> list1 = new List<AudioRecordBillModel>();
        this.blistModel = FormUIHelper.SetGridDataSource<AudioRecordBillModel>(this.gridFile, list1, null, false);
    }

    private void FormAudioRecordBill_Load(object sender, EventArgs e)
    {
        this.LoadData();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        DateTime dtmNow = DateTime.Now;
        TimeSpan ts1 = dtmNow - this.dtmStart.Value;

        string[] arrayTime1 = ts1.ToString().Split('.');
        this.lblDurationValue.Text = arrayTime1[0];
    }

    /// <summary>
    /// 开始录音回调函数
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void waveSource_DataAvailable(object sender, WaveInEventArgs e)
    {
        if (this.waveFile != null)
        {
            this.waveFile.Write(e.Buffer, 0, e.BytesRecorded);
            this.waveFile.Flush();
        }
    }

    /// <summary>
    /// 录音结束回调函数
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void waveSource_RecordingStopped(object sender, StoppedEventArgs e)
    {
        if (this.waveSource != null)
        {
            this.waveSource.Dispose();
            this.waveSource = null;
        }

        if (this.waveFile != null)
        {
            this.waveFile.Dispose();
            this.waveFile = null;
        }
    }

    public override void OnDevGridCustomDrawRowIndicatorEventHandler(object sender, RowIndicatorCustomDrawEventArgs e)
    {
        FormUIHelper.SetGridRowIndex(sender, e);
    }

    public override void OnDevGridColumnButtonEditButtonClickEventHandler(object sender, ButtonPressedEventArgs e)
    {
        ButtonEdit btn = sender as ButtonEdit;
        GridControl grid = btn.Parent as GridControl;
        GridView gridView = grid.DefaultView as GridView;

        int rowIndex = FormUIHelper.GetGridSelectedRow(gridView);
        if (rowIndex < 0)
            return;

        AudioRecordBillModel model1 = FormUIHelper.GetGridRowData<AudioRecordBillModel>(this.gridviewFile, rowIndex);
        FileInfo fileInfo = new FileInfo(model1.FullName);

        string btnText = e.Button.Caption;
        if (btnText == "播放")
        {
            ControlAudioPreview conPreview = this.panelPlayer.Controls[0] as ControlAudioPreview;
            conPreview.Preview(model1.FullName);
        }
        else if (btnText == "打开")
        {
            SystemHelper.OpenFile(fileInfo.DirectoryName, string.Empty);
        }
        else if (btnText == "删除")
        {
            DialogResult dlg1 = FormUIHelper.ShowMessage("确认删除这行吗?", MessageType.Question);
            if (dlg1 == DialogResult.Yes)
            {
                this.gridviewFile.DeleteRow(rowIndex);
            }
        }
    }

    public override void OnDevButtonClickEventHandler(object sender, EventArgs e)
    {
        SimpleButton btn = sender as SimpleButton;
        if (btn.Name == this.btnStart.Name)
        {
            this.waveFolder = this.fmSaveFolder.Text;
            if (string.IsNullOrEmpty(this.waveFolder))
            {
                FormUIHelper.ShowMessage("请输入保存文件夹", MessageType.Warning);
                return;
            }

            //参考地址
            //https://blog.csdn.net/anyan1858/article/details/102067490

            //获取扩展名
            string fileExt = FormUIHelper.GetComboBoxEditValue(this.fmExportFileExt) as string;

            this.waveSource = new WaveIn();
            this.waveSource.WaveFormat = new WaveFormat(16000, 16, 1); // 16bit,128KHz,Mono的录音格式

            this.waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
            this.waveSource.RecordingStopped += new EventHandler<StoppedEventArgs>(waveSource_RecordingStopped);

            this.waveFileName = this.waveFolder + @"\rec_" + FileHelper.GetFileNameByDateTime() + "." + fileExt;
            this.waveFile = new WaveFileWriter(this.waveFileName, waveSource.WaveFormat);

            this.dtmStart = DateTime.Now;

            this.waveSource.StartRecording();
            this.timer1.Start();
        }
        else if (btn.Name == this.btnStop.Name)
        {
            this.waveSource.StopRecording();
            this.timer1.Stop();

            if (this.waveSource != null)
            {
                this.waveSource.Dispose();
                this.waveSource = null;
            }

            if (this.waveFile != null)
            {
                this.waveFile.Dispose();
                this.waveFile = null;
            }

            //此时将音频文件
            FileInfo fi = new FileInfo(this.waveFileName);
            this.blistModel.Add(new AudioRecordBillModel()
            {
                FileName = fi.Name,
                FileNameNoExt = Path.GetFileNameWithoutExtension(fi.FullName),
                FullName = fi.FullName,
                AudioDuration = this.lblDurationValue.Text,
            });

            this.dtmStart = null;
            this.waveFileName = null;
            this.lblDurationValue.Text = "00:00:00";
        }
        else if (btn.Name == this.btnChangeSaveFolder.Name)
        {
            string folder = FormUIHelper.OpenFolderDialog();
            if (string.IsNullOrEmpty(folder))
                return;

            this.fmSaveFolder.Text = folder;
        }
        else if (btn.Name == this.btnOpenSaveFolder.Name)
        {
            string folder = this.fmSaveFolder.Text.Trim();
            if (!Directory.Exists(folder))
                return;

            SystemHelper.OpenFile(folder, string.Empty);
        }
    }

    public override void OnToolItemButtonClickEventHandler(object sender, EventArgs e)
    {
        //参数检测
        if (sender == null) return;
        ToolStripItem tsi = (ToolStripItem)sender;

        object tag = tsi.Tag;
        if (StringHelper.ObjectIsNullOrEmpty(tag)) tag = "";

        string s = tag.ToString().Trim().ToLower();
        if (s == "")
        {
            //空方法,占位用
        }
        else if (s == "close")
        {                
            //正式代码
            this.Close();
        }
    }
}

 

2、效果图

c#使用NAudio使用音频录制-效果图

 

3、完整源码

FormAudioRecordBill.rar

 

相关阅读

net中c#如何发送邮件?推荐Aspose.Network组件

c#中实现AOP的N种解决方案,ILEmit的最简单

标签: c#教程 NAudio net教程 录制音频
最后更新:2022年12月21日

小Q

80后中年不油腻大叔,喜欢编写代码、打羽毛球、做木制玩具。目前定居浙江杭州

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2022 小Q的博客. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

浙ICP备2022019157号-2