Linuxからのストリーミング配信 (動画編)

前にデスクトップを配信する方法は書きましたが、今回は動画を配信する方法です。前とほとんど変わらない方法ですが、今回はrecordmydesktopの代わりにmplayerを使います。違いはそれぐらいです。

必要なもの

vloopbackは本家のsubversionから持ってくると最近のカーネルにも対応していていい感じです。

% svn co http://www.lavrsen.dk/svn/vloopback/trunk/ vloopback

シェルスクリプト

#!/bin/sh

FIFO=/tmp/stream-$USER.yuv
OUTDEV=/dev/video0
INDEV=/dev/video1
SIZE=512x384
VOLUME=7

usage() {
    echo "Usage: $0 video_file"
    exit $1
}

[ "$#" -ne 1 ] && usage 1

lsmod | grep -q vloopback || sudo modprobe vloopback

if [ -f /dev/"$OUTDEV" ]; then
    echo "no such video device: $OUTDEV"
    exit 1
fi

[ -p "$FIFO" ] || mkfifo "$FIFO"

# failsafe
ffmpeg -i "$FIFO" -f yuv4mpegpipe -s "$SIZE" -sameq - | \
mjpegtools_yuv_to_v4l "$INDEV" &
mplayer -nosound -vo yuv4mpeg:file="$FIFO" "$1" >/dev/null 2>&1

ffmpeg -i "$FIFO" -f yuv4mpegpipe -s "$SIZE" -sameq - | \
mjpegtools_yuv_to_v4l "$OUTDEV" &
mplayer -volume "$VOLUME" -vo yuv4mpeg:file="$FIFO" "$1" >/dev/null 2>&1

killall ffmpeg
rm -f "$FIFO"

$OUTDEVと$INDEVはそれぞれvloopbackのinput、outputのデバイスを書きます。(名前の対応が反対になっているのに注意してください)
failsafeのコメントの後に同じような処理がありますが、これはvloopbackの仕様への対策です。これを下側だけにした場合、このスクリプトを終了した後にこのスクリプトが使えなくなります。いろいろ試した結果、スマートではないですが、vloopbackのoutputに対して一回ストリームを流せば回避出来たのでこの様になっています。