此项目需求是针对.wav格式音频进行操作,转换成相应的.mp3格式的音频文件,对音频进行切割,最后以需求的形式输出,此篇会回顾运用到的一些知识点。
1.MDI子窗口的建立:
首先一个窗体能够创建多个MDI窗体,应当将IsMDIContainer属性设为true;以下为效果图:

控制窗体切换的是一个DotNetBar.TabStrip控件,style属性为Office2007Document,TabLayOutType:FixedWithNavigationBox
创建窗体的代码如下:
01
class="color1">/// <summary> 
02
 /// 创建MDI子窗体类 
03
 /// </summary> 
04
 classCreateMDIWindow 
05
 { 
06
      /// <summary> 
07
     /// 当前程序的主窗体对象 
08
     /// </summary> 
09
     public staticForm MainForm { get; set; } 
10
      
11
     /// <summary> 
12
     /// 创建子窗口 
13
     /// </summary> 
14
     ///
15
<typeparam name="T">     窗口类型
16
</typeparam>      
17
     public static void CreateChildWindow
18
<t>     () where T : Form, new() 
19
     // where 子句还可以包括构造函数约束。 可以使用 new 运算符创建类型参数的实例;但类型参数为此必须受构造函数约束  
20
     // new() 的约束。 new() 约束可以让编译器知道:提供的任何类型参数都必须具有可访问的无参数(或默认)构造函数。            
21
     { 
22
         T form = null; 
23
    
24
         var childForms = MainForm.MdiChildren; 
25
         //遍历窗体 
26
         foreach (Form f inchildForms) 
27
         { 
28
             if (f isT) 
29
             { 
30
                 form = f asT; 
31
                 break; 
32
             } 
33
         } 
34
         //如果没有,则创建 
35
         if(form == null) 
36
         { 
37
             //新建窗体 
38
             form = newT(); 
39
             //设定窗体的图标 
40
             form.Icon = System.Drawing.Icon.FromHandle(Properties.Resources.MainIcon.GetHicon()); 
41
             //设定窗体的主图标 
42
             form.MdiParent = MainForm; 
43
             //设定窗体的边框类型 
44
             form.FormBorderStyle = FormBorderStyle.FixedToolWindow; 
45
         } 
46
         //窗口如何显示 
47
         form.WindowState = FormWindowState.Maximized; 
48
         form.Show(); 
49
     } 
50
 } 
51
</t>
前台点击按钮调用代码:CreateMDIWindow.CreateChildWindow (); <>里为窗体的名称。
2.序列化与反序列化:
当一个系统你有默认的工作目录,默认的文件保存路径,且这些数据时唯一的,你希望每次打开软件都会显示这些数据,也可以更新这些数据,可以使用序列化与反序列化。

我们以项目存储根目录和选择项目为例:
代码如下:
01
[Serializable] 
02
public  classUserSetting 
03
{ 
04
    /// <summary> 
05
    /// 序列化存储路径 
06
    /// </summary> 
07
    private string FilePath{ get { returnPath.Combine(Environment.CurrentDirectory, "User.data"); } } 
08
   
09
    /// <summary> 
10
    /// 音频资源存储目录 
11
    /// </summary> 
12
    public  stringAudioResourceFolder { get; set; } 
13
   
14
    /// <summary> 
15
    /// 项目名称 
16
    /// </summary> 
17
    public stringSolution { get; set; } 
18
   
19
    /// <summary> 
20
    /// 构造函数,创建序列化存储文件 
21
    /// </summary> 
22
    publicUserSetting() 
23
    { 
24
        if(!File.Exists(FilePath)) 
25
        { 
26
            FileStream fs = File.Create(FilePath); 
27
            fs.Close();//不关闭文件流,首次创建该文件后不能被使用买现成会被占用 
28
        }       
29
    } 
30
   
31
    /// <summary> 
32
    /// 通过反序列化方法,获得保存的数据 
33
    /// </summary>       
34
    publicUserSetting ReadUserSetting()        
35
    { 
36
        using (FileStream fs = newFileStream(FilePath, FileMode.Open,FileAccess.Read)) 
37
        { 
38
            objectob = null; 
39
            if(fs.Length > 0) 
40
            { 
41
                SoapFormatter sf = newSoapFormatter(); 
42
                ob = sf.Deserialize(fs);                   
43
            } 
44
            return ob asUserSetting; 
45
        } 
46
    } 
47
   
48
    /// <summary> 
49
    /// 通过序列化方式,保存数据 
50
    /// </summary>       
51
    public void SaveUserSetting(objectobj) 
52
    { 
53
        using (FileStream fs = newFileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write)) 
54
        { 
55
            SoapFormatter sf = newSoapFormatter(); 
56
            sf.Serialize(fs,obj); 
57
        } 
58
    } 
59
       
60
}
3.Datagridview动态生成:

根据设置的楼层生成相应楼层带button按钮的datagridview,并且每层按钮为每层选定选择音乐,代码如下:
01
/// <summary> 
02
/// 绑定楼层音乐属性 
03
/// </summary> 
04
private void BindData(int elevatorLow,intnumber) 
05
{ 
06
    try 
07
    { 
08
        DataTable list = newDataTable(); 
09
        list.Columns.Clear(); 
10
        list.Columns.Add(newDataColumn("name", typeof(string))); 
11
        list.Columns.Add(newDataColumn("musicPath", typeof(string)));              
12
        for (inti =0; i < number; i++) 
13
        { 
14
            //不包括楼层0层 
15
            if(elevatorLow != 0) 
16
            { 
17
                list.Rows.Add(list.NewRow()); 
18
                list.Rows[i][0] = elevatorLow; 
19
            } 
20
            else{ i--; } 
21
            elevatorLow++; 
22
        } 
23
        dataGridViewX1.DataSource = list; 
24
    } 
25
    catch(Exception ex) 
26
    { MessageBox.Show(ex.ToString()); } 
27
}
选择音乐按钮事件:
01
private void dataGridViewX1_CellContentClick(objectsender, DataGridViewCellEventArgs e) 
02
{ 
03
    try 
04
    {          
05
        //点击选择按钮触发的事件 
06
        if(e.RowIndex >= 0) 
07
        { 
08
            DataGridViewColumn column = dataGridViewX1.Columns[e.ColumnIndex]; 
09
            if (column isDataGridViewButtonColumn) 
10
            { 
11
                OpenFileDialog openMusic = newOpenFileDialog(); 
12
                openMusic.AddExtension = true; 
13
                openMusic.Multiselect = true; 
14
                openMusic.Filter = "MP3文件(*.mp3)|*mp3";                    
15
                if(openMusic.ShowDialog() == DialogResult.OK) 
16
                { 
17
                    dataGridViewX1.Rows[e.RowIndex].Cells[2].Value = Path.GetFileName(openMusic.FileName);                        
18
                } 
19
            } 
20
        } 
21
    } 
22
    catch(Exception ex) 
23
    { MessageBox.Show(ex.ToString()); } 
24
}
4.获得音乐文件属性:
使用Shellclass获得文件属性可以参考 点击打开链接

