此項目需求是針對.wav格式音頻進行操作,轉換成相應的.mp3格式的音頻文件,對音頻進行切割,最後以需求的形式輸出,此篇會回顧運用到的一些知識點。
1.MDI子窗口的建立:
首先一個窗體能夠創建多個MDI窗體,應當將IsMDIContainer屬性設為true;以下為效果圖:

控制窗體切換的是一個DotNetBar.TabStrip控件,style屬性為Office2007Document,TabLayOutType:FixedWithNavigationBox
創建窗體的代碼如下:
01
/// <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的應用。