Skip to content

Instantly share code, notes, and snippets.

@tslamic
Created August 10, 2023 11:20
Show Gist options
  • Save tslamic/786b0124fb47b9d10a636f20a2b2d012 to your computer and use it in GitHub Desktop.
Save tslamic/786b0124fb47b9d10a636f20a2b2d012 to your computer and use it in GitHub Desktop.
Encodes and segments an MP4 video for adaptive streaming over various network conditions.
#!/bin/bash
# Encodes and segments an MP4 video for adaptive streaming over various network conditions.
# It supports resolutions ranging from 360p to 1080p and creates both HLS and MPEG-DASH playlists.
# Assumes ffmpeg is installed and in the path. Usage: ./encode.sh <video_file>
set -euo pipefail
if [ -z "$1" ]; then
echo "Usage: $0 <video_file>"
exit 1
fi
input="$1"
if [ ! -f "$input" ]; then
echo "Error: File '$input' not found!"
exit 1
fi
input_type=$(file --brief --mime-type "$input")
if [ "$input_type" != "video/mp4" ]; then
echo "Error: File '$input' is not a valid MP4 video!"
exit 1
fi
output_dir="${input%.*}_streaming_output"
if [ -d "$output_dir" ]; then
echo "Error: Output directory '$output_dir' already exists!"
exit 1
fi
mkdir -p "$output_dir"
# Encoding profiles for various network conditions.
resolutions=("640x360" "854x480" "1280x720" "1920x1080")
bitrates=("400k" "800k" "1500k" "3000k")
profiles=("360p" "480p" "720p" "1080p")
# Encode and segment the video for each profile.
for i in "${!resolutions[@]}"; do
resolution=${resolutions[$i]}
bitrate=${bitrates[$i]}
profile=${profiles[$i]}
ffmpeg -i "$input" -vf "scale=$resolution" -c:v libx264 -profile:v main -level 3.1 -b:v "$bitrate" -c:a aac -b:a 128k -g 48 -keyint_min 48 -sc_threshold 0 -hls_time 4 -hls_playlist_type vod -hls_segment_filename "$output_dir/${profile}_%03d.ts" "$output_dir/${profile}.m3u8"
ffmpeg -i "$input" -vf "scale=$resolution" -c:v libx264 -profile:v main -level 3.1 -b:v "$bitrate" -c:a aac -b:a 128k -g 48 -keyint_min 48 -sc_threshold 0 -dash 1 -f dash "$output_dir/${profile}.mpd"
done
# Create master HLS playlist.
echo "#EXTM3U" > "$output_dir/master.m3u8"
for i in "${!profiles[@]}"; do
profile=${profiles[$i]}
bitrate=$((${bitrates[$i]%k} * 1000 + 128000)) # Remove the "k" suffix, multiply by 1000, and add 128000
echo "#EXT-X-STREAM-INF:BANDWIDTH=$bitrate,RESOLUTION=$profile" >> "$output_dir/master.m3u8"
echo "${profile}.m3u8" >> "$output_dir/master.m3u8"
done
echo "Done"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment