Command line cinema

See also: http://ustensile.be/Command-line_cinema

Last time we ended with the following script:

espeak "and now for something completely different" -v en -p 99 -s 50 -w hello.wav
sox hello.wav padded.wav pad 3 3
sox padded.wav -b 8 -e unsigned-integer -c 1 -r 4000 -t raw rawfile
rm frame*.jpg
python speak.py
ffmpeg -r 10 -i frame%09d.jpg -i padded.wav -y output.mp4

Project Gutenberg ~ http://www.gutenberg.org/

Librivox ~ https://librivox.org/search?primary_key=2&search_category=language&search_page=1&search_form=get_results

Let's download some audio from Librivox with wget:

wget http://ia902604.us.archive.org/10/items/apologie_de_socrate_l_librivox/apologie_socrate_01_platon.mp3

And adjust the recipe to work with this audio, using ffmpeg to convert to wav (since the default sox install doesn't like mp3)...

ffmpeg -i apologie_socrate_01_platon.mp3 -y apologie_socrate_01_platon.wav
sox apologie_socrate_01_platon.wav padded.wav pad 0 1
sox padded.wav -b 8 -e unsigned-integer -c 1 -r 4000 -t raw rawfile
rm frame*.jpg
python speak.py
ffmpeg -r 10 -i frame%09d.jpg -i padded.wav -y output.mp4

Youtube-dl

YOu might also want to rip a movie from youtube.

Check if you have youtube-dl already installed by simply trying to run it from the shell:

youtube-dl

If you need to install it that'd be either:

(Linux)

sudo apt install youtube-dl or (OSX)

brew install youtube-dl

Using youtube-dl URL

Mplayer

Basic key commands when playing a movie with mplayer

SPACE: Pause/Play
. : Forward one frame
Left + Right : Jump
9 0 : Volume
[ ] : Speed
o   : Toggle display mode (shows current time and duration)
f   : Toggle fullscreen
s   : Save current frame (with -vf screenshot, see Mplayer Snapshots)
q   : Quit

Time options

# Play from 10 seconds to 1 minute 6 seconds.
mplayer -ss 10 -endpos 56

# Play from 01:10:30 - 01:11:00
mplayer -ss 01:10:30 -endpos 30

Extracting Frames from a Movie: Mplayer Snapshots

mplayer -vf screenshot <source>

Then while the movie is playing ... press the s key each time you want to save a frame. You should find files named like:

shot0001.png
shot0002.png
shot0003.png
shot0004.png

Extracting Frames from a Movie: ffmpeg

ffmpeg -i <source> <destination%06d.jpg>

Selecting a section of a video with ffmpeg

Extract 3 seconds starting at (near) 05:47 and save as snip.mp4

ffmpeg -ss 05:47 -t 03:00 -i ten.mp4 snip.mp4

Extract to images ffmpeg -ss 12:00 -vframes 100 -i

Timing (start + stop) can be controlled with -ss (skip start) and -t (total time of result)

When -ss is before the -i ffmpeg attempts to JUMP which is fast only precise to the nearest key frame.

When you put -ss after the -i, the timing is more precise but it's slower as the movie is actually played (quickly) up to that precise point.

# Extract 3 seconds starting at (exactly) 05:47 and save as snip.mp4 
ffmpeg -i ten.mp4 -ss 05:47 -t 3 snip.mp4


ffmpeg -ss 05:47 -i powersof10/ten.mp4 -vframes 10 snip%04d.jpg


# Starting at 05:47 output one frame every 5 seconds for 10 frames, save using names starting snip0001.jpg
ffmpeg -ss 05:47 -i powersof10/ten.mp4 -r 1/5 -vframes 10 snip%04d.jpg


# Combine Image Sequence starting frames000001.jpg and the audio in soundtrack.wav
# Save result as "result.mp4"
ffmpeg -i frames%06d.jpg -i soundtrack.wav result.mp4

Example:

ffmpeg -ri 10 -i frame%06d.jpg -i apologie.wav apologie.mp4

To force ffmpeg to OVERWRITE any previously existing file (useful when inside a larger script that you want to run again and again) -- add the -y to "AUTO-YES" the question about replacing the output.

ffmpeg -r 10 -i frame%06d.jpg -i apologie.wav -y apologie.mp4

Padding audio

Add 10 seconds to start and 30 seconds to end of input, save as output:

sox input.wav output.wav pad 10 30

Mixing audio

with ffmpeg

ffmpeg -i apologie.wav -i badmusic.wav -filter_complex amerge mix.mp3

it uses the duration of the shortest file.

you can also explicitly limit the number of audio channels with:

ffmpeg -i apologie.wav -i badmusic.wav -filter_complex amerge -ac 1 mix.mp3

Sequence (concatenate) audio / video

For audio, you can use sox like this:

sox a.wav b.wav c.wav output.wav

For video, you can use mlt / melt .....

melt a.mp4 b.mp4 c.mp4 -consumer avformat:output.mp4 b=1000k

You can also use melt to combine still images as "inter-titles", the numbers with "out" are frames (so for output at 25 fps, 50 = 2 seconds):

melt title2-0.png out=50 \
video.mp4 \
title2-1.png out=100 \
-consumer avformat:output.mp4 b=1000k

To do this with ffmpeg you need to make a sort of playlist file that looks like:

playlist.txt

file 'a.wav'
file 'b.wav'
file 'c.wav'
ffmpeg -f concat -i concat.txt concat.mp3

See: https://trac.ffmpeg.org/wiki/Concatenate

Text / Titles

Imagemagick! http://www.imagemagick.org/Usage/text/

convert -size 640x480 -gravity center -pointsize 72 -font CoupeurBoldBlock.otf -background lightblue -fill blue caption:'HEY what about a very long text then?' title.png

with a newline:

convert -size 640x480 -gravity center -pointsize 72 -font CoupeurBoldBlock.otf -background lightblue -fill blue caption:'HEY!\n what about a very long text then?' title.png

What colors?

convert -list color

Random color!

convert -list color | cut -d" " -f1 | shuf | head -n1

There's also label:, but it doesn't do word wrap.

convert -size 640x480 -gravity center -pointsize 72 -font ~/.fonts/coupeur-boldblock/CoupeurBoldBlock.otf -background lightblue -fill blue caption:'HEY what about a very long text then?' title.png
convert -size 640x480 -gravity center -pointsize 72 -font -background lightblue -fill blue label:'magic\nmagic!!!' whoami.png

title with random colors:

convert -size 640x480 -gravity center -pointsize 72 \
    -font ~/.fonts/coupeur-boldblock/CoupeurBoldBlock.otf \
    -background $(convert -list color | cut -d" " -f1 | shuf | head -n1) \
    -fill $(convert -list color | cut -d" " -f1 | shuf | head -n1) \
    label:'Surprise!!!' surprise.png

TITLE

c1=shuf imcolornames.txt | head -n 1 c2=shuf imcolornames.txt | head -n 1 convert -size 640x480 -background $c1 -fill $c2 -pointsize 72 -gravity center -f ont /home/murtaugh/.fonts/OSP_Libertinage/Libertinage-s.ttf label:Contemporaneit y contemporaneity.png

NB: Using the @ sign with label to read from a file seems to be blocked (by some kind of security "policy").... back quoting a file might work though?!