此项目需求是针对.wav格式音频进行操作,转换成相应的.mp3格式的音频文件,对音频进行切割,最后以需求的形式输出,此篇会回顾运用到的一些知识点。
1.MDI子窗口的建立:
首先一个窗体能够创建多个MDI窗体,应当将IsMDIContainer属性设为true;以下为效果图:
控制窗体切换的是一个DotNetBar.TabStrip控件,style属性为Office2007Document,TabLayOutType:FixedWithNavigationBox
创建窗体的代码如下:
01
class="color1">/// <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的应用。