Skip to content

Instantly share code, notes, and snippets.

@paulreece42
Created March 21, 2023 22:54
Show Gist options
  • Save paulreece42/c8b3db76f9bd5c36a9e4e96ea480890a to your computer and use it in GitHub Desktop.
Save paulreece42/c8b3db76f9bd5c36a9e4e96ea480890a to your computer and use it in GitHub Desktop.
ffmpeg transcode to HLS resolution
#!/bin/bash
# usage: ./encode_hls.sh video.mp4 480
#
# Transcode to HLS @ XXXXp
#
# Simple little script I made, requires jq and ffmpeg
# I just use the ffmpeg from https://johnvansickle.com/ffmpeg/
#
export INPUTFILE=$1
export RES=$2
export VIDPATH=`echo ${INPUTFILE}|awk -F "." '{print $1}'`
mkdir -p ${VIDPATH}/${RES}
ffmpeg -i $INPUTFILE \
-vf scale=-2:${2},setsar=1:1 \
-c:v libx264 -crf 23 -tune film \
-c:a aac -b:a 128k -ac 2 -threads 0 -stats \
-f hls -hls_time 4 -hls_playlist_type vod \
${VIDPATH}/${RES}/stream.m3u8
get_vidinfo() {
BITRATE=`ffprobe -print_format json -show_format -show_streams ${1} 2>/dev/null | jq '.format.bit_rate' | tr -d '\"'`
WIDTH=`ffprobe -print_format json -show_format -show_streams ${1} 2>/dev/null | jq .streams[0].width`
HEIGHT=`ffprobe -print_format json -show_format -show_streams ${1} 2>/dev/null | jq .streams[0].height`
}
#Rebuild main m3u8 if needed
#
# if main m3u8 doesn't exist, rebuild for all subfolders
if [ ! -f $VIDPATH/stream.m3u8 ] ; then
echo '#EXTM3U' > $VIDPATH/stream.m3u8
for format in `find $VIDPATH -maxdepth 1 -mindepth 1 -type d`; do
echo $format
if [ -f ${format}/stream.m3u8 ] && [ -f ${format}/stream0.ts ] ; then
get_vidinfo ${format}/stream0.ts
cat <<EOF >> $VIDPATH/stream.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=${BITRATE},RESOLUTION=${WIDTH}x${HEIGHT}
${HEIGHT}/stream.m3u8
EOF
fi
done
else
if [ -f ${VIDPATH}/${RES}/stream.m3u8 ] && [ -f ${VIDPATH}/${RES}/stream0.ts ] ; then
get_vidinfo ${VIDPATH}/${RES}/stream0.ts
cat <<EOF >> $VIDPATH/stream.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=${BITRATE},RESOLUTION=${WIDTH}x${HEIGHT}
${RES}/stream.m3u8
EOF
fi
fi
#!/bin/bash
#
# usage encode_multi_hls.sh $file
#
# encode to various current and smaller
# versions of HLS
#
HEIGHT=`ffprobe -print_format json -show_format -show_streams ${1} 2>/dev/null | jq .streams[0].height`
for res in 2160 1080 720 480 240 ; do
if [ $res -le $HEIGHT ] ; then
/usr/local/sbin/encode_hls.sh $1 $res
else
echo "Skipping $res as video is $HEIGHT"
fi
done
@paulreece42
Copy link
Author

Something like this would be a lot better (and cleaner) for most cases: https://blog.zazu.berlin/internet-programmierung/mpeg-dash-and-hls-adaptive-bitrate-streaming-with-ffmpeg.html

@paulreece42
Copy link
Author

For burning in subtitles, burn in the source file first, then HLS

Example:

ffmpeg -i mamma-mia.mkv -filter_complex "[0:v][0:s]overlay[v]" -map "[v]" -map 0:a mamma-mia-burnedsubz.mkv
hls_multi_encode.sh mamma-mia-burnedsubz.mkv

https://trac.ffmpeg.org/wiki/HowToBurnSubtitlesIntoVideo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment