0

How get sum, for ezample 00:03:03.333, of 00:01:01.111 and 00:02:02.222 into variable

EPOCH='jan 1 1970'
offset=$EPOCH

lsdvd -c VIDEO_TS | grep "Length:" | grep "Chapter:" | awk '{print($4)}' | while read -r len
do
  len=${len:0:12}
  offset="$(date -u -d "$EPOCH $len" +%T.%3N) + $(date -u -d "$offset" +%T.%3N)"
  echo "need sum" $offset "then" ffmpeg -ss $offset ... -t $len ...
done
2

sh can only do integer arithmetic so you have to use something else, like bc (or a language that can do non-integer arithmetic such as awk or perl).

To use bc, you first have to convert the %H:%M:%S.%3N format to seconds (including the decimal fraction) and then pipe that into bc.

For example:

#!/bin/bash

epoch='1970-01-01'

len1='00:01:01.111'
len2='00:02:02.222'

# convert to seconds
len1_s=$(date -u -d "$epoch $len1" '+%s.%3N')
len2_s=$(date -u -d "$epoch $len2" '+%s.%3N')

# add the seconds
sum_s=$( echo "$len1_s + $len2_s" | bc )

echo $len1_s + $len2_s = $sum_s

# convert back to H:M:S.N
sum=$(date -u -d "@$sum_s" '+%T.%3N')

echo $len1 + $len2 = $sum

Output:

$ ./sum.sh 
61.111 + 122.222 = 183.333
00:01:01.111 + 00:02:02.222 = 00:03:03.333

I'll leave implementing that in your while loop to you....but I will note that lsdvd has some useful output options that will give you the chapter lengths in seconds (so you don't need to convert them). Probably the most useful is the XML output option which can then be processed with xmlstarlet or xml2 to extract the chapter lengths.

e.g. here's lsdvd's XML output converted to a line-oriented format (suitable for processing with awk or whatever) using xml2:

It's an approx 48 minute video with 11 chapters, most of which are roughly 5 mins (300 seconds) long.

$ lsdvd -c -Ox '/path/to/some/dvd.iso'  | xml2
/lsdvd/device=/path/to/some/dvd.iso
/lsdvd/title=TITLE
/lsdvd/vmg_id=DVDVIDEO-VMG
/lsdvd/provider_id=PROVIDER
/lsdvd/track/ix=1
/lsdvd/track/length=2874.667
/lsdvd/track/vts_id=DVDVIDEO-VTS
/lsdvd/track/chapter/ix=1
/lsdvd/track/chapter/length=299.934
/lsdvd/track/chapter/startcell=1
/lsdvd/track/chapter
/lsdvd/track/chapter/ix=2
/lsdvd/track/chapter/length=299.500
/lsdvd/track/chapter/startcell=2
/lsdvd/track/chapter
/lsdvd/track/chapter/ix=3
/lsdvd/track/chapter/length=300.000
/lsdvd/track/chapter/startcell=3
[...]
/lsdvd/track/chapter/ix=11
/lsdvd/track/chapter/length=176.734
/lsdvd/track/chapter/startcell=11
/lsdvd/longest_track=1

This is a LOT easier to process in a script than the default human-readable output of lsdvd. e.g. if I wanted just the chapter lengths in seconds:

$ lsdvd -c -Ox /path/to/some/dvd.iso' | xml2 | \
     awk -F'[/=]' '$5 == "length" { print $6 }'
299.934
299.500
300.000
299.500
300.000
299.500
299.500
300.000
299.500
0.500
176.734

I'll also point out that if you're using awk, you don't need grep. So, if you want to use the human-readable output, your grep | grep | awk (as well as the len=${len:0:12} to strip the trailing comma) can be reduced to:

lsdvd -c VIDEO_TS | awk -F' +|,' '/Chapter:/ && /Length:/ { print $5 }' | \
  while read len

The field separator is defined here as either one-or-more spaces OR a comma.

$ lsdvd -c '/path/to/some/dvd.iso' | \
    awk -F' +|,' '/Chapter:/ && /Length:/ { print $5 }'
00:04:59.934
00:04:59.500
00:05:00.000
00:04:59.500
00:05:00.000
00:04:59.500
00:04:59.500
00:05:00.000
00:04:59.500
00:00:00.500
00:02:56.734

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.