I have a list of .ts files:

out1.ts ... out749.ts   out8159.ts  out8818.ts

How can I get the total duration (running time) of all these files?

  • @Hauke Laging i found this program "mediainfo"
    – k961
    Dec 2, 2014 at 6:09
  • These are media files, likely video.
    – slm
    Dec 2, 2014 at 6:21
  • 1
    Any media files(e.g: MP4, ASF & .264...) will have predefined standard header information, we can get the information from that file like resolution, frame rate, number of frames(GOP) & file length & duration of the media... Dec 2, 2014 at 7:17

10 Answers 10


I have no .ts here but this works for .mp4. Use ffprobe (part of ffmpeg) to get the time in seconds, e.g:

ffprobe -v quiet -of csv=p=0 -show_entries format=duration Inception.mp4 

so for all .mp4 files in the current dir:

find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \;

then use paste to pass the output to bc and get the total time in seconds:

find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc

So, for .ts files you could try:

find . -maxdepth 1 -iname '*.ts' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc

Another tool that works for the video files I have here is exiftool, e.g.:

exiftool -S -n Inception.mp4 | grep ^Duration
Duration: 275.69
exiftool -q -p '$Duration#' Inception.mp4

Total length for all .mp4 files in the current directory:

exiftool -S -n ./*.mp4 | awk '/^Duration/ {print $2}' | paste -sd+ -| bc
exiftool -q -p '$Duration#' ./*.mp4 | awk '{sum += $0}; END{print sum}'

You could also pipe the output to another command to convert the total to DD:HH:MM:SS, see the answers here.

Or use exiftool's internal ConvertDuration for that (you need a relatively recent version though):

exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)
                    }' ./*.mp4| tail -n1
  • Very nice, hadn't seen that trick w/ ffprobe before.
    – slm
    Dec 2, 2014 at 7:24
  • 1
    Nice trick with paste and bc! much cleaner than with awk let's say.
    – fduff
    Dec 2, 2014 at 12:03
  • @fduff. While bc will do arbitrary precision, one drawback is that ...| paste -sd+ - | bc will either reach the line size limit in some bc implementations (for instance seq 429 | paste -sd+ - | bc fails with OpenSolaris bc) or have the potential of using up all the memory in others. Dec 2, 2014 at 12:29
  • Can you do this (ffprobe method) with something like avconv? I can't find ffmpeg in my repos for Kubuntu 14.04 - so I don't have ffprobe either? I do have avprobe, but it doesn't like those arguments.
    – Joe
    Dec 16, 2014 at 7:51
  • @Joe - No avprobe in Arch repos (prolly because it conflicts with ffmpeg) so cannot try it ATM but does it give you the duration of the file if you run it like this: avprobe -show_format_entry duration myfile.mp4 or avprobe -loglevel quiet -show_format_entry duration myfile.mp4? I think one of these commands should give you a single line of output with the duration of the file. Not sure though. Dec 16, 2014 at 17:09

This uses ffmpeg and prints the time out in total seconds:

for f in *.ts; do
    _t=$(ffmpeg -i "$f" 2>&1 | grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' ' | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }')
echo "${times[@]}" | sed 's/ /+/g' | bc


for f in *.ts; do iterates each of the files that ends in ".ts"

ffmpeg -i "$f" 2>&1 redirects output to stderr

grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' ' isolates the time

awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }' Converts time to seconds

times+=("$_t") adds the seconds to an array

echo "${times[@]}" | sed 's/ /+/g' | bc expands each of the arguments and replaces the spaces and pipes it to bc a common linux calculator

  • 1
    Nice! Also see my version which is heavily based on your ideas.
    – MvG
    Dec 2, 2014 at 9:02
  • Short and elegant solution
    – Neo
    Mar 26, 2017 at 2:48
  • How to pipe bc to have hours instead of seconds?
    – Freedo
    Nov 20, 2020 at 9:20

Streamlining @jmunsch's answer, and using the paste I just learned from @slm's answer, you could end up with something like this:

for i in *.ts; do LC_ALL=C ffmpeg -i "$i" 2>&1 | \
awk -F: '/Duration:/{print $2*3600+$3*60+$4}'; done | paste -sd+ | bc

Just like jmunsch did, I'm using ffmpeg to print the duration, ignoring the error about a missing output file and instead searching the error output for the duration line. I invoke ffmpeg with all aspects of the locale forced to the standard C locale, so that I won't have to worry about localized output messages.

Next I'm using a single awk instead of his grep | grep | head | tr | awk. That awk invocation looks for the (hopefully unique) line containing Duration:. Using colon as a separator, that label is field 1, the hours are field 2, the minutes filed 3 and the seconds field 4. The trailing comma after the seconds doesn't seem to bother my awk, but if someone has problems there, he could include a tr -d , in the pipeline between ffmpeg and awk.

Now comes the part from slm: I'm using paste to replace newlines with plus signs, but without affecting the trailing newline (contrary to the tr \\n + I had in a previous version of this answer). That gives the sum expression which can be fed to bc.

Inspired by slm's idea of using date to handle time-like formats, here is a version which does use it to format the resulting seconds as days, hours, minutes and seconds with fractional part:

TZ=UTC+0 date +'%j %T.%N' --date=@$(for i in *.ts; do LC_ALL=C \
ffmpeg -i "$i" 2>&1 | awk -F: '/Duration:/{print $2*3600+$3*60+$4}'; done \
| paste -sd+ | bc) | awk '{print $1-1 "d",$2}' | sed 's/[.0]*$//'

The part inside $(…) is exactly as before. Using the @ character as an indication, we use this as the number of seconds since the 1 January 1970. The resulting “date” gets formatted as day of the year, time and nanoseconds. From that day of the year we subtract one, since an input of zero seconds already leads to day 1 of that year 1970. I don't think there is a way to get day of the year counts starting at zero.

The final sed gets rid of extra trailing zeros. The TZ setting should hopefully force the use of UTC, so that daylight saving time won't interfere with really large video collections. If you have more than one year worth of video, this approach still won't work, though.


I'm not familiar with the .ts extension, but assuming they're some type of video file you can use ffmpeg to identify the duration of a file like so:

$ ffmpeg -i some.mp4 2>&1 | grep Dura
  Duration: 00:23:17.01, start: 0.000000, bitrate: 504 kb/s

We can then split this output up, selecting just the duration time.

$ ffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"

So now we just need a way to iterate through our files and collect these duration values.

$ for i in *.mp4; do
    ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"; done

NOTE: Here for my example I simply copied my sample file some.mp4 and named it 1.mp4, 2.mp4, and 3.mp4.

Converting times to seconds

The following snippet will take the durations from above and convert them to seconds.

$ for i in *.mp4; do 
    dur=$(ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)");
    date -ud "1970/01/01 $dur" +%s; done

This takes our durations and puts them in a variable, $dur, as we loop through the files. The date command is then used to calculate the number of seconds sine the Unix epoch (1970/01/01). Here's the above date command broken out so it's easier to see:

$ date -ud "1970/01/01 00:23:17.01" +%s

NOTE: Using date in this manner will only work if all your files have a duration that's < 24 hours (i.e. 86400 seconds). If you need something that can handle larger durations you can use this as an alternative:

sed 's/^/((/; s/:/)*60+/g' | bc
$ echo 44:29:36.01 | sed 's/^/((/; s/:/)*60+/g' | bc

Totaling up the times

We can then take the output of our for loop and run it into a paste command which will incorporate + signs in between each number, like so:

$ for i in *.mp4; do 
    dur=$(ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)");
    date -ud "1970/01/01 $dur" +%s; done | paste -s -d+

Finally we run this into the command line calculator, bc to sum them up:

$ for i in *.mp4; do 
    dur=$(ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)");
    date -ud "1970/01/01 $dur" +%s; done | paste -s -d+ | bc

Resulting in the total duration of all the files, in seconds. This can of course be converted to some other format if needed.

  • @DamenSalvatore - no problem, hopefully it shows you how you can break the task down into various steps, so you can customize it as needed.
    – slm
    Dec 2, 2014 at 6:26
  • @slm - I would use another way to convert the video duration to seconds as date might choke if ffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)" returns something like 26:33:21.68 (that is, duration ≥ 24 hours/86400 seconds) Dec 2, 2014 at 7:08
  • @don_crissti - thanks, I hadn't tried it beyond 20 hours when testing it out. I'll add a note showing an alternative method.
    – slm
    Dec 2, 2014 at 7:17
  • Thanks for your answer! Not only did it inspire mine, but it also brought paste to my attention. I guess java -classpath $(find -name \*.jar | paste -sd:) is going to be very useful to me, considering the hacks I'd used for this in the past.
    – MvG
    Dec 2, 2014 at 9:02
  • @MvG - paste is my favorite command 8-)
    – slm
    Dec 2, 2014 at 12:16

Well, these all solution need a bit of work, what I did was very simple, 1)

  1. went to the desired folder and right click -> open with other application

  2. Then select VLC media player,

  3. this will start playing one of the videos, but then

  4. press ctrl + L, and you will see the playlist of the videos and somewhere on top left corner you will see total duration

here is example

1. List item

2.enter image description here

3.enter image description here

You can see just under the toolbar, there is Playlist[10:35:51] written, so folder contains 10 hours 35 mins and 51 sec duration of total videos


Going off the accepted answer and using the classic UNIX reverse-polish tool:

{ find . -maxdepth 2 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 \
         -show_entries format=duration {} \; ; printf '+\n60\n*\np'; } | dc


I.e.: Appening + and p then piping that into dc and you'll get your sum.

  • 2
    bc gets way too much love. You're all putting + signs between each line (joining on +), whereas with reverse-polish you can just chuck a + on the end and print it out ;)
    – A T
    Feb 9, 2017 at 13:59
$ find -iname '*.ts' -print0 |\
xargs -0  mplayer -vo dummy -ao dummy -identify 2>/dev/null |\
perl -nle '/ID_LENGTH=([0-9\.]+)/ && ($t += $1) && printf "%02d:%02d:%02d:%02d\n",$t/86400,$t/3600%24,$t/60%60,$t%60'

Be sure that you have MPlayer installed.

  • it doesnt give me any output
    – k961
    Dec 2, 2014 at 6:00
  • do you have mplayer and perl installed? Dec 3, 2014 at 14:15
  • yes i installed mplayer and perl was already installed
    – k961
    Dec 3, 2014 at 15:01
  • 1
    Sorry, I don't know why it's not working; but, you already have enough decent answers already anyways. :) Dec 4, 2014 at 1:33

As ubuntu ship libav instead of ffmpeg :

for f in *.mp4; do
    avprobe -v quiet -show_format_entry duration "$f"
done | paste -sd+ | bc

Heavily based on MvG ideas


I had sub-directories on the current folder so I had to recursively compute the duration:

find . -iname '*.mp4' -print0 | xargs --null exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n1


For music collections I use Banshee [AUR].

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.