7

I wrote a skript to quickly create short preview clips from vides I recorded on timestamps that I found worth checking out later for cutting. My file with the timestamps is written like this

FILE_NAME1#MM:SS MM:SS
FILE_NAME2#MM:SS MM:SS MM:SS MM:SS

example:

MAH01728#02:47 03:34 03:44 05:00 06:08 06:55

The script looks like this:

#!/bin/bash
while read f
 do

 file=$(echo $f | cut -d"#" -f1)
 filename=${file}".MP4"
 timestamps=$(echo $f | cut -d"#" -f2)

for time in $timestamps 
 do 
  ffmpeg -ss 00:${time}.0 -i "orig/${filename}" -c copy -t 10 "preview/${file}_${time}.MP4"
 done
done < $1

The script gets half of the previews that I want and on the other the filename is messed up and ffmpeg complains that the file is not found:

orig/714.MP4: No such file or directory
orig/00:58 01:25.MP4: No such file or directory

So I modified the script for trouble shooting and just put an echo in front of the ffmpeg command - now all file names are correct. What am I missing?

ffmpeg -ss 00:01:47.0 -i orig/MAH01714.MP4 -c copy -t 10 preview/MAH01714_01:47.MP4
ffmpeg -ss 00:02:00.0 -i orig/MAH01713.MP4 -c copy -t 10 preview/MAH01713_02:00.MP4
ffmpeg -ss 00:00:58.0 -i orig/MAH01712.MP4 -c copy -t 10 preview/MAH01712_00:58.MP4
ffmpeg -ss 00:01:25.0 -i orig/MAH01712.MP4 -c copy -t 10 preview/MAH01712_01:25.MP4
Eike
  • 451
  • 1
  • 4
  • 17

1 Answers1

13

ffmpeg reads from standard input, consuming data from $1 that was intended for the read command at the top of the loop. Redirect its standard input from /dev/null:

while IFS="#" read file timestamps; do
  filename="$file.MP4"
  for time in $timestamps; do
    ffmpeg -ss 00:${time}.0 -i "orig/${filename}" \
           -c copy -t 10 "preview/${file}_${time}.MP4" < /dev/null
  done
done < "$1"

echo does not read from standard input, which is why your modification made it appear to be working correctly.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • 5
    Alternatively, use the `-nostdin` option in `ffmpeg`. – llogan Sep 17 '18 at 19:26
  • 1
    That is great. I did not know you could specify the IFS in the while loop and also asign multiple variables. Much leaner. This worked for me. – Eike Sep 17 '18 at 19:44
  • @LordNeckbeard Thank you tried this as well and with this line it works: ffmpeg -nostdin -ss 00:${time}.0 -i "orig/${filename}" \ -c copy -t 10 "preview2/${file}_${time}.MP4" – Eike Sep 17 '18 at 19:48
  • 3
    ffmpeg is the most bizarre, most idiosyncratic piece of software I've ever seen. Reading from stdin is the sneakiest way to make scripts fail and very hard to troubleshoot when they do so. But I would not expect the ffmpeg devs to understand why it's incredibly wrong to do this. Thanks for the solution BTW. – Florin Andrei Aug 15 '19 at 01:09
  • It would be good to explain why does it read from stdin, and where is the WONTFIXED bug report for this :-) – Ciro Santilli OurBigBook.com Aug 19 '19 at 08:09