Nvidia GPU use FFmpeg
Nvidia GPU create VOD HLS
origin: http://docs.peer5.com/guides/production-ready-hls-vod/
Nvidia GPU use FFmpeg
Nvidia GPU create VOD HLS
origin: http://docs.peer5.com/guides/production-ready-hls-vod/
#!/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=10 # 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="-map 0:v:${3} -map 0:a:${4} -c:a libfdk_aac -ar 48000 -c:v h264_nvenc -profile:v main -preset:v fast -rc constqp -qp 30 -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="-vsync 0 -hwaccel cuvid -hwaccel_device ${5} -hwaccel_output_format cuda -c:v h264_cuvid -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_npp=w=${width}:h=${height}:force_original_aspect_ratio=decrease:format=yuv420p " | |
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}/" |