简体   繁体   中英

What is the fastest way to get a media file's duration?

I am working on a program that scans drop folders for files, and registers them to another system that requires a duration for the file. The best solution I've been able to find so far is to use MediaInfo to get the duration from the header, but for some reason it tends to take a few seconds to return a result.

Suppose I have a list of 1,000 file paths, and I want to get the duration for each one, but getting the duration takes 15 seconds. Linear iteration over the list would take just over 4 hours, and even running 8 tasks in parallel would take half an hour. With my tests, this would be the best case scenario.

I've tried using the MediaInfo DLL as well as calling the .exe, and both seemed to have similar processing times.

DLL Code:

MediaInfo MI;

public Form1()
{
    InitializeComponent();
    MI = new MediaInfo();
}

private void button1_Click(object sender, EventArgs e)
{
    MI.Open(textBox1.Text);
    MI.Option("Inform", "Video;%Duration%");
    label2.Text = MI.Inform();
    MI.Close();
}

Executable code:

Process proc = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = "MediaInfo.exe",
        Arguments = $"--Output=Video;%Duration% \"{textBox1.Text}\"",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true
    }
};

StringBuilder line = new StringBuilder();
proc.Start();

while (!proc.StandardOutput.EndOfStream)
{
    line.Append(proc.StandardOutput.ReadLine());
}

label2.Text = line.ToString();

It should be noted that the files being processed are on a networked drive, but I have tested retrieving the duration of a local file and it was only a few seconds faster. Note, this program has to run on Windows Server 2003 R2, which means .net 4.0 only. Most of the files I will be processing are .mov but I can't restrict it to that.

Some better code (prefer DLL call, init takes time) with options for reducing the scan duration:

MediaInfo MI;

public Form1()
{
    InitializeComponent();
    MI = new MediaInfo();
    MI.Option("ParseSpeed", "0"); // Advanced information (e.g. GOP size, captions detection) not needed, request to scan as fast as possible
    MI.Option("ReadByHuman", "0"); // Human readable strings are not needed, no noeed to spend time on them
}

private void button1_Click(object sender, EventArgs e)
{
    MI.Open(textBox1.Text);
    label2.Text = MI.Get(Stream_Video, "Duration"); //Note: prefer Stream_General if you want the duration of the program (here, you select the duration of the video stream)
    MI.Close();
}

There are several possibilities for improving parsing time depending of your specific needs (ie you don't care of lot of features) but this is code to add directly to MediaInfo (eg for MP4/QuickTime files, getting only the duration could take less than 200 ms if I disable other features), add a feature request if you need speed.

Jérôme, developer of MediaInfo

apt-get install python-pip
pip install pymediainfo

#!/usr/bin/env python
import pymediainfo
duration = float(pymediainfo.MediaInfo.parse(myfilename).tracks[0])/1000.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM