C# 音频操作系统项目总结
openkk
12年前
此项目需求是针对.wav格式音频进行操作,转换成相应的.mp3格式的音频文件,对音频进行切割,最后以需求的形式输出,此篇会回顾运用到的一些知识点。
1.MDI子窗口的建立:
首先一个窗体能够创建多个MDI窗体,应当将IsMDIContainer属性设为true;以下为效果图:
控制窗体切换的是一个DotNetBar.TabStrip控件,style属性为Office2007Document,TabLayOutType:FixedWithNavigationBox
创建窗体的代码如下:
////// 创建MDI子窗体类 /// class CreateMDIWindow { ////// 当前程序的主窗体对象 /// public static Form MainForm { get; set; } ////// 创建子窗口 /// ///窗口类型 public static void CreateChildWindow() 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
2.序列化与反序列化:
当一个系统你有默认的工作目录,默认的文件保存路径,且这些数据时唯一的,你希望每次打开软件都会显示这些数据,也可以更新这些数据,可以使用序列化与反序列化。
我们以项目存储根目录和选择项目为例:
代码如下:
[Serializable] public class UserSetting { ////// 序列化存储路径 /// private string FilePath{ get { return Path.Combine(Environment.CurrentDirectory, "User.data"); } } ////// 音频资源存储目录 /// public string AudioResourceFolder { get; set; } ////// 项目名称 /// public string Solution { get; set; } ////// 构造函数,创建序列化存储文件 /// public UserSetting() { if (!File.Exists(FilePath)) { FileStream fs = File.Create(FilePath); fs.Close();//不关闭文件流,首次创建该文件后不能被使用买现成会被占用 } } ////// 通过反序列化方法,获得保存的数据 /// 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; } } ////// 通过序列化方式,保存数据 /// 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,并且每层按钮为每层选定选择音乐,代码如下:
///选择音乐按钮事件:/// 绑定楼层音乐属性 /// 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获得文件属性可以参考 点击打开链接
代码如下:
////// 获得音乐长度 /// /// 文件的完整路径 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目录下,代码如下:///音频转换的代码如下:/// 转换函数 /// /// ffmpeg程序 /// 执行参数 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的应用。
转自:http://blog.csdn.net/kaoleba126com/article/details/7570745