首页 > 技术文章 > C# 音频操作系统项目总结

gc2013 2014-04-23 17:15 原文

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

1.MDI子窗口的建立:

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

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

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

创建窗体的代码如下:

01 /// <summary> 
02  /// 创建MDI子窗体类 
03  /// </summary> 
04  classCreateMDIWindow 
05  
06       /// <summary> 
07      /// 当前程序的主窗体对象 
08      /// </summary> 
09      public staticForm MainForm { getset; } 
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.序列化与反序列化:

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

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

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

代码如下:

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 { getset; } 
13    
14     /// <summary> 
15     /// 项目名称 
16     /// </summary> 
17     public stringSolution { getset; } 
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动态生成:

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

根据设置的楼层生成相应楼层带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获得文件属性可以参考  点击打开链接   

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

代码如下:

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的应用。 

推荐阅读