why unix | RBL service | netrs | please | ripcalc | linescroll
hosted services

hosted services

This is a skeleton page at the moment.

audio

Convert mp4 audio to wav

$ ffmpeg -i input.mp4 -vn -acodec pcm_s16le -ar 44100 -ac 2 output.wav

Remove audio from video file:

$ ffmpeg -i video.3gp -vcodec copy -an newvideo.3gp

Converting formats

$ ffmpeg -i video.mkv -acodec copy -vcodec copy video.mp4

Turning a mp4 audio file with chapters into individual mp3 files per chapter.

$ ffmpeg -i 'unabridged.mp4' -f ffmetadata 2> /tmp/chapters
$ for i in $( grep 'Chapter #' /tmp/chapters | sed -e 's/.*#//g' -e 's/: .*//g' ); do
    start=$( grep "Chapter #$i:" /tmp/chapters | sed -e 's/.*start //g' -e 's/, end.*//g' )
    end=$( grep "Chapter #$i:" /tmp/chapters | sed -e 's/.*end //g' )
    track=$( echo $i | sed -e 's/.*://g' -e 's/$/ + 1/' | bc )
    ffmpeg -i 'unabridged.mp4' -q:a 0 -map a -ss "$start" -to "$end" -y "$track.mp3"
    id3v2 -1 -a 'artist' -A 'album' -t "$track" -T "$track" "$track.mp3"
done

Rebuilding mp4 from m3u8:

$ ffmpeg -i 'index_728_av-p.m3u8' -bsf:a aac_adtstoasc -vcodec copy -c copy -crf 50 file.mp4

video

$ ffmpeg -i source_file.mkv -acodec copy -vcodec copy dest_file.mp4

shrinking

To shrink the video frame size to 1/3 the original size, but simply copy audio:

$ ffmpeg -i source_file.mp4 -vf "scale=iw/3:ih/3" -c:a copy output.mp4

how i made a birthday movie?

The brief was this:

"Can you merge all these videos and pictures into one with some
music for a birthday message?"

Essentially this is a collage of random sized videos, orientations and pictures.

After trying a few programs I decided to settle with ffmpeg. There were videos of different rotations sizes and the same went for photos. The photos needed music and differing amounts of time on screen.

Since much of the video wasn't going to work on first go, I decided to start as I meant to go on and would compile all this with a Makefile. This works well for several reasons, one of those is that the various elements could be defined through variables at the top in a simple way.

Firstly I needed to specify the resolution, note that a lower proportion is commented:

RESX=1080
#RESX=270
RESY=1920
#RESY=480
RES=$(RESX)x$(RESY)

Firstly, all videos pieces need to be in a fixed sized and orientation, lets make this part of the ffmpeg invocation:

REFORMAT=-vf 'scale=$(RESX):$(RESY):force_original_aspect_ratio=decrease,pad=$(RESX):$(RESY):(ow-iw)/2:(oh-ih)/2,setsar=0'

The above will use the resolution values and set padding so that the videos retain their aspect ratios.

We need to use a common codec, and audio we do this with the following:

CODECS=-s $(RES) -r $(RATE) -acodec aac -vcodec libx264 -ar 48000 -strict experimental

Now we need to make the image collage, we can do that with the following:

ffmpeg -y -f concat -i image_list.txt $(REFORMAT) $(CODECS) slide_show_vid.mp4

If you notice in the above command we use concat and image_list.txt. This tells ffmpeg to use a filter named concat against the list. I've reduced the list greatly, but this example shows two different images and durations in the file:

file plain_picture.jpg
duration 2.5
file complex_text_picture.jpg
duration 10

This then produces a file named slide_show_vid.mp4, without any sound. Lets add some sound by merging slide_show_vid.mp4 and my_sound_file.mp3 with fade out at 45 seconds for five seconds!

ffmpeg -y -i slide_show_vid.mp4 -i my_sound_file.mp3 \
$(REFORMAT) $(CODECS) -af 'afade=out:st=45:d=5' \
-shortest slide_show.mp4

Lets convert the videos to a common video/audio format:

ffmpeg -y -i video_from_some_phone.mp4 $(CODECS) \
video_from_some_phone_encoded1.mp4

We do this for all the videos that were sent, and the compile a list of videos to make the final montage, named video_list.txt:

video_from_some_phone_encoded1.mp4
video_from_some_phone_encoded2.mp4
video_from_some_phone_encoded3.mp4
slide_show.mp4

