How To Get Video Duration With FFMPEG and PHP

This thread may refer to an older version of JW Player! Check our articles for the most up-to-date information.
This Q&A thread was imported from our previous system and could apply to an older product.
  • i would like to use PHP and FFMPEG to get the DURATION of the VIDEO so i can save into the Database.. I found some examples but could not get to work

    my path to my FFMPEG is

    */usr/local/bin/ffmpeg*

    here is the example of of snippet but it looks to be local for the ffmpeg??

    so much help appreciated if you can fix the php code and fix the proper path i provided above to grab the DURATION in a php file.. thanks for any help to get this properly working as i do not want to have to use ffmpeg-php


    bc.. if (isset($_GET['percent']))
    {
    $percent = $_GET['percent'];

    ob_start();
    passthru("ffmpeg-9260.exe -i \"". $videofile . "\" 2>&1");
    $duration = ob_get_contents();
    ob_end_clean();

    preg_match('/Duration: (.*?),/', $duration, $matches);
    $duration = $matches[1];
    $duration_array = split(':', $duration);
    $duration = $duration_array[0] * 3600 + $duration_array[1] * 60 + $duration_array[2];
    $time = $duration * $percent / 100;
    $time = intval($time/3600) . ":" . intval(($time-(intval($time/3600)*3600))/60) . ":" . sprintf("%01.3f", ($time-(intval($time/60)*60)));
    }

  • First, you should change the script to:bc.. passthru("ffmpeg -i \"{$videofile}\" 2>&1");


    Then try ffmpeg from the command line in the directory where the script is, to confirm that it works:bc.. ffmpeg -i /path/path/videofile.flv

    Up Down 0 rated
  • sadhu

    Up Down 0 rated
  • Nice code it runnung fine.
    Thanks

    Up Down 0 rated
  • What "ob_start();" do ?

    Up Down 0 rated
  • http://www.google.com/search?hl=en&q=PHP+ob_start%28%29&aq=f&oq=

    Up Down 0 rated
  • muchas gracias!!

    Up Down 0 rated
  • This one worked for me:

    <?php
    $videofile="/var/video/user_videos/partofvideo.avi";
    ob_start();
    passthru("/usr/bin/ffmpeg -i \"{$videofile}\" 2>&1");
    $duration = ob_get_contents();
    ob_end_clean();

    $search='/Duration: (.*?),/';
    $duration=preg_match($search, $duration, $matches, PREG_OFFSET_CAPTURE, 3);
    //TEST ECHO
    echo $matches[1][0];
    ?>

    Up Down 0 rated
  • thanks as i will try to implement this into my php code..

    as users were having issue ffmpeg-php..


    anyone have any other experience on any other ways to the duration with any other php files.. ID3Tag, etc

    Up Down 0 rated
  • hy,

    when i convert any media file into flv through ffmpeg.
    orignal file have metadata but the converted flv file have not complete metadata which some information lost.
    such as duration.which i need.
    for copy metadata input file to output file this command is used (-map_meta_data output file:input file) but this parameter does not work.
    which always movie file duration show 00:00:00.
    please help me.
    thanks

    Rana Muhammad Saleem

    Up Down 0 rated
  • hy,
    when i used this code
    ob_start();
    passthru("ffmpeg-9260.exe -i \"". $videofile . "\" 2>&1");
    $duration = ob_get_contents();
    ob_end_clean();

    preg_match('/Duration: (.*?),/', $duration, $matches);
    $duration = $matches[1];

    in which movie file duration show different from the orignal file duration which is showing by any player.
    please help me why this code show wrong different file duration.
    i have experienced with multiple file.
    please help
    thanks
    Rana muhammad Saleem

    Up Down 0 rated
  • hay,

    when i convert any media file into flv through ffmpeg.
    orignal file have metadata but the converted flv file have not complete metadata which some information lost.
    such as duration.which i need.
    for copy metadata input file to output file this command is used (-map_meta_data output file:input file) but this parameter does not work.
    which always movie file duration show 00:00:00.
    please help me.
    thanks

    Up Down 0 rated
  • i am using this commang

    exec("ffmpeg -i $fileToFlv -ar 44100 -sameq -an $fileFlv");

    after conversion, size of file increase too large and duration metadata missing.
    Please help me

    Up Down 0 rated
  • Somebody knows how obtain the duration with vb6.0 thanks...

    Up Down 0 rated
  • There's a Ruby tool that manipulates metadata; ffmpeg is a powerful tool, but it's a bit of overkill just to get the duration of an flv no?

    http://rubyforge.org/frs/?group_id=1096&release_id=9694

    It will even output the data as xml, very useful.

    Up Down 0 rated

  • ffmpeg is lightining fast!

    That's why it's the best tool to use for video.

    Not that it's needed here, but ffmpeg will transcode at 3~4 times the framerate, making real-time transcoding very usable.

    ffmpeg will also serve "chunks" of FLV video without regard to keyframes.

    It's the best tool there is.

    Up Down 0 rated
  • Ok so how do i parse this into the player (script) then ?

    for example, my player script has :-

    <?php
    ob_start();
    //$whereis ffmpeg: change with /usr/local/bin/ffmpeg
    passthru("/usr/local/bin/ffmpeg -i ".$file." 2>&1");
    $duration = ob_get_contents();
    ob_end_clean();

    //the full output:
    //echo $duration."<br/>";

    $search='/Duration: (.*?)[.]/';
    $duration=preg_match($search, $duration, $matches, PREG_OFFSET_CAPTURE);
    $duration = $matches[1][0];

    //i suppose that our video hasn't duration of a day+ :
    list($hours, $mins, $secs) = split('[:]', $duration);

    echo $duration;
    ?>

    then in the java script section (to invoke the player), i have

    so.addVariable('duration','<?php echo $duration; ?>');

    Since the duration string is derived from the first bit of php script it should work but it does not.

    How do i get this to work ?

    Thanks Rich

    Up Down 0 rated
  • at the moment to get my non flv videos to work with some sort of progress bar i have to cheat with :-

    so.addVariable('duration','10800');

    basic say that my media files are 3 hours long.

    Up Down 0 rated
  • I managed to fix my own issue

    now what ever video format ffmpeg supports, on file selection the player file will then interogate the file for duration then parse this out the the jw player under $duration_in_seconds string

    code -

    <?php
    $path = '/mnt/data/video/films/';
    $filename = htmlspecialchars($_GET["file"]);
    $ext=strrchr($filename, ".");
    $file = $path . $filename;

    ob_start();
    passthru("/usr/local/bin/ffmpeg -i \"". $file . "\" 2>&1");
    $duration = ob_get_contents();
    ob_end_clean();

    preg_match('/Duration: (.*?),/', $duration, $matches);
    $duration = $matches[1];
    list($hr,$m,$s) = explode(':', $duration);
    $duration_in_seconds = ( (int)$hr*3600 ) + ( (int)$m*60 ) + (int)$s;

    // a work around for now - need to remove when above works
    //$duration_in_seconds = 10800
    //}
    ?>

    then further down the same php script i have the players code -

    <script type='text/javascript'>
    var so = new SWFObject('player-viral.swf','ply','640','360','9','#ffffff');
    so.addParam('allowfullscreen','true');
    so.addVariable('smoothing','false');
    so.addVariable('deblocking','0');
    so.addParam('allowscriptaccess','always');
    so.addParam('wmode','opaque');
    so.addVariable('frontcolor','EEEEEE');
    so.addVariable('backcolor','333333');
    so.addVariable('provider','video');
    so.addVariable('bufferlength','20');
    so.addVariable('duration','<?php echo $duration_in_seconds; ?>');
    so.addVariable('stretching','exactfit');
    so.addVariable('autostart','true');
    so.addVariable('file','/filmstreamencoder.php?file=<?php echo $_GET["file"]; ?>&position=0');
    so.write('mediaspace');
    </script>

    well happy i finally nailed it.

    Up Down 0 rated
  • <?php

    $file= ".../movie.flv"

    //ffmpeg-php method without the same output as mine:
    //$movie = new ffmpeg_movie($file);
    //echo $movie->getDuration();


    ob_start();
    //$whereis ffmpeg: change with /usr/local/bin/ffmpeg
    passthru("/usr/local/bin/ffmpeg -i ".$file." 2>&1");
    $duration = ob_get_contents();
    ob_end_clean();

    //the full output:
    //echo $duration."<br/>";

    $search='/Duration: (.*?)[.]/';
    $duration=preg_match($search, $duration, $matches, PREG_OFFSET_CAPTURE);
    $duration = $matches[1][0];

    //i suppose that our video hasn't duration of a day+ :
    list($hours, $mins, $secs) = split('[:]', $duration);

    echo "Hours: ".$hours." Minutes: ".$mins." Seconds: ".$secs;

    ?>

    Up Down 0 rated
  • Try this to get the width and height too (there's probably a swisher way!):

    ob_start();
    passthru("/usr/bin/ffmpeg -i \"{$videofile}\" 2>&1");
    $resolution = ob_get_contents();
    ob_end_clean();
    $search='/Video: (.*?),(.*?),(.*?),/';
    $resolution=preg_match($search, $resolution, $durmatches, PREG_OFFSET_CAPTURE, 3);
    $resolution= $durmatches[3][0];
    $resolutionsplit=array();

    $resolutionsplit=explode("x",$resolution);
    $videowidth=$resolutionsplit[0];
    $videoheight=$resolutionsplit[1];

    Up Down 0 rated
  • here's an example that works on windows well and returns the seconds instead of the 00:00:00 format:
    bc.. <?php
    $videofile="c:\\webs\\band\\bunny.flv";
    ob_start();
    passthru("C:\\ffmpeg.rev12665\\ffmpeg.exe -i \"{$videofile}\" 2>&1");
    $duration = ob_get_contents();
    ob_end_clean();
    $search='/Duration: (.*?),/';
    $duration=preg_match($search, $duration, $matches, PREG_OFFSET_CAPTURE, 3);
    $duration = $matches[1][0];
    //echo $duration."<BR>";
    $timearray = explode(":", $duration);
    $min = 60*$timearray[1];
    $sec = $timearray[2];
    $ttime = $min+$sec;
    if($dot = strpos($ttime, ".")){
    $ttime = substr($ttime, 0, 3);
    }
    echo $ttime;

    ?>

    Up Down 0 rated
  • i want get duration video a use ffmpeg java ?
    who can help me... please?

    Up Down 0 rated
  • bc.. $percent = 100;
    $text = "Seems stream 0 codec frame rate differs from container frame rate: 50.00 (50/1) -> 25.00 (25/1)
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/opt/lampp/htdocs/split_video/test.mp4':
    Duration: 01:44:13.68, start: 0.000000, bitrate: 718 kb/s
    Stream #0.0(und): Video: h264, yuv420p, 512x384, 25 tbr, 25 tbn, 50 tbc
    Stream #0.1(und): Audio: aac, 44100 Hz, mono, s16
    At least one output file must be specified";

    $preg = '|Duration: (.*),|siU';
    preg_match_all($preg, $text, $matches, PREG_PATTERN_ORDER);
    if(isset($matches[1][0])){
    $duration = trim($matches[1][0]);
    $duration_array = split(':', $duration);
    $duration = $duration_array[0] * 3600 + $duration_array[1] * 60 + $duration_array[2];
    $time = $duration * $percent / 100;
    $time = intval($time/3600) . ":" . intval(($time-(intval($time/3600)*3600))/60) . ":" . sprintf("%01.3f", ($time-(intval($time/60)*60)));
    print $time;
    }

    Up Down 0 rated
  • hello, my friends

    I am new to PHP. I use xampp and Window XP. I want to know how to convert video files to flv file type using ffmpeg. I find this information everywhere. But I can not find. Now here I find. Your
    informations are so cool. So can you guide me how to convert movies to flv file type using ffmpeg on XAMPP.

    Up Down 0 rated
  • You should really go to the FFmpeg site for that info. It’s a bit too serverside/technical for the kind of support we provide here.

     
    Up Down 0 rated
  • Just in case anyone was wondering .. you can also get the video width and height if you wanted to set the video to its original width and height or work out if its widescreen so you can set the video settings to show widescreen. (I am new to PHP by the way)

    bc.. $videofile="/home/sim2k/Tezco/Vids/802000129.MTS";
    ob_start();
    passthru("ffmpeg -i \"{$videofile}\" 2>&1");
    $Size = ob_get_contents();
    $full = ob_get_contents();
    ob_end_clean();
    $search='/Video: (.*?), (.*?), (.*?),/';
    $Size=preg_match($search, $Size, $matches, PREG_OFFSET_CAPTURE, 0);
    $Size = $matches[3][0];
    echo $Size."<BR>";

    if (preg_match("/16:9/", $Size, $matches)) {
    echo "This is wide screen <br />";
    echo $matches[0]."<br><br>";
    }

    $search='/(.*?) (.*?) (.*?) (.*?) (.*?)/';
    $Size=preg_match($search, $Size, $matches, PREG_OFFSET_CAPTURE, 0);
    $Size = $matches[1][0];
    echo $Size."<BR>";
    $Size = explode("x", $Size);
    echo $Size[0]." - Width<br>";
    echo $Size[1]." - Height<br><br>";
    echo $full."<br><br>File stream Done";


    Up Down 0 rated
  • <?php
    $videofile="http://localhost/spadesocial/code/ch_videos/2843business_video.flv";

    ob_start();

    passthru("/usr/bin/ffmpeg -i \"{$videofile}\" 2>&1");


    $duration = ob_get_contents();

    print_r($duration);
    ob_end_clean();

    $search='/Duration: (.*?),/';
    print_r($search);
    $duration=preg_match($search, $duration, $matches, PREG_OFFSET_CAPTURE, 3);

    print_r($duration);


    //TEST ECHO
    //echo $matches[1][0];
    ?>
    please confirm me



    Up Down 0 rated
  • <?php
    $videofile="http://localhost/spadesocial/code/ch_videos/2843business_video.flv";

    ob_start();

    passthru("/usr/bin/ffmpeg -i \"{$videofile}\" 2>&1");


    $duration = ob_get_contents();

    print_r($duration);
    ob_end_clean();

    $search='/Duration: (.*?),/';
    print_r($search);
    $duration=preg_match($search, $duration, $matches, PREG_OFFSET_CAPTURE, 3);

    print_r($duration);


    //TEST ECHO
    //echo $matches[1][0];
    ?>
    please confirm me



    Up Down 0 rated
  • Confirm what?

     
    Up Down 0 rated

  • This seems to work fine for me. This script is most useful when you can call it with the filename of a video file and it returns the duration.
    bc.. <?php

    // call with: http://www.mydomain.com/path/duration.php?videofile=filename.ext

    $videofile = isset($_GET["videofile"]) ? strval($_GET["videofile"]) : "default";

    //...external access
    $videofile = "http://localhost/path/" . $videofile;

    //...internal access
    //$videofile = "/path/" . $videofile;

    ob_start();

    passthru("\"/path/ffmpeg\" -i \"{$videofile}\" 2>&1");

    $duration = ob_get_contents();

    ob_end_clean();

    $search = "/Duration: (.*?),/";

    $duration = preg_match($search, $duration, $matches, PREG_OFFSET_CAPTURE, 3);

    //return $matches[1][0];

    echo "Duration of " . $videofile . ": " . $matches[1][0];

    ?>



    Up Down 0 rated
  • If you have full access to bash app you could use the following script:
    $ /usr/bin/ffmpeg -i /path/to/file.flv 2>&1 |grep Duration |awk '{print $2}' |awk -F: '{print ($1 * 3600) + ($2 * 60 ) + $3}'

    This command will return the time in seconds with milli precision.
    If you like, you could replace the math formula and do what you want (eg return the time expressed in hh:mm:ss)

    Cheers

    Up Down 0 rated
  • Why not use ffprobe(1) to obtain this kind of metadata?

    When you compile ffmpeg, ffprobe gets compiled along with it. Here's some sample output from a small test mp4:

    *The container format, displayed in json:*
    [~] ffprobe -show_format -pretty -print_format json -v quiet t1.mp4
    bc.. {
    "format": {
    "filename": "t1.mp4",
    "nb_streams": 2,
    "format_name": "mov,mp4,m4a,3gp,3g2,mj2",
    "format_long_name": "QuickTime/MPEG-4/Motion JPEG 2000 format",
    "start_time": "0:00:00.000000",
    "duration": "0:00:20.350000",
    "size": "3.489486 Mibyte",
    "bit_rate": "1.438423 Mbit/s",
    "tags": {
    "major_brand": "M4VH",
    "minor_version": "1",
    "compatible_brands": "M4VHM4A mp42isom",
    "creation_time": "2010-04-12 18:05:54"
    }
    }
    }



    That gives us the duration and bit rate.

    *The frame rate comes from the stream info:*
    [~] ffprobe -show_streams -pretty -print_format json -v quiet t1.mp4
    bc.. {
    "streams": [
    {
    "index": 0,
    "codec_name": "aac",
    "codec_long_name": "Advanced Audio Coding",
    "codec_type": "audio",
    "codec_time_base": "1/44100",
    "codec_tag_string": "mp4a",
    "codec_tag": "0x6134706d",
    "sample_fmt": "s16",
    "sample_rate": "44.100000 KHz",
    "channels": 2,
    "bits_per_sample": 0,
    "r_frame_rate": "0/0",
    "avg_frame_rate": "11025/256",
    "time_base": "1/44100",
    "start_time": "0:00:00.000000",
    "duration": "0:00:20.363900",
    "bit_rate": "102.236000 Kbit/s",
    "nb_frames": "877",
    "tags": {
    "creation_time": "2010-04-12 18:05:54",
    "language": "eng",
    "handler_name": "Apple Sound Media Handler"
    }
    },
    {
    "index": 1,
    "codec_name": "h264",
    "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
    "codec_type": "video",
    "codec_time_base": "1/1200",
    "codec_tag_string": "avc1",
    "codec_tag": "0x31637661",
    "width": 852,
    "height": 480,
    "has_b_frames": 1,
    "pix_fmt": "yuv420p",
    "level": 31,
    "is_avc": "1",
    "nal_length_size": "4",
    "r_frame_rate": "30000/1001",
    "avg_frame_rate": "91500/3053",
    "time_base": "1/600",
    "start_time": "0:00:00.000000",
    "duration": "0:00:20.353333",
    "bit_rate": "1.329995 Mbit/s",
    "nb_frames": "610",
    "tags": {
    "creation_time": "2010-04-12 18:05:54",
    "language": "eng",
    "handler_name": "Apple Video Media Handler"
    }
    }
    ]
    }


    Note that you also get an "average" bit rate as well as a "real" frame rate (along with all sorts of neat stuff) but that it needs to be computed. In this case the real frame rate (r_frame_rate) comes out to 29.97 fps.

    The "pretty" options formats the numbers in a way that makes sense; the "-v quiet" drops the debug info that you've been using with ffmpeg -i. There are other "print_formats" available.

    T.

    Up Down 0 rated
  • Thank you for sharing this.

     
    Up Down 0 rated
Want to join the discussion? Log In here to add a comment.

Still don't have JW Player? Get It Here