首页 > 其他分享 >【Tools】读取Mp4文件时长

【Tools】读取Mp4文件时长

时间:2022-09-20 22:35:45浏览次数:43  
标签:Console 读取 indexOfCuurent byteSize Mp4 byte fileInfo Tools array

使用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

相关文章