DASH - Adaptive H.264 Videos erstellen
Skript zur Generierung von DASH-Videos, die je nach zur Verfügung stehenden Bandbreite das qualitativ beste Video dem Client bereitstellen.
brew install MP4box
brew install ffmpeg
 
#!/usr/bin/env bash
set -e
SAVEDIR="$(pwd)/"
mkdir -p "${SAVEDIR}"
renderAudio() {
    filename="$1"
    bitrate="$2"
    if [ ! -f "${filename}_audio_${bitrate}.m4a" ]; then
	ffmpeg -y -i "${inputfile}" -c:a aac -ac 2 -ab "${bitrate}k" -vn "${filename}_audio_${bitrate}.m4a"
    fi
}
renderVideo() {
    filename="$1"
    bitrate="$2"
    height="$3"
    if [ ! -f "${filename}_${height}_${bitrate}.mp4" ]; then
#	ffmpeg -y -i "${inputfile}" -an -c:v libx264 -x264opts 'keyint=25:min-keyint=25:no-scenecut' \
#            -movflags frag_keyframe+empty_moov -g 25 -b:v ${bitrate}k -vf "scale=-2:${height}" -f mp4 -pass 1 -y /dev/null
	ffmpeg -y -i "${inputfile}" -an -c:v libx264 -x264opts 'keyint=25:min-keyint=25:no-scenecut' \
	    -movflags frag_keyframe+empty_moov -g 25 -b:v ${bitrate}k -vf "scale=-2:${height}" -f mp4 "${filename}_${height}_${bitrate}.mp4"
    fi
}
for inputfile in $@
do
    fname=$(basename "${inputfile}") # fullname of the file
    fname="${fname%.*}" # name without extension
    echo "Converting \"${inputfile}\" to multi-bitrate video in MPEG-DASH"
    renderAudio "${SAVEDIR}/${fname}" 96
    renderAudio "${SAVEDIR}/${fname}" 48
    renderVideo "${SAVEDIR}/${fname}" 1500 540
    renderVideo "${SAVEDIR}/${fname}" 0500 540
    renderVideo "${SAVEDIR}/${fname}" 0300 270
    renderVideo "${SAVEDIR}/${fname}" 0200 180
    ffmpeg -i "${SAVEDIR}/${fname}_540_0500.mp4" -i "${SAVEDIR}/${fname}_audio_96.m4a" \
           -acodec copy -vcodec copy \
           "${fname}_stream.mp4"
    MP4Box -inter 500 "${fname}_stream.mp4"
    MP4Box -dash 2000 -min-buffer 3000 -frag 2000 -rap -out "${fname}_mp4.mpd" \
	"${SAVEDIR}/${fname}_540_1500.mp4" \
	"${SAVEDIR}/${fname}_540_0500.mp4" \
	"${SAVEDIR}/${fname}_270_0300.mp4" \
	"${SAVEDIR}/${fname}_180_0200.mp4" \
	"${SAVEDIR}/${fname}_audio_96.m4a" \
	"${SAVEDIR}/${fname}_audio_48.m4a"
#	"${SAVEDIR}/${fname}_360_0400.mp4"
#	"${SAVEDIR}/${fname}_audio_32.m4a"
#    rm 	"${SAVEDIR}/${fname}_540_1500.mp4" "${SAVEDIR}/${fname}_540_0500.mp4" \
#	"${SAVEDIR}/${fname}_360_0400.mp4" "${SAVEDIR}/${fname}_270_0300.mp4" \
#	"${SAVEDIR}/${fname}_180_0200.mp4" \
#	"${SAVEDIR}/${fname}_audio_96.m4a" "${SAVEDIR}/${fname}_audio_48.m4a" "${SAVEDIR}/${fname}_audio_32.m4a"
done
Konvertieren via:
mp4-to-dash sample.mp4
Abspielen dann via dash-if player (Auszug aus dem _video.html.erb-Renderer
einer Camaleon Instanz):
...
<script src="http://cdn.dashjs.org/latest/dash.all.min.js"></script>
...
    <video data-dashjs-player id="video-<%= post.the_id %>"
           poster="<%= post.the_thumb_url %>"
           width="960" height="540"
           controls="controls"
           preload="auto"
           data-src="/streams/<%= post.the_field('video-file') %>/<%= post.the_field('video-file') %>_mp4.mpd">
      <source src="/streams/<%= post.the_field('video-file') %>/<%= post.the_field('video-file') %>_stream.mp4">
    </video>
...              
Da alle 2 Sekunden ein neues Fragment geladen wird, sollten im access-log vom nginx diese Requests ausgeblendet werden:
    location /streams/ {
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS, HEAD';
            add_header 'Access-Control-Allow-Headers' 'range, content-type';
            return 204;
        }
        access_log none;
        add_header 'Access-Control-Allow-Origin' '*';
    }
Die Konfiguration der Access-Control-Allow-Flags kann entfallen, falls die Videos nicht von einer anderen URL
heraus aufgerufen werden.