Several Methods to Get Video Duration with FFmpeg

In video processing, batch transcoding, or automated workflows, obtaining video duration is a common requirement. The FFmpeg ecosystem provides multiple methods to achieve this functionality. This article will introduce several commonly used techniques.

Using ffprobe to Get Duration

ffprobe is a media information probing tool included with FFmpeg, and it's the best choice for获取 video metadata.

Basic Command

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4

This command will return the duration in seconds, such as 30.024000.

Human-Readable Time Format

Adding the -sexagesimal option can convert the output to hours:minutes:seconds.microseconds format:

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -sexagesimal input.mp4

Example output: 0:00:30.024000

Using ffmpeg Command to Get Duration

If you don't have ffprobe installed separately, you can also get duration information directly using the ffmpeg command.

Get Seconds Directly

ffmpeg -i input.mp4 2>&1 | grep "Duration" | cut -d ' ' -f 4 | sed s/,// | awk -F: '{ print $1*3600 + $2*60 + $3 }'

Get Original Duration Information

If you need to keep the duration information in its original format:

Linux/macOS:

ffmpeg -i input.mp4 2>&1 | grep Duration

Windows Command Prompt:

ffmpeg -i input.mp4 2>&1 | find "Duration"

Windows PowerShell:

ffmpeg -i input.mp4 2>&1 | Select-String "Duration"

Note: There is no find command in PowerShell; you need to use Select-String (can be abbreviated as sls) instead. The 2>&1 redirection syntax is still valid in PowerShell.

Example output: Duration: 00:11:16.70, start: 0.000000, bitrate: 206 kb/s

Script Implementation

Bash Script

#!/bin/bash

# Input file path
IN_FILE="input.mp4"

# Get duration information
DURATION_HMS=$(ffmpeg -i "$IN_FILE" 2>&1 | grep Duration | cut -f 4 -d ' ')

# Parse hours, minutes, seconds
DURATION_H=$(echo "$DURATION_HMS" | cut -d ':' -f 1)
DURATION_M=$(echo "$DURATION_HMS" | cut -d ':' -f 2)
DURATION_S=$(echo "$DURATION_HMS" | cut -d ':' -f 3 | cut -d '.' -f 1)

# Calculate total seconds
let "DURATION = ( DURATION_H * 60 + DURATION_M ) * 60 + DURATION_S"

echo "Video duration: $DURATION seconds ($DURATION_HMS)"

Windows VBS Script

Dim wShell
Set wShell=CreateObject("WScript.Shell")

Function getVideoSeconds(vfile)
    dim strCmd, duration, tmp, parts, objExec

    ' Build command
    strCmd="cmd /c ""ffmpeg -i " & vfile & " 2>&1"""
    
    ' Execute command and capture output
    duration=""
    set objExec=wsShell.Exec(strCmd)
    Do
        tmp=objExec.StdOut.ReadLine
        if InStr(1,tmp,"Duration")>0 then
            duration=tmp
            exit do
        end if
    Loop while not objExec.StdOut.atEndOfStream

    ' Handle error cases
    if duration="" then
        getVideoSeconds=0
        exit Function
    end if

    ' Parse and calculate seconds
    parts=Split(Replace(duration,",",":"),":",-1)
    getVideoSeconds=CDbl(parts(1))*3600 + CDbl(parts(2))*60 + CDbl(parts(3))
End Function

' Usage example
Dim videoFile, durationSec
videoFile="C:\path\to\your\video.mp4"
durationSec=getVideoSeconds(videoFile)
WScript.Echo "Video duration: " & durationSec & " seconds"

Notes

  1. Ensure FFmpeg is correctly installed and added to the system PATH
  2. For some special format video files, additional decoder support may be required
  3. When using scripts, pay attention to handling possible error situations, such as non-existent files or unsupported formats
  4. The ffprobe method is more efficient than the ffmpeg method because it only reads file metadata without parsing the entire file

Reference: