C# 音频操作系统项目总结

此项目需求是针对.wav格式音频进行操作,转换成相应的.mp3格式的音频文件,对音频进行切割,最后以需求的形式输出,此篇会回顾运用到的一些知识点。

1.MDI子窗口的建立:

首先一个窗体能够创建多个MDI窗体,应当将IsMDIContainer属性设为true;以下为效果图:


控制窗体切换的是一个DotNetBar.TabStrip控件,style属性为Office2007Document,TabLayOutType:FixedWithNavigationBox

创建窗体的代码如下:

    /// <summary>
    /// 创建MDI子窗体类
    /// </summary>
    class CreateMDIWindow
    {
         /// <summary>
        /// 当前程序的主窗体对象
        /// </summary>
        public static Form MainForm { get; set; }
      
        /// <summary>
        /// 创建子窗口
        /// </summary>
        /// <typeparam name="T">窗口类型</typeparam>     
        public static void CreateChildWindow<T>() where T : Form, new()
        // where 子句还可以包括构造函数约束。 可以使用 new 运算符创建类型参数的实例;但类型参数为此必须受构造函数约束 
        // new() 的约束。 new() 约束可以让编译器知道:提供的任何类型参数都必须具有可访问的无参数(或默认)构造函数。           
        {
            T form = null;

            var childForms = MainForm.MdiChildren;
            //遍历窗体
            foreach (Form f in childForms)
            {
                if (f is T)
                {
                    form = f as T;
                    break;
                }
            }
            //如果没有,则创建
            if (form == null)
            {
                //新建窗体
                form = new T();
                //设定窗体的图标
                form.Icon = System.Drawing.Icon.FromHandle(Properties.Resources.MainIcon.GetHicon());
                //设定窗体的主图标
                form.MdiParent = MainForm;
                //设定窗体的边框类型
                form.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            }
            //窗口如何显示
            form.WindowState = FormWindowState.Maximized;
            form.Show();
        }
    }

前台点击按钮调用代码:CreateMDIWindow.CreateChildWindow<FrmWavToMp3>();  <>里为窗体的名称。

2.序列化与反序列化:

当一个系统你有默认的工作目录,默认的文件保存路径,且这些数据时唯一的,你希望每次打开软件都会显示这些数据,也可以更新这些数据,可以使用序列化与反序列化。


我们以项目存储根目录和选择项目为例:

代码如下:

    [Serializable]
    public  class UserSetting
    {
        /// <summary>
        /// 序列化存储路径
        /// </summary>
        private string FilePath{ get { return Path.Combine(Environment.CurrentDirectory, "User.data"); } }

        /// <summary>
        /// 音频资源存储目录
        /// </summary>
        public  string AudioResourceFolder { get; set; }

        /// <summary>
        /// 项目名称
        /// </summary>
        public string Solution { get; set; }

        /// <summary>
        /// 构造函数,创建序列化存储文件
        /// </summary>
        public UserSetting()
        {
            if (!File.Exists(FilePath))
            {
                FileStream fs = File.Create(FilePath);
                fs.Close();//不关闭文件流,首次创建该文件后不能被使用买现成会被占用
            }      
        }

        /// <summary>
        /// 通过反序列化方法,获得保存的数据
        /// </summary>      
        public UserSetting ReadUserSetting()       
        {
            using (FileStream fs = new FileStream(FilePath, FileMode.Open,FileAccess.Read))
            {
                object ob = null;
                if (fs.Length > 0)
                {
                    SoapFormatter sf = new SoapFormatter();
                    ob = sf.Deserialize(fs);                  
                }
                return ob as UserSetting;
            }
        }

        /// <summary>
        /// 通过序列化方式,保存数据
        /// </summary>      
        public void SaveUserSetting(object obj)
        {
            using (FileStream fs = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                SoapFormatter sf = new SoapFormatter();
                sf.Serialize(fs,obj);
            }
        }
        
    }

3.Datagridview动态生成:


根据设置的楼层生成相应楼层带button按钮的datagridview,并且每层按钮为每层选定选择音乐,代码如下:

        /// <summary>
        /// 绑定楼层音乐属性
        /// </summary>
        private void BindData(int elevatorLow,int number)
        {
            try
            {
                DataTable list = new DataTable();
                list.Columns.Clear();
                list.Columns.Add(new DataColumn("name", typeof(string)));
                list.Columns.Add(new DataColumn("musicPath", typeof(string)));             
                for (int i =0; i < number; i++)
                {
                    //不包括楼层0层
                    if (elevatorLow != 0)
                    {
                        list.Rows.Add(list.NewRow());
                        list.Rows[i][0] = elevatorLow;
                    }
                    else { i--; }
                    elevatorLow++;
                }
                dataGridViewX1.DataSource = list;
            }
            catch (Exception ex)
            { MessageBox.Show(ex.ToString()); }
        }
选择音乐按钮事件:

        private void dataGridViewX1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {         
                //点击选择按钮触发的事件
                if (e.RowIndex >= 0)
                {
                    DataGridViewColumn column = dataGridViewX1.Columns[e.ColumnIndex];
                    if (column is DataGridViewButtonColumn)
                    {
                        OpenFileDialog openMusic = new OpenFileDialog();
                        openMusic.AddExtension = true;
                        openMusic.Multiselect = true;
                        openMusic.Filter = "MP3文件(*.mp3)|*mp3";                   
                        if (openMusic.ShowDialog() == DialogResult.OK)
                        {
                            dataGridViewX1.Rows[e.RowIndex].Cells[2].Value = Path.GetFileName(openMusic.FileName);                       
                        }
                    }
                }
            }
            catch(Exception ex)
            { MessageBox.Show(ex.ToString()); }
        }
