Using a webcam on linux and pushing to Wowza

Note: This is still a work in progress

Setup:

  1. Standard USB webcam connected to Ubuntu 12
  2. Latest build of ffmpeg from the repo with libx264
  3. Wowza media server 3.6 hosted on Amazon EC2 (with Cloudfront CDN)

Check available devices with v42l

Get the current video format: v4l2-ctl -V

Format Video Capture:
Width/Height : 640/480
Pixel Format : ‘YUYV’
Field : None
Bytes per Line: 1280
Size Image : 614400
Colorspace : SRGB

v4l2-ctl –list-formats-ext

 

Start encoding

ffmpeg -re -f v4l2 -r 25 -s 640×480 -i /dev/video0 -b:v 300k -c:v libx264 -g 15 -pix_fmt yuv420p -an -f flv rtmp://wowzaserver/live/myStream

Useful script for splitting videos

Source: http://grapsus.net/blog/post/A-script-for-splitting-videos-using-ffmpeg

#!/bin/bash

# Written by Alexis Bezverkhyy <alexis@grapsus.net> in 2011
# This is free and unencumbered software released into the public domain.
# For more information, please refer to <http://unlicense.org/>

function usage {
        echo "Usage : ffsplit.sh input.file chunk-duration [output-filename-format]"
        echo -e "\t - input file may be any kind of file reconginzed by ffmpeg"
        echo -e "\t - chunk duration must be in seconds"
        echo -e "\t - output filename format must be printf-like, for example myvideo-part-%04d.avi"
        echo -e "\t - if no output filename format is given, it will be computed\
 automatically from input filename"
}

IN_FILE="$1"
OUT_FILE_FORMAT="$3"
typeset -i CHUNK_LEN
CHUNK_LEN="$2"

DURATION_HMS=$(ffmpeg -i "$IN_FILE" 2>&1 | grep Duration | cut -f 4 -d ' ')
DURATION_H=$(echo "$DURATION_HMS" | cut -d ':' -f 1)
DURATION_M=$(echo "$DURATION_HMS" | cut -d ':' -f 2)
DURATION_S=$(echo "$DURATION_HMS" | cut -d ':' -f 3 | cut -d '.' -f 1)
let "DURATION = ( DURATION_H * 60 + DURATION_M ) * 60 + DURATION_S"

if [ "$DURATION" = '0' ] ; then
        echo "Invalid input video"
        usage
        exit 1
fi

if [ "$CHUNK_LEN" = "0" ] ; then
        echo "Invalid chunk size"
        usage
        exit 2
fi

if [ -z "$OUT_FILE_FORMAT" ] ; then
        FILE_EXT=$(echo "$IN_FILE" | sed 's/^.*\.\([a-zA-Z0-9]\+\)$/\1/')
        FILE_NAME=$(echo "$IN_FILE" | sed 's/^\(.*\)\.[a-zA-Z0-9]\+$/\1/')
        OUT_FILE_FORMAT="${FILE_NAME}-%03d.${FILE_EXT}"
        echo "Using default output file format : $OUT_FILE_FORMAT"
fi

N='1'
OFFSET='0'
let 'N_FILES = DURATION / CHUNK_LEN + 1'

while [ "$OFFSET" -lt "$DURATION" ] ; do
        OUT_FILE=$(printf "$OUT_FILE_FORMAT" "$N")
        echo "writing $OUT_FILE ($N/$N_FILES)..."
        ffmpeg -i "$IN_FILE" -vcodec copy -acodec copy -ss "$OFFSET" -t "$CHUNK_LEN" "$OUT_FILE"
        let "N = N + 1"
        let "OFFSET = OFFSET + CHUNK_LEN"
done

Creating a timelapse from a sequence of images on GOPRO with ffmpeg

If you have set your Go Pro to capture a sequence of images then here are some easy steps to convert them into a movie with ffmpeg.

My GoPro Her0 3 Black numbers the videos in the following format:

G0010001.JPG

Where the first 1 represents the batch of photos, e.g. if I took 3 timelapses on the same SD card before formatting the sequences would look like:

G0010001.JPG

G0020001.JPG

G0020001.JPG

To use with ffmpeg you need to use the image input filter and unless your image happens to start at 1 (almost never happens to me) you also need to specify the -start_number, especially if you decide to manually delete a few images at the start as I sometimes do.

If the first image was G0010582.JPG you would use the following command:

ffmpeg -f image2 -start_number 002 -i G0010%03d.JPG -vcodec libx264 -b:v 5000k -s 1920×1080 timelapse_1080P.mp4

Note that with this setting I am outputting a 5Mbit video, you can drop this all together if you want to get a lot higher quality or manually up it to 5-8Mbit for decent quality HD video while maintaining a reasonable size.

I also find ffplay is quite good for a quick view on how it looks:

>ffplay timelapse_1080P.mp4