[linux] How to extract duration time from ffmpeg output?

To get a lot of information about a media file one can do

ffmpeg -i <filename>

where it will output a lot of lines, one in particular

Duration: 00:08:07.98, start: 0.000000, bitrate: 2080 kb/s

I would like to output only 00:08:07.98, so I try

ffmpeg -i file.mp4 | grep Duration| sed 's/Duration: \(.*\), start/\1/g'

But it prints everything, and not just the length.

Even ffmpeg -i file.mp4 | grep Duration outputs everything.

How do I get just the duration length?

This question is related to linux bash ffmpeg

The answer is


ffmpeg has been substituted by avconv: just substitute avconb to Louis Marascio's answer.

avconv -i file.mp4 2>&1 | grep Duration | sed 's/Duration: \(.*\), start.*/\1/g'

Note: the aditional .* after start to get the time alone !!


I would just do this in C++ with a text file and extract the tokens. Why? I am not a linux terminal expert like the others.
To set it up I would do this in Linux..

ffmpeg -i 2>&1 | grep "" > mytext.txt

and then run some C++ app to get the data needed. Maybe extract all the important values and reformat it for further processing by using tokens. I will just have to work on my own solution and people will just make fun of me because I am a linux newbie and I do not like scripting too much.


Best Solution: cut the export do get something like 00:05:03.22

ffmpeg -i input 2>&1 | grep Duration | cut -c 13-23

ffmpeg -i abc.mp4 2>&1 | grep Duration | cut -d ' ' -f 4 | sed s/,//

gives output

HH:MM:SS.milisecs


In case of one request parameter it is simplier to use mediainfo and its output formatting like this (for duration; answer in milliseconds)

mediainfo --Output="General;%Duration%" ~/work/files/testfiles/+h263_aac.avi 

outputs

24840

For those who want to perform the same calculations with no additional software in Windows, here is the script for command line script:

set input=video.ts

ffmpeg -i "%input%" 2> output.tmp

rem search "  Duration: HH:MM:SS.mm, start: NNNN.NNNN, bitrate: xxxx kb/s"
for /F "tokens=1,2,3,4,5,6 delims=:., " %%i in (output.tmp) do (
    if "%%i"=="Duration" call :calcLength %%j %%k %%l %%m
)
goto :EOF

:calcLength
set /A s=%3
set /A s=s+%2*60
set /A s=s+%1*60*60
set /A VIDEO_LENGTH_S = s
set /A VIDEO_LENGTH_MS = s*1000 + %4
echo Video duration %1:%2:%3.%4 = %VIDEO_LENGTH_MS%ms = %VIDEO_LENGTH_S%s

Same answer posted here: How to crop last N seconds from a TS video


If you want to retrieve the length (and possibly all other metadata) from your media file with ffmpeg by using a python script you could try this:

import subprocess
import json

input_file  = "< path to your input file here >"

metadata = subprocess.check_output(f"ffprobe -i {input_file} -v quiet -print_format json -show_format -hide_banner".split(" "))

metadata = json.loads(metadata)
print(f"Length of file is: {float(metadata['format']['duration'])}")
print(metadata)

Output:

Length of file is: 7579.977143

{
  "streams": [
    {
      "index": 0,
      "codec_name": "mp3",
      "codec_long_name": "MP3 (MPEG audio layer 3)",
      "codec_type": "audio",
      "codec_time_base": "1/44100",
      "codec_tag_string": "[0][0][0][0]",
      "codec_tag": "0x0000",
      "sample_fmt": "fltp",
      "sample_rate": "44100",
      "channels": 2,
      "channel_layout": "stereo",
      "bits_per_sample": 0,
      "r_frame_rate": "0/0",
      "avg_frame_rate": "0/0",
      "time_base": "1/14112000",
      "start_pts": 353600,
      "start_time": "0.025057",
      "duration_ts": 106968637440,
      "duration": "7579.977143",
      "bit_rate": "320000",
      ...
      ...

You can use ffprobe:

ffprobe -i <file> -show_entries format=duration -v quiet -of csv="p=0"

It will output the duration in seconds, such as:

154.12

Adding the -sexagesimal option will output duration as hours:minutes:seconds.microseconds:

00:02:34.12

From my experience many tools offer the desired data in some kind of a table/ordered structure and also offer parameters to gather specific parts of that data. This applies to e.g. smartctl, nvidia-smi and ffmpeg/ffprobe, too. Simply speaking - often there's no need to pipe data around or to open subshells for such a task.

As a consequence I'd use the right tool for the job - in that case ffprobe would return the raw duration value in seconds, afterwards one could create the desired time format on his own:

$ ffmpeg --version
ffmpeg version 2.2.3 ...

The command may vary dependent on the version you are using.

#!/usr/bin/env bash
input_file="/path/to/media/file"

# Get raw duration value
ffprobe -v quiet -print_format compact=print_section=0:nokey=1:escape=csv -show_entries format=duration "$input_file"

An explanation:

"-v quiet": Don't output anything else but the desired raw data value

"-print_format": Use a certain format to print out the data

"compact=": Use a compact output format

"print_section=0": Do not print the section name

":nokey=1": do not print the key of the key:value pair

":escape=csv": escape the value

"-show_entries format=duration": Get entries of a field named duration inside a section named format

Reference: ffprobe man pages


I recommend using json format, it's easier for parsing

ffprobe -i your-input-file.mp4 -v quiet -print_format json -show_format -show_streams -hide_banner

{
    "streams": [
        {
            "index": 0,
            "codec_name": "aac",
            "codec_long_name": "AAC (Advanced Audio Coding)",
            "profile": "HE-AACv2",
            "codec_type": "audio",
            "codec_time_base": "1/44100",
            "codec_tag_string": "[0][0][0][0]",
            "codec_tag": "0x0000",
            "sample_fmt": "fltp",
            "sample_rate": "44100",
            "channels": 2,
            "channel_layout": "stereo",
            "bits_per_sample": 0,
            "r_frame_rate": "0/0",
            "avg_frame_rate": "0/0",
            "time_base": "1/28224000",
            "duration_ts": 305349201,
            "duration": "10.818778",
            "bit_rate": "27734",
            "disposition": {
                "default": 0,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0
            }
        }
    ],
    "format": {
        "filename": "your-input-file.mp4",
        "nb_streams": 1,
        "nb_programs": 0,
        "format_name": "aac",
        "format_long_name": "raw ADTS AAC (Advanced Audio Coding)",
        "duration": "10.818778",
        "size": "37506",
        "bit_rate": "27734",
        "probe_score": 51
    }
}

you can find the duration information in format section, works both for video and audio


Argh. Forget that. It looks like I have to get the cobwebs out of my C and C++ programming and use that instead. I do not know all the shell tricks to get it to work. This is how far I got.

ffmpeg -i myfile 2>&1 | grep "" > textdump.txt

and then I would probably extract the duration with a C++ app instead by extracting tokens.

I am not posting the solution because I am not a nice person right now

Update - I have my approach to getting that duration time stamp

Step 1 - Get the media information on to a text file
`ffprobe -i myfile 2>&1 | grep "" > textdump.txt`
OR
`ffprobe -i myfile 2>&1 | awk '{ print }' > textdump.txt`

Step 2 - Home in on the information needed and extract it
cat textdump.txt | grep "Duration" | awk '{ print $2 }' | ./a.out
Notice the a.out. That is my C code to chop off the resulting comma because the output is something like 00:00:01.33,
Here is the C code that takes stdin and outputs the correct information needed. I had to take the greater and less than signs out for viewing.

#include stdio.h #include string.h void main() { //by Admiral Smith Nov 3. 2016 char time[80]; int len; char *correct; scanf("%s", &time); correct = (char *)malloc(strlen(time)); if (!correct) { printf("\nmemory error"); return; } memcpy(correct,&time,strlen(time)-1); correct[strlen(time)]='/0'; printf("%s", correct); free(correct); }

Now the output formats correctly like 00:00:01.33


You could try this:

/*
* Determine video duration with ffmpeg
* ffmpeg should be installed on your server.
*/
function mbmGetFLVDuration($file){

  //$time = 00:00:00.000 format
  $time =  exec("ffmpeg -i ".$file." 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//");

  $duration = explode(":",$time);
  $duration_in_seconds = $duration[0]*3600 + $duration[1]*60+ round($duration[2]);

  return $duration_in_seconds;

}

$duration = mbmGetFLVDuration('/home/username/webdir/video/file.mov');
echo $duration;

Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to bash

Comparing a variable with a string python not working when redirecting from bash script Zipping a file in bash fails How do I prevent Conda from activating the base environment by default? Get first line of a shell command's output Fixing a systemd service 203/EXEC failure (no such file or directory) /bin/sh: apt-get: not found VSCode Change Default Terminal Run bash command on jenkins pipeline How to check if the docker engine and a docker container are running? How to switch Python versions in Terminal?

Examples related to ffmpeg

OCI runtime exec failed: exec failed: (...) executable file not found in $PATH": unknown Using ffmpeg to change framerate FFMPEG mp4 from http live streaming m3u8 file? ffprobe or avprobe not found. Please install one How to extract 1 screenshot for a video with ffmpeg at a given time? What steps are needed to stream RTSP from FFmpeg? How to create a video from images with FFmpeg? Download TS files from video stream Best approach to real time http streaming to HTML5 video client Cutting the videos based on start and end time using ffmpeg