此項目需求是針對.wav格式音頻進行操作,轉換成相應的.mp3格式的音頻文件,對音頻進行切割,最後以需求的形式輸出,此篇會回顧運用到的一些知識點。
1.MDI子窗口的建立:
首先一個窗體能夠創建多個MDI窗體,應當將IsMDIContainer屬性設為true;以下為效果圖:
控制窗體切換的是一個DotNetBar.TabStrip控件,style屬性為Office2007Document,TabLayOutType:FixedWithNavigationBox
創建窗體的代碼如下:
01
/// <summary>
02
/// 創建MDI子窗體類
03
/// </summary>
04
class
CreateMDIWindow
05
{
06
/// <summary>
07
/// 當前程序的主窗體對象
08
/// </summary>
09
public
static
Form 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
in
childForms)
27
{
28
if
(f
is
T)
29
{
30
form = f
as
T;
31
break
;
32
}
33
}
34
//如果沒有,則創建
35
if
(form ==
null
)
36
{
37
//新建窗體
38
form =
new
T();
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
class
UserSetting
03
{
04
/// <summary>
05
/// 序列化存儲路徑
06
/// </summary>
07
private
string
FilePath{
get
{
return
Path.Combine(Environment.CurrentDirectory,
"User.data"
); } }
08
09
/// <summary>
10
/// 音頻資源存儲目錄
11
/// </summary>
12
public
string
AudioResourceFolder {
get
;
set
; }
13
14
/// <summary>
15
/// 項目名稱
16
/// </summary>
17
public
string
Solution {
get
;
set
; }
18
19
/// <summary>
20
/// 構造函數,創建序列化存儲文件
21
/// </summary>
22
public
UserSetting()
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
public
UserSetting ReadUserSetting()
35
{
36
using
(FileStream fs =
new
FileStream(FilePath, FileMode.Open,FileAccess.Read))
37
{
38
object
ob =
null
;
39
if
(fs.Length > 0)
40
{
41
SoapFormatter sf =
new
SoapFormatter();
42
ob = sf.Deserialize(fs);
43
}
44
return
ob
as
UserSetting;
45
}
46
}
47
48
/// <summary>
49
/// 通過序列化方式,保存數據
50
/// </summary>
51
public
void
SaveUserSetting(
object
obj)
52
{
53
using
(FileStream fs =
new
FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write))
54
{
55
SoapFormatter sf =
new
SoapFormatter();
56
sf.Serialize(fs,obj);
57
}
58
}
59
60
}
3.Datagridview動態生成:
根據設置的樓層生成相應樓層帶button按鈕的datagridview,並且每層按鈕為每層選定選擇音樂,代碼如下:
01
/// <summary>
02
/// 綁定樓層音樂屬性
03
/// </summary>
04
private
void
BindData(
int
elevatorLow,
int
number)
05
{
06
try
07
{
08
DataTable list =
new
DataTable();
09
list.Columns.Clear();
10
list.Columns.Add(
new
DataColumn(
"name"
,
typeof
(
string
)));
11
list.Columns.Add(
new
DataColumn(
"musicPath"
,
typeof
(
string
)));
12
for
(
int
i =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(
object
sender, DataGridViewCellEventArgs e)
02
{
03
try
04
{
05
//點擊選擇按鈕觸發的事件
06
if
(e.RowIndex >= 0)
07
{
08
DataGridViewColumn column = dataGridViewX1.Columns[e.ColumnIndex];
09
if
(column
is
DataGridViewButtonColumn)
10
{
11
OpenFileDialog openMusic =
new
OpenFileDialog();
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(
string
filePath)
06
{
07
string
dirName = Path.GetDirectoryName(filePath);
08
string
SongName = Path.GetFileName(filePath);
//獲得歌曲名稱
09
ShellClass sh =
new
ShellClass();
10
Folder dir = sh.NameSpace(dirName);
11
FolderItem item = dir.ParseName(SongName);
12
string
SongTime = dir.GetDetailsOf(item, 27);
//27為獲得歌曲持續時間 ,28為獲得音樂速率,1為獲得音樂文件大小
13
string
[] time = Regex.Split(SongTime,
":"
);
14
return
time;
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,
string
arg)
07
{
08
using
(var p =
new
Process())
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(
object
sender, 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
int
bitrate = Convert.ToInt32(cobBitRate.Text) * 1000;
//恆定碼率
09
string
Hz = 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
in
listMusics.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(
object
sender, EventArgs e)
02
{
03
SaveFileDialog saveMusic =
new
SaveFileDialog();
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
string
startTime =
string
.Format(
"0:{0}:{1}"
, txtBeginM.Text, txtBeginS.Text).Trim();
//歌曲起始時間
09
int
duration = (Convert.ToInt32(
this
.txtEndM.Text) * 60 + Convert.ToInt32(
this
.txtEndS.Text)) - (Convert.ToInt32(
this
.txtBeginM.Text) * 60 + Convert.ToInt32(
this
.txtBeginS.Text));
10
string
endTime =
string
.Format(
"0:{0}:{1}"
, duration / 60, duration % 60);
//endTime是持續的時間,不是歌曲結束的時間
11
if
(saveMusic.ShowDialog() == DialogResult.OK)
12
{
13
string
savePath = 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的應用。