4.获得音乐文件属性:

使用Shellclass获得文件属性可以参考  点击打开链接   


代码如下:

        /// <summary>
        /// 获得音乐长度
        /// </summary>
        /// <param name="filePath">文件的完整路径</param>
        public static string[] GetMP3Time(string filePath)
        {
            string dirName = Path.GetDirectoryName(filePath);
            string SongName = Path.GetFileName(filePath);//获得歌曲名称           
            ShellClass sh = new ShellClass();
            Folder dir = sh.NameSpace(dirName);
            FolderItem item = dir.ParseName(SongName);
            string SongTime = dir.GetDetailsOf(item, 27);//27为获得歌曲持续时间 ,28为获得音乐速率,1为获得音乐文件大小    
            string[] time = Regex.Split(SongTime, ":");
            return time;
        }

5.音频操作:

音频的操作用的fmpeg.exe ,下载地址

fmpeg放在bin目录下,代码如下:

        /// <summary>
        /// 转换函数
        /// </summary>
        /// <param name="exe">ffmpeg程序</param>
        /// <param name="arg">执行参数</param>     
        public static void ExcuteProcess(string exe, string arg)
        {
            using (var p = new Process())
            {             
                    p.StartInfo.FileName = exe;
                    p.StartInfo.Arguments = arg;
                    p.StartInfo.UseShellExecute = false;    //输出信息重定向
                    p.StartInfo.CreateNoWindow = true;
                    p.StartInfo.RedirectStandardError = true;
                    p.StartInfo.RedirectStandardOutput = true;
                    p.Start();                    //启动线程
                    p.BeginOutputReadLine();
                    p.BeginErrorReadLine();
                    p.WaitForExit();//等待进程结束                                      
            }
        }

音频转换的代码如下:
        private void btnConvert_Click(object sender, EventArgs e)
        {
            //转换MP3
            if (txtMp3Music.Text != "")
            {
                string fromMusic = Statics.Setting.AudioResourceFolder + "\\" + Statics.Setting.Solution+"\\" + cobFolders.Text + "\\" + txtMusic.Text;//转换音乐路径
                string toMusic = Statics.Setting.AudioResourceFolder + "\\" + Statics.Setting.Solution+"\\" + cobFolders.Text + "\\" + txtMp3Music.Text;//转换后音乐路径
                int bitrate = Convert.ToInt32(cobBitRate.Text) * 1000;//恒定码率
                string Hz = cobHz.Text;//采样频率

                try
                {
                    MP3Convertion.ExcuteProcess("ffmpeg.exe", "-y -ab " + bitrate + " -ar " + Hz + " -i \"" + fromMusic + "\" \"" + toMusic + "\"");
                    if (cbRetain.Checked == false)
                    {
                        File.Delete(fromMusic);
                        BindList();
                    }
                    else
                    {
                        foreach (ListViewItem lt in listMusics.Items)
                        {
                            if (lt.Text == txtMusic.Text)
                            {
                                listMusics.Items.Remove(lt);
                            }
                        }
                    }

                    //转换完成
                    MessageBox.Show("转换完成");
                    txtMusic.Text = "";
                    txtMp3Music.Text = "";
                }
                catch (Exception ex)
                { MessageBox.Show(ex.ToString()); }
            }
            else
            {
                MessageBox.Show("请选择你要转换的音乐"); 
            }
        }

音频切割的代码如下:
        private void btnCut_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveMusic = new SaveFileDialog();
            saveMusic.Title = "选择音乐文件存放的位置";
            saveMusic.DefaultExt = ".mp3";
            saveMusic.InitialDirectory = Statics.Setting.AudioResourceFolder +"\\"  + Statics.Setting.Solution+"\\" + cobFolders.Text;
            string fromPath = Statics.Setting.AudioResourceFolder + "\\" + Statics.Setting.Solution +"\\"+ cobFolders.Text + "\\" + txtMusic.Text;//要切割音乐的物理路径
            string startTime = string.Format("0:{0}:{1}", txtBeginM.Text, txtBeginS.Text).Trim();//歌曲起始时间
            int duration = (Convert.ToInt32(this.txtEndM.Text) * 60 + Convert.ToInt32(this.txtEndS.Text)) - (Convert.ToInt32(this.txtBeginM.Text) * 60 + Convert.ToInt32(this.txtBeginS.Text));
            string endTime = string.Format("0:{0}:{1}", duration / 60, duration % 60);//endTime是持续的时间,不是歌曲结束的时间
            if (saveMusic.ShowDialog() == DialogResult.OK)
            {
                string savePath = saveMusic.FileName;//切割后音乐保存的物理路径
                try
                {
                    MP3Convertion.ExcuteProcess("ffmpeg.exe", "-y -i \"" + fromPath + "\" -ss " + startTime + " -t " + endTime + " -acodec copy \"" + savePath+"\"");//-acodec copy表示歌曲的码率和采样频率均与前者相同
                    MessageBox.Show("已切割完成");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }               
            }
        }


切割音频操作系统的知识点就总结道这了,就是fmpeg的应用。




  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值