zoukankan      html  css  js  c++  java
  • C# 音频操作系统项目总结

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

    1.MDI子窗口的建立:

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

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

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

    创建窗体的代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    /// <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(); 
         
     
    </t>

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

    2.序列化与反序列化:

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

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

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

    代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    [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动态生成:

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    /// <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()); } 
    }

    选择音乐按钮事件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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获得文件属性可以参考  点击打开链接   

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

    代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /// <summary> 
    /// 获得音乐长度 
    /// </summary> 
    /// <param name="filePath">文件的完整路径 
    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目录下,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /// <summary> 
    /// 转换函数 
    /// </summary> 
    /// <param name="exe">ffmpeg程序 
    /// <param name="arg">执行参数      
    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();//等待进程结束                                       
        
    }

    音频转换的代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    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("请选择你要转换的音乐");  
        
    }

    音频切割的代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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的应用。

    转自:http://blog.csdn.net/kaoleba126com/article/details/7570745

  • 相关阅读:
    作业5

    Linux系统管理4
    作业
    递归训练1:在两个长度相等的排序数组中找到上中位数
    LeetCode:面试题 08.05. 递归乘法
    LeetCode:面试题 08.06. 汉诺塔问题
    LeetCode:22. 括号生成
    如何仅用递归函数和栈操作逆序一个栈
    LeetCode:面试题 03.02. 栈的最小值
  • 原文地址:https://www.cnblogs.com/liushunli/p/4020066.html
Copyright © 2011-2022 走看看