|  | #!/usr/bin/env bash | 
        
          |  |  | 
        
          |  | set -e | 
        
          |  |  | 
        
          |  | # Usage create-vod-hls.sh SOURCE_FILE [OUTPUT_NAME] | 
        
          |  | [[ ! "${1}" ]] && echo "Usage: create-vod-hls.sh SOURCE_FILE [OUTPUT_NAME]" && exit 1 | 
        
          |  |  | 
        
          |  | # comment/add lines here to control which renditions would be created | 
        
          |  | renditions=( | 
        
          |  | # resolution  bitrate  audio-rate | 
        
          |  | #  "426x240    400k    64k" | 
        
          |  | "640x360    800k     96k" | 
        
          |  | "842x480    1400k    128k" | 
        
          |  | "1280x720   2800k    128k" | 
        
          |  | "1920x1080  5000k    192k" | 
        
          |  | ) | 
        
          |  |  | 
        
          |  | segment_target_duration=4       # try to create a new segment every X seconds | 
        
          |  | max_bitrate_ratio=1.07          # maximum accepted bitrate fluctuations | 
        
          |  | rate_monitor_buffer_ratio=1.5   # maximum buffer size between bitrate conformance checks | 
        
          |  |  | 
        
          |  | ######################################################################### | 
        
          |  |  | 
        
          |  | source="${1}" | 
        
          |  | target="${2}" | 
        
          |  | if [[ ! "${target}" ]]; then | 
        
          |  | target="${source##*/}" # leave only last component of path | 
        
          |  | target="${target%.*}"  # strip extension | 
        
          |  | fi | 
        
          |  | mkdir -p ${target} | 
        
          |  |  | 
        
          |  |  | 
        
          |  | key_frames_interval="$(echo `ffprobe ${source} 2>&1 | grep -oE '[[:digit:]]+(.[[:digit:]]+)? fps' | grep -oE '[[:digit:]]+(.[[:digit:]]+)?'`*2 | bc || echo '')" | 
        
          |  | key_frames_interval=${key_frames_interval:-50} | 
        
          |  | key_frames_interval=$(echo `printf "%.1f\n" $(bc -l <<<"$key_frames_interval/10")`*10 | bc) # round | 
        
          |  | key_frames_interval=${key_frames_interval%.*} # truncate to integer | 
        
          |  |  | 
        
          |  | # static parameters that are similar for all renditions | 
        
          |  | static_params="-c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0" | 
        
          |  | static_params+=" -g ${key_frames_interval} -keyint_min ${key_frames_interval} -hls_time ${segment_target_duration}" | 
        
          |  | static_params+=" -hls_playlist_type vod" | 
        
          |  |  | 
        
          |  | # misc params | 
        
          |  | misc_params="-hide_banner -y" | 
        
          |  |  | 
        
          |  | master_playlist="#EXTM3U | 
        
          |  | #EXT-X-VERSION:3 | 
        
          |  | " | 
        
          |  | cmd="" | 
        
          |  | for rendition in "${renditions[@]}"; do | 
        
          |  | # drop extraneous spaces | 
        
          |  | rendition="${rendition/[[:space:]]+/ }" | 
        
          |  |  | 
        
          |  | # rendition fields | 
        
          |  | resolution="$(echo ${rendition} | cut -d ' ' -f 1)" | 
        
          |  | bitrate="$(echo ${rendition} | cut -d ' ' -f 2)" | 
        
          |  | audiorate="$(echo ${rendition} | cut -d ' ' -f 3)" | 
        
          |  |  | 
        
          |  | # calculated fields | 
        
          |  | width="$(echo ${resolution} | grep -oE '^[[:digit:]]+')" | 
        
          |  | height="$(echo ${resolution} | grep -oE '[[:digit:]]+$')" | 
        
          |  | maxrate="$(echo "`echo ${bitrate} | grep -oE '[[:digit:]]+'`*${max_bitrate_ratio}" | bc)" | 
        
          |  | bufsize="$(echo "`echo ${bitrate} | grep -oE '[[:digit:]]+'`*${rate_monitor_buffer_ratio}" | bc)" | 
        
          |  | bandwidth="$(echo ${bitrate} | grep -oE '[[:digit:]]+')000" | 
        
          |  | name="${height}p" | 
        
          |  |  | 
        
          |  | cmd+=" ${static_params} -vf scale=w=${width}:h=${height}:force_original_aspect_ratio=decrease" | 
        
          |  | cmd+=" -b:v ${bitrate} -maxrate ${maxrate%.*}k -bufsize ${bufsize%.*}k -b:a ${audiorate}" | 
        
          |  | cmd+=" -hls_segment_filename ${target}/${name}_%03d.ts ${target}/${name}.m3u8" | 
        
          |  |  | 
        
          |  | # add rendition entry in the master playlist | 
        
          |  | master_playlist+="#EXT-X-STREAM-INF:BANDWIDTH=${bandwidth},RESOLUTION=${resolution}\n${name}.m3u8\n" | 
        
          |  | done | 
        
          |  |  | 
        
          |  | # start conversion | 
        
          |  | echo -e "Executing command:\nffmpeg ${misc_params} -i ${source} ${cmd}" | 
        
          |  | ffmpeg ${misc_params} -i ${source} ${cmd} | 
        
          |  |  | 
        
          |  | # create master playlist file | 
        
          |  | echo -e "${master_playlist}" > ${target}/playlist.m3u8 | 
        
          |  |  | 
        
          |  | echo "Done - encoded HLS is at ${target}/" |