使用Microsoft.WindowsAPICodePack-Shell
我创建了一个控制台项目,通过读取文件夹,获得文件夹下所有Mp4文件,然后遍历并打印其名字和时长,这个方法获取时长的速度还是比较快的。
using Microsoft.WindowsAPICodePack.Shell;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
Console.WriteLine("Please enter the folder path");
//把文件夹拖进控制台后读取文件夹路径
string _folderPath = Console.ReadLine();
if (_folderPath == null)
{
Console.WriteLine("No files found");
}
else
{
DirectoryInfo path = new DirectoryInfo(_folderPath);
GetAllMp4Length(path);
}
void GetAllMp4Length(DirectoryInfo dir)
{
//获得此路径下所有的Mp4文件
FileInfo[] fileInfos = dir.GetFiles("*.mp4", SearchOption.AllDirectories);
foreach (FileInfo fileInfo in fileInfos)
{
TimeSpan timeSpan = GetVideoDuration(fileInfo.DirectoryName + "\\" + fileInfo.Name);
Console.WriteLine(fileInfo.Name +" : "+timeSpan);
}
}
TimeSpan GetVideoDuration(string filePath)
{
//WindowsAPICodePack-Shell 的使用
var shell = ShellObject.FromParsingName(filePath);
IShellProperty prop = shell.Properties.System.Media.Duration;
long t = (long)(ulong)prop.ValueAsObject;
return TimeSpan.FromTicks((long)t);
}
mvhd
GitHub上找的,这种方法不依赖第三方库了,但速度奇慢。
internal class Mp4Duration
{
/// <summary>
/// get mp4 duration
/// </summary>
/// <param name="fileName"></param>
/// <returns>second</returns>
public static double GetMp4Duration(string fileName)
{
ulong timeScale = 0;
ulong timeUnits = 0;
int byteSize = 4;
string str = "mvhd";
var charStr = Encoding.ASCII.GetBytes(str);
byte[] array = File.ReadAllBytes(fileName);
var indexOfCuurent = ByteUtils.IndexOf(array, charStr, 0);
indexOfCuurent += 4;
if (array[indexOfCuurent] == 1)
{
byteSize = 8;
}
indexOfCuurent += 4;//now point to the createa date
//byte[] createDateByte = new byte[byteSize];
//Array.Copy(array, indexOfCuurent, createDateByte, 0, byteSize);
//var createDate = BitConverter.ToUInt32(createDateByte, 0);
indexOfCuurent += byteSize;
indexOfCuurent += byteSize;
byte[] timeScaleByte = new byte[4];
Array.Copy(array, indexOfCuurent, timeScaleByte, 0, 4);
timeScale = BitConverter.ToUInt32(timeScaleByte, 0);
indexOfCuurent += 4;
byte[] timeUnitsByte = new byte[4];
Array.Copy(array, indexOfCuurent, timeUnitsByte, 0, 4);
timeUnits = BitConverter.ToUInt32(timeUnitsByte, 0);
timeScale = InfoFlip(timeScale);
timeUnits = InfoFlip(timeUnits);
return timeUnits * 1.0 / timeScale;
}
static UInt64 InfoFlip(UInt64 vla)
{
UInt64 tem = 0;
tem += (vla & 0x000000FF) << 24;
tem += (vla & 0xFF000000) >> 24;
tem += (vla & 0x0000FF00) << 8;
tem += (vla & 0x00FF0000) >> 8;
return tem;
}
}
internal sealed class ByteUtils
{
public static int IndexOf(byte[] array, byte[] pattern, int offset)
{
int success = 0;
for (int i = offset; i < array.Length; i++)
{
if (array[i] == pattern[success])
{
success++;
}
else
{
success = 0;
}
if (pattern.Length == success)
{
return i - pattern.Length + 1;
}
}
return -1;
}
}
//调用
void GetAllMp4Length(DirectoryInfo dir)
{
FileInfo[] fileInfos = dir.GetFiles("*.mp4", SearchOption.AllDirectories);
foreach (FileInfo fileInfo in fileInfos)
{
double t = Mp4Duration.GetMp4Duration(fileInfo.DirectoryName + "\\" + fileInfo.Name);
Console.WriteLine(fileInfo.Name +" : "+t);
}
}
标签:Console,读取,indexOfCuurent,byteSize,Mp4,byte,fileInfo,Tools,array
From: https://www.cnblogs.com/flashing-magic/p/16712814.html