此项目需求是针对.wav格式音频进行操作,转换成相应的.mp3格式的音频文件,对音频进行切割,最后以需求的形式输出,此篇会回顾运用到的一些知识点。
1.MDI子窗口的建立:
首先一个窗体能够创建多个MDI窗体,应当将IsMDIContainer属性设为true;以下为效果图:
控制窗体切换的是一个DotNetBar.TabStrip控件,style属性为Office2007Document,TabLayOutType:FixedWithNavigationBox
创建窗体的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
/// <summary> /// 创建MDI子窗体类
/// </summary>
class CreateMDIWindow
{
/// <summary>
/// 当前程序的主窗体对象
/// </summary>
public static Form MainForm { get ; set ; }
/// <summary>
/// 创建子窗口
/// </summary>
///
<typeparam name= "T" > 窗口类型
</typeparam> public static void CreateChildWindow
<t> () 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();
}
}
</t> |
前台点击按钮调用代码:CreateMDIWindow.CreateChildWindow (); <>里为窗体的名称。
2.序列化与反序列化:
当一个系统你有默认的工作目录,默认的文件保存路径,且这些数据时唯一的,你希望每次打开软件都会显示这些数据,也可以更新这些数据,可以使用序列化与反序列化。
我们以项目存储根目录和选择项目为例:
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
[Serializable] public class UserSetting
{ /// <summary>
/// 序列化存储路径
/// </summary>
private string FilePath{ get { return Path.Combine(Environment.CurrentDirectory, "User.data" ); } }
/// <summary>
/// 音频资源存储目录
/// </summary>
public string AudioResourceFolder { get ; set ; }
/// <summary>
/// 项目名称
/// </summary>
public string Solution { get ; set ; }
/// <summary>
/// 构造函数,创建序列化存储文件
/// </summary>
public UserSetting()
{
if (!File.Exists(FilePath))
{
FileStream fs = File.Create(FilePath);
fs.Close(); //不关闭文件流,首次创建该文件后不能被使用买现成会被占用
}
}
/// <summary>
/// 通过反序列化方法,获得保存的数据
/// </summary>
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;
}
}
/// <summary>
/// 通过序列化方式,保存数据
/// </summary>
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,并且每层按钮为每层选定选择音乐,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
/// <summary> /// 绑定楼层音乐属性 /// </summary> 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()); }
} |
选择音乐按钮事件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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获得文件属性可以参考 点击打开链接
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/// <summary> /// 获得音乐长度 /// </summary> /// <param name="filePath">文件的完整路径 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目录下,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/// <summary> /// 转换函数 /// </summary> /// <param name="exe">ffmpeg程序 /// <param name="arg">执行参数 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(); //等待进程结束
}
} |
音频转换的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
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( "请选择你要转换的音乐" );
}
} |
音频切割的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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