Lets splice it together:

ffmpeg -y -f concat -i ./video_list.txt $(REFORMAT) $(CODECS) \
output.mp4

There we have it, a nicely built video montage. When someone sends another video or the photo set changes, it is a very trivial task to recreate the montage with minimum hassle.

ok, how do i play a stupid video for conference calls?

Simple. Surprisingly.

while /bin/true; do
    ffmpeg -re -i 20200509_quiriano_Have_a_good_weekend_and_watch_for_fresh_cement_NA_mpw3fwxd9sx41.mp4 -map 0:v -f v4l2 /dev/video0
done

But that's only half of it. First you will need the v4l loopback device. We do that with the following:

sudo apt update
sudo apt install v4l2loopback-dkms v4l2loopback-utils

Then we need to ensure that module is loaded

sudo modprobe v4l2loopback

how to do simple stop motion?

Here's how I did a simple stop-motion video. I used gphoto2 to access a nikon and store the photos in a new directory. I placed this script in the parent directory:

#!/bin/sh
while IFS= read -r THROW; do
    gphoto2 --camera 'Nikon DSC D610' --capture-image-and-download --filename '%Y%m%d-%H%M%S.%3n.%C'
done

Then I called it with ../camera.sh. This stores the photos with a date-time stamp, so that the following script pieces them together in the right order, allowing one second for each image, I called this movie.sh and also placed that in the parent.

#!/bin/sh
RESX=1080
#RESX=270
RESY=1920
#RESY=480
RES="${RESX}x${RESY}"
REFORMAT="-vf scale=${RESX}:${RESY}:force_original_aspect_ratio=decrease,pad=${RESX}:${RESY}:(ow-iw)/2:(oh-ih)/2,setsar=0"
AFRESAMPLE="-af aresample=async=1000"
AFRESAMPLE=
RATE=30
CODECS="-s ${RES} -r ${RATE} -acodec aac -vcodec libx264 -ar 48000 -strict experimental"

/bin/rm output.mp4

for i in `/bin/ls *.jpg`; do
    echo -ne "file ${i}\nduration 1\n"
done | tee image_list.txt

ffmpeg -y -f concat -i image_list.txt ${REFORMAT} ${AFRESAMPLE} ${CODECS} slide_show_vid.mp4

Storing both scripts in the parent directory makes it easy to build up a series of scenes that can be joined together using the concat method above.

how do i do caption text on a movie?

Suppose you take a movie from a video streaming site such as YouTube and you want to put some captions on the movie, perhaps for a meme of some sort. This is a common task, and perhaps one that is worth pursuing as it has quite an interesting solution.

Setup a boiler place script, similar to this:

#!/bin/sh

FILE='input_video.mp4'
OUTPUT="output_video.mp4"
FONT="fontcolor=white:fontsize=40:shadowx=2:shadowy=2"
TEXTPOS="x=(w-text_w)/2:y=h-th-10"

ffmpeg -y -i "$FILE" \
-vf \
-acodec copy "$OUTPUT"

Watch the video clip that you want and make a note of all the timestamps that you want the text to appear in along with the text. Store these in the following format:

drawtext=enable='between(t,1,3)':text='sample text':${TEXTPOS}:${FONT},

Join all the drawtext lines together with , separators, but not , terminator, so don't leave a trailing , on the final drawtext command.

Your final script should look similar to this:

#!/bin/sh

FILE='input_video'
OUTPUT="output_video.mp4"
FONT="fontcolor=white:fontsize=40:shadowx=2:shadowy=2"
TEXTPOS="x=(w-text_w)/2:y=h-th-10"

ffmpeg -y -i "$FILE" \
    -vf \
    "drawtext=enable='between(t,1,3)':text='sample text':${TEXTPOS}:${FONT},
    drawtext=enable='between(t,5,6)':text='ffmpeg is awesome':${TEXTPOS}:${FONT},
    drawtext=enable='between(t,8,10)':text='best thing since sliced bread':${TEXTPOS}:${FONT}
    " \
    -acodec copy "$OUTPUT"

vlc outputVideo.mp4

how do i make caption text move around during the movie?

Things get a little more difficult to organise now. Mostly, how do you group text, time and position information together well?

One way to do this is we can define it something like this

TEXT1='sample1' TEXT2='sample2' TEXT3='sample3'

image stabilisation

ffmpeg -i input.mp4 -vf deshake stable_output.mp4