代码如下:
01
/// <summary> 
02
/// 获得音乐长度 
03
/// </summary> 
04
/// <param name="filePath">文件的完整路径 
05
public static string[] GetMP3Time(stringfilePath) 
06
{ 
07
    stringdirName = Path.GetDirectoryName(filePath); 
08
    stringSongName = Path.GetFileName(filePath);//获得歌曲名称            
09
    ShellClass sh = newShellClass(); 
10
    Folder dir = sh.NameSpace(dirName); 
11
    FolderItem item = dir.ParseName(SongName); 
12
    stringSongTime = dir.GetDetailsOf(item, 27);//27为获得歌曲持续时间 ,28为获得音乐速率,1为获得音乐文件大小     
13
    string[] time = Regex.Split(SongTime, ":"); 
14
    returntime; 
15
}
5.音频操作:
音频的操作用的fmpeg.exe ,下载地址
fmpeg放在bin目录下,代码如下:
01
/// <summary> 
02
/// 转换函数 
03
/// </summary> 
04
/// <param name="exe">ffmpeg程序 
05
/// <param name="arg">执行参数      
06
public static void ExcuteProcess(string exe, stringarg) 
07
{ 
08
    using (var p = newProcess()) 
09
    {              
10
            p.StartInfo.FileName = exe; 
11
            p.StartInfo.Arguments = arg; 
12
            p.StartInfo.UseShellExecute = false;    //输出信息重定向 
13
            p.StartInfo.CreateNoWindow = true; 
14
            p.StartInfo.RedirectStandardError = true; 
15
            p.StartInfo.RedirectStandardOutput = true; 
16
            p.Start();                    //启动线程 
17
            p.BeginOutputReadLine(); 
18
            p.BeginErrorReadLine(); 
19
            p.WaitForExit();//等待进程结束                                       
20
    } 
21
}
音频转换的代码如下:
01
private void btnConvert_Click(objectsender, EventArgs e) 
02
{ 
03
    //转换MP3 
04
    if(txtMp3Music.Text != "") 
05
    { 
06
        string fromMusic = Statics.Setting.AudioResourceFolder + "\\"+ Statics.Setting.Solution+"\\" + cobFolders.Text + "\\" + txtMusic.Text;//转换音乐路径 
07
        string toMusic = Statics.Setting.AudioResourceFolder + "\\"+ Statics.Setting.Solution+"\\" + cobFolders.Text + "\\"+ txtMp3Music.Text;//转换后音乐路径 
08
        intbitrate = Convert.ToInt32(cobBitRate.Text) * 1000;//恒定码率 
09
        stringHz = cobHz.Text;//采样频率 
10
   
11
        try 
12
        { 
13
            MP3Convertion.ExcuteProcess("ffmpeg.exe", "-y -ab " + bitrate + " -ar "+ Hz + " -i \"" + fromMusic + "\" \"" + toMusic + "\""); 
14
            if(cbRetain.Checked == false) 
15
            { 
16
                File.Delete(fromMusic); 
17
                BindList(); 
18
            } 
19
            else 
20
            { 
21
                foreach (ListViewItem lt inlistMusics.Items) 
22
                { 
23
                    if(lt.Text == txtMusic.Text) 
24
                    { 
25
                        listMusics.Items.Remove(lt); 
26
                    } 
27
                } 
28
            } 
29
   
30
            //转换完成 
31
            MessageBox.Show("转换完成"); 
32
            txtMusic.Text = ""; 
33
            txtMp3Music.Text = ""; 
34
        } 
35
        catch(Exception ex) 
36
        { MessageBox.Show(ex.ToString()); } 
37
    } 
38
    else 
39
    { 
40
        MessageBox.Show("请选择你要转换的音乐");  
41
    } 
42
}
音频切割的代码如下:
01
private void btnCut_Click(objectsender, EventArgs e) 
02
{ 
03
    SaveFileDialog saveMusic = newSaveFileDialog(); 
04
    saveMusic.Title = "选择音乐文件存放的位置"; 
05
    saveMusic.DefaultExt = ".mp3"; 
06
    saveMusic.InitialDirectory = Statics.Setting.AudioResourceFolder +"\\" + Statics.Setting.Solution+"\\" + cobFolders.Text; 
07
    string fromPath = Statics.Setting.AudioResourceFolder + "\\"+ Statics.Setting.Solution +"\\"+ cobFolders.Text + "\\"+ txtMusic.Text;//要切割音乐的物理路径 
08
    stringstartTime = string.Format("0:{0}:{1}", txtBeginM.Text, txtBeginS.Text).Trim();//歌曲起始时间 
09
    intduration = (Convert.ToInt32(this.txtEndM.Text) * 60 + Convert.ToInt32(this.txtEndS.Text)) - (Convert.ToInt32(this.txtBeginM.Text) * 60 + Convert.ToInt32(this.txtBeginS.Text)); 
10
    stringendTime = string.Format("0:{0}:{1}", duration / 60, duration % 60);//endTime是持续的时间,不是歌曲结束的时间 
11
    if(saveMusic.ShowDialog() == DialogResult.OK) 
12
    { 
13
        stringsavePath = saveMusic.FileName;//切割后音乐保存的物理路径 
14
        try 
15
        { 
16
            MP3Convertion.ExcuteProcess("ffmpeg.exe", "-y -i \"" + fromPath + "\" -ss "+ startTime + " -t " + endTime + " -acodec copy \""+ savePath+"\"");//-acodec copy表示歌曲的码率和采样频率均与前者相同 
17
            MessageBox.Show("已切割完成"); 
18
        } 
19
        catch(Exception ex) 
20
        { 
21
            MessageBox.Show(ex.ToString()); 
22
        }                
23
    } 
24
}
切割音频操作系统的知识点就总结道这了,就是fmpeg的应用。