在看视频教程的时候,由于视频是一段一段的,持续时间长短也不同,导致学习进度安排起来有点小麻烦,于是就想自己做个统计视频持续时间的工具来辅助视频学习。
想做就做!按照我奉行的“用以致学,基础为先”的准则。首先要解决零散的基础知识点:
程序的目的是将人从重复的劳动中解放出来,为使用者提供方便。于是我就想如何手动得到媒体持续时间。终于,我在avi文件的属性中找到了。既然操作系统可以获取到持续时间,那我们也就一定可以。于是,上网搜索资料,终于找到了Shell32.dll中提供的方法:
ShellClass sh = new ShellClass();
Folder dir = sh.NameSpace(Path.GetDirectoryName(FilePath)); //FilePath为文件的绝对路径
FolderItem item = dir.ParseName(Path.GetFileName(FilePath));
string stime = dir.GetDetailsOf(item, 21);
当然,我们也可以遍历得到文件的全部信息,从而做到举一反三,一通百通。
StringBuilder sb = new StringBuilder();
for (int i = -1; i < 50; i++)
{
sb.Append(i.ToString());
sb.Append(":");
sb.Append(dir.GetDetailsOf(item, i));
sb.Append("/r/n");
}
string sout = sb.ToString();
MessageBox.Show(sout);
修改:由于每次都是只能添加一个文件实在是很不爽,本着偷懒至上的原则,修改成了多选了。代码如下:
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "所有文件|*.*|AVI文件|*.avi";
ofd.Multiselect = true;//可多选
DialogResult dr = ofd.ShowDialog();
if (dr == DialogResult.OK)
{
for (int i = 0; i < ofd.FileNames.Length; i++)
{
lstbDir.Items.Add(ofd.FileNames.GetValue(i).ToString());
}
}
我最终决定使用ListBox存放一行行的文件路径(从文本合并器上得到的思路,在此表示感谢!)。通过回顾一些其他的软件,定下了2中添加文件到ListBox的方法:直接添加文件和添加文件夹(类似酷狗的添加音乐O(∩_∩)O~)。
直接添加文件[单个文件的绝对路径]的方法:
OpenFileDialog ofd = new OpenFileDialog();//创建一个”打开文件”对话框对象(只创建,不显示)!
ofd.Filter = "所有文件|*.*|AVI文件|*.avi";//设置对话框中打开文件类型。
DialogResult dr = ofd.ShowDialog();//显示对话框
if (dr == DialogResult.OK)
{
lstbDir.Items.Add(ofd.FileName); //lstbDir就是ListBox的name
}
注意:DialogResult的值是对话框操作的结果,只有其值为DialogResult.OK才是正常选中了一个文件。ofd.FileName即文件的绝对路径。
添加文件夹的方法:
FolderBrowserDialog fbd = new FolderBrowserDialog();
DialogResult dr = fbd.ShowDialog();
if (dr == DialogResult.OK)
{
DirectoryInfo di = new DirectoryInfo(fbd.SelectedPath);
FileInfo[] fia = di.GetFiles();//获取文件夹里的文件列表,不含其子文件夹的
foreach (FileInfo fi in fia)
{
lstbDir.Items.Add(fi.FullName);
}
}
如果要当前目录的子目录列表可以调用di.GetDirectories();遍历子目录列表可以获得子目录中的文件列表。
我先做的是删除选中的ListBox项,后来发现,如果要删除多项的话,一个个的删除实在是太慢。测试发现,如果ListBox中什么都没选中,lstbDir.SelectedIndex的值是-1,于是我就想到用while循环来删除,直到lstbDir.SelectedIndex的值为-1为止。还真成功了,呵呵~~
int i = lstbDir.SelectedIndex;
while (i >= 0)
{
lstbDir.Items.RemoveAt(i);
i = lstbDir.SelectedIndex;
}
如何将1中得到的字符串类型的文件持续时间{“0:01:12”类型}转换为相应的数字,我用的是字符串的Split()方法按照“:”分得到3个小字符串,然后用Int32.TryParse()方法转换成数字。
对于得到的时间数字,一开始是想使用DateTime,可是的DateTime属性器是没有set的,用起来麻烦,放弃了,自己写了个CTime类,并做了加法运算符重载,和一个ToTimeString()的方法返回时间字符串。
至此为止,基础知识点都搞定了。由于这是总结型的文章,就直接贴源码了。
有了这些基础知识,再加上一些流程控制的代码就可以完成这个小工具了。
1、如果媒体文件的属性信息里没有添加文件持续时间的值,那用这种方法就取不到这个值,有待新的方法更精确地获取持续时间。
