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

控制窗体切换的是一个DotNetBar.TabStrip控件,style属性为Office2007Document,TabLayOutType:FixedWithNavigationBox
创建窗体的代码如下:
09 |
public staticForm MainForm { get; set; } |
15 |
<typeparam name="T"> 窗口类型 |
17 |
public static void CreateChildWindow |
18 |
<t> () where T : Form, new() |
19 |
// where 子句还可以包括构造函数约束。 可以使用 new 运算符创建类型参数的实例;但类型参数为此必须受构造函数约束 |
20 |
// new() 的约束。 new() 约束可以让编译器知道:提供的任何类型参数都必须具有可访问的无参数(或默认)构造函数。 |
24 |
var childForms = MainForm.MdiChildren; |
26 |
foreach (Form f inchildForms) |
40 |
form.Icon = System.Drawing.Icon.FromHandle(Properties.Resources.MainIcon.GetHicon()); |
42 |
form.MdiParent = MainForm; |
44 |
form.FormBorderStyle = FormBorderStyle.FixedToolWindow; |
47 |
form.WindowState = FormWindowState.Maximized; |
前台点击按钮调用代码:CreateMDIWindow.CreateChildWindow (); <>里为窗体的名称。
2.序列化与反序列化:
当一个系统你有默认的工作目录,默认的文件保存路径,且这些数据时唯一的,你希望每次打开软件都会显示这些数据,也可以更新这些数据,可以使用序列化与反序列化。

我们以项目存储根目录和选择项目为例:
代码如下:
02 |
public classUserSetting |
07 |
private string FilePath{ get { returnPath.Combine(Environment.CurrentDirectory, "User.data"); } } |
12 |
public stringAudioResourceFolder { get; set; } |
17 |
public stringSolution { get; set; } |
24 |
if(!File.Exists(FilePath)) |
26 |
FileStream fs = File.Create(FilePath); |
27 |
fs.Close();//不关闭文件流,首次创建该文件后不能被使用买现成会被占用 |
34 |
publicUserSetting ReadUserSetting() |
36 |
using (FileStream fs = newFileStream(FilePath, FileMode.Open,FileAccess.Read)) |
41 |
SoapFormatter sf = newSoapFormatter(); |
42 |
ob = sf.Deserialize(fs); |
44 |
return ob asUserSetting; |
51 |
public void SaveUserSetting(objectobj) |
53 |
using (FileStream fs = newFileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write)) |
55 |
SoapFormatter sf = newSoapFormatter(); |
3.Datagridview动态生成:

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

代码如下:
04 |
/// <param name="filePath">文件的完整路径 |
05 |
public static string[] GetMP3Time(stringfilePath) |
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, ":"); |
5.音频操作:
音频的操作用的fmpeg.exe ,下载地址
fmpeg放在bin目录下,代码如下:
04 |
/// <param name="exe">ffmpeg程序 |
05 |
/// <param name="arg">执行参数 |
06 |
public static void ExcuteProcess(string exe, stringarg) |
08 |
using (var p = newProcess()) |
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; |
17 |
p.BeginOutputReadLine(); |
18 |
p.BeginErrorReadLine(); |
19 |
p.WaitForExit();//等待进程结束 |
音频转换的代码如下:
01 |
private void btnConvert_Click(objectsender, EventArgs e) |
04 |
if(txtMp3Music.Text != "") |
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;//采样频率 |
13 |
MP3Convertion.ExcuteProcess("ffmpeg.exe", "-y -ab " + bitrate + " -ar "+ Hz + " -i \"" + fromMusic + "\" \"" + toMusic + "\""); |
14 |
if(cbRetain.Checked == false) |
16 |
File.Delete(fromMusic); |
21 |
foreach (ListViewItem lt inlistMusics.Items) |
23 |
if(lt.Text == txtMusic.Text) |
25 |
listMusics.Items.Remove(lt); |
31 |
MessageBox.Show("转换完成"); |
33 |
txtMp3Music.Text = ""; |
36 |
{ MessageBox.Show(ex.ToString()); } |
40 |
MessageBox.Show("请选择你要转换的音乐"); |
音频切割的代码如下:
01 |
private void btnCut_Click(objectsender, EventArgs e) |
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) |
13 |
stringsavePath = saveMusic.FileName;//切割后音乐保存的物理路径 |
16 |
MP3Convertion.ExcuteProcess("ffmpeg.exe", "-y -i \"" + fromPath + "\" -ss "+ startTime + " -t " + endTime + " -acodec copy \""+ savePath+"\"");//-acodec copy表示歌曲的码率和采样频率均与前者相同 |
17 |
MessageBox.Show("已切割完成"); |
21 |
MessageBox.Show(ex.ToString()); |
切割音频操作系统的知识点就总结道这了,就是fmpeg的应用。
- EasyDarwin开源音频解码项目EasyAudioDecoder:EasyPlayer Android音频解码库(第二部分,封装解码器接口)
上一节我们讲了如何基于ffmpeg-Android工程编译安卓上的支持音频的ffmpeg静态库:http://blog.csdn.net/xiejiashu/article/details/52524 ...
- EasyDarwin开源音频解码项目EasyAudioDecoder:基于ffmpeg的安卓音频(AAC、G726)解码库(第一部分,ffmpeg-android的编译)
ffmpeg是一套开源的,完整的流媒体解决方案.基于它可以很轻松构建一些强大的应用程序.对于流媒体这个行业,ffmpeg就像圣经一样的存在.为了表达敬意,在这里把ffmpeg官网的一段简介搬过来,ff ...
- Ucan23操作系统项目地址
期间耽误了近半年的时间.在昨天最终完毕了Ucan23OS, 项目托管在GitHub上,地址为: https://github.com/howardking/UCAN23OS 以下为操作系统的执行截图 ...
- 操作系统项目:向Linux内核添加一个系统调用
内容: 向Linux增加一个系统调用 撰写一个应用测试程序调用该系统调用 使用ptrace或类似的工具对该测试程序进行跟踪调 环境: 1.vmware workstation 15.0.0 2.ubu ...
- 我发起了一个 操作系统 GUI 和 Tcp / IP 包 的 开源项目 DeviceOS
操作系统 如果 不需要 处理 复杂多样 的 硬件 兼容性, 其实 并不算 大项目, 可以算 毕业设计 . 但是, GUI 和 Tcp / IP 这两个 部分 的 实现逻辑 很多 很复杂, 这 2 ...
- 物联网操作系统HelloX V1.79发布公告
经过HelloX开发团队近半年的努力,在HelloX V1.78版本基础上,增加许多功能特性,并对V1.78版本的一些特性进行了进一步优化之后,正式形成HelloX V1.79测试版本.经相对充分的测 ...
- Cookiecutter: 更好的项目模板工具:(1)简介及可用资源汇总
原文档地址:https://cookiecutter.readthedocs.io/en/latest/ 本系列只介绍cookiecutter的基础使用,而且会删除与功能使用无关的部分.深度使用及了解 ...
- EasyDarwin开源流媒体项目
本文转自EasyDarwin CSDN官方博客:http://blog.csdn.net/easydarwin EasyDarwin是由国内开源流媒体团队维护和迭代的一整套开源流媒体视频平台框架,从2 ...
- [转帖](整理)GNU Hurd项目详解
(整理)GNU Hurd项目详解 http://www.ha97.com/3188.html 发表于: 开源世界 | 作者: 博客教主 标签: GNU,Hurd,详解,项目 Hurd原本是要成为GNU ...
随机推荐
- 【基础知识】C#数据库中主键类型的选择
主键在数据库中占有很大的地位,对于表的关联性,和数据的唯一识别性有重要的作用: 1,在C#开发中,Int自增字段和Guid(数据库中是uniqueidentifier类型)可设置为主键: 1>G ...
- 为了增强团队的协作和高效开发,提升代码质量,TGideas团队一起制订的代码规范。主要包括五部分内容:PC规范、移动端规范、性能优化、CP规范、其他项目规范
http://tguide.qq.com/main/index.htm
- 二分搜索之C++实现
二分搜索之C++实现 一.源代码:BinarySearch.cpp #include<iostream> using namespace std; /*定义输出一维数组的函数*/ void ...
- [BZOJ1758][WC2010]重建计划(点分治+单调队列)
点分治,对于每个分治中心,考虑求出经过它的符合长度条件的链的最大权值和. 从分治中心dfs下去取出所有链,为了防止两条链属于同一个子树,我们一个子树一个子树地处理. 用s1[i]记录目前分治中心伸下去 ...
- bzoj1814: Ural 1519 Formula 1 动态规划 插头dp
http://acm.timus.ru/problem.aspx?space=1&num=1519 题目描述 一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数. ...
- Python168的学习笔记1
在对list的条件选择有两种常用方法,直接使用filter函数,就是filter(func,sequence);另外一种就是迭代操作,类似 x for x in sequence func.这两种方法 ...
- UVALive 4867 Maximum Square 贪心
E - Maximum Square Time Limit:4500MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit ...
- Mac OSX系统下通过ProxyChains-NG实现终端下的代理
项目主页:https://github.com/rofl0r/proxychains-ng 官方说明: proxychains ng (new generation) - a preloader wh ...
- Window 下安装
Window 下安装 下载地址:https://github.com/MSOpenTech/redis/releases Redis 支持 32 位和 64 位.这个需要根据你系统平台的实际情况选择, ...
- Go语言Web框架gwk介绍 (三)
上一篇忘了ChanResult ChanResult 可以用来模拟BigPipe,定义如下 type ChanResult struct { Wait sync.WaitGroup Chan chan ...