【Tools】读取Mp4文件时长
使用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);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律