#!/usr/bin/env bash # set -euo pipefail IFS=$'\n\t' DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" function main { local cmd cmd=$1 shift if [ "$cmd" = "copy" ]; then copy "${@}" elif [ "$cmd" = "stream_software_h264" ]; then stream_software_h264 "${@}" elif [ "$cmd" = "stream_hardware_h264" ]; then stream_hardware_h264 "${@}" elif [ "$cmd" = "preprocess_software_h264" ]; then preprocess_software_h264 "${@}" elif [ "$cmd" = "preprocess_hardware_h264" ]; then preprocess_hardware_h264 "${@}" elif [ "$cmd" = "vp9" ]; then vp9 "${@}" elif [ "$cmd" = "preprocess_hardware_vp9" ]; then preprocess_hardware_vp9 "${@}" elif [ "$cmd" = "vp8" ]; then vp8 "${@}" elif [ "$cmd" = "software_vp8" ]; then software_vp8 "${@}" elif [ "$cmd" = "preprocess_h264" ]; then preprocess_h264 "${@}" elif [ "$cmd" = "preprocess_vp8" ]; then preprocess_vp8 "${@}" elif [ "$cmd" = "webcam" ]; then webcam "${@}" elif [ "$cmd" = "encode_webcam" ]; then encode_webcam "${@}" else (>&2 echo "Unknown command: $cmd") exit 1 fi } function copy { local file_to_cast file_to_cast="$3" local USERNAME PASSWORD USERNAME="$1" PASSWORD="$2" set -x </dev/null exec ffmpeg \ -re \ -stream_loop -1 \ -i "$file_to_cast" \ -c copy \ -strict experimental \ -f rtsp \ -rtsp_transport tcp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } function stream_software_h264 { local file_to_cast file_to_cast="$3" local USERNAME PASSWORD USERNAME="$1" PASSWORD="$2" set -x # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. </dev/null exec ffmpeg \ -re \ -stream_loop -1 \ -i "$file_to_cast" \ -c:v h264 \ -b:v 2M \ -profile:v high \ -bf 0 \ -strict -2 \ -c:a opus \ -ac 2 \ -b:a 320k \ -ar 48000 \ -f rtsp \ -rtsp_transport tcp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } function stream_hardware_h264 { local file_to_cast file_to_cast="$3" local USERNAME PASSWORD USERNAME="$1" PASSWORD="$2" set -x # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. </dev/null exec ffmpeg \ -re \ -stream_loop -1 \ -vaapi_device /dev/dri/renderD128 \ -i "$file_to_cast" \ -vf 'format=nv12|vaapi,hwupload' \ -c:v h264_vaapi \ -b:v 2M \ -profile:v high \ -bf 0 \ -strict -2 \ -c:a opus \ -ac 2 \ -b:a 320k \ -ar 48000 \ -f rtsp \ -rtsp_transport tcp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } function preprocess_software_h264 { local file_to_cast file_to_save file_to_cast="$1" file_to_save="$2" set -x # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. </dev/null exec ffmpeg \ -i "$file_to_cast" \ -c:v h264 \ -b:v 2M \ -profile:v high \ -bf 0 \ -strict -2 \ -c:a opus \ -ac 2 \ -b:a 320k \ -ar 48000 \ "$file_to_save" } function preprocess_hardware_h264 { local file_to_cast file_to_save file_to_cast="$1" file_to_save="$2" set -x # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. </dev/null exec ffmpeg \ -vaapi_device /dev/dri/renderD128 \ -i "$file_to_cast" \ -vf 'format=nv12,hwupload' \ -c:v h264_vaapi \ -b:v 2M \ -profile:v high \ -bf 0 \ -strict -2 \ -c:a opus \ -ac 2 \ -b:a 320k \ -ar 48000 \ "$file_to_save" } function vp9 { local file_to_cast file_to_cast="$3" local USERNAME PASSWORD USERNAME="$1" PASSWORD="$2" set -x # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. </dev/null exec ffmpeg \ -re \ -stream_loop -1 \ -init_hw_device vaapi=foo:/dev/dri/renderD128 \ -hwaccel vaapi \ -hwaccel_output_format vaapi \ -hwaccel_device foo \ -i "$file_to_cast" \ -filter_hw_device foo \ -vf 'format=nv12|vaapi,hwupload' \ -c:v vp9_vaapi \ -bf 0 \ -strict -2 \ -c:a opus \ -b:a 320k \ -ar 48000 \ -f rtsp \ -rtsp_transport tcp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } function preprocess_hardware_vp9 { local file_to_cast file_to_save file_to_cast="$1" file_to_save="$2" set -x # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. </dev/null exec ffmpeg \ -init_hw_device vaapi=foo:/dev/dri/renderD128 \ -hwaccel vaapi \ -hwaccel_output_format vaapi \ -hwaccel_device foo \ -i "$file_to_cast" \ -filter_hw_device foo \ -vf 'format=nv12|vaapi,hwupload' \ -c:v vp9_vaapi \ -bf 0 \ -strict -2 \ -c:a opus \ -b:a 320k \ -ar 48000 \ "$file_to_save" } function software_vp8 { local USERNAME PASSWORD USERNAME="$1" PASSWORD="$2" local file_to_cast file_to_cast="$3" set -x # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. # -strict -2 :: Enable support for experimental codecs like opus. # -b:v 2M :: Target 2 megabit/s # -crf 10 :: Target a quality level and adjust bitrate accordingly. This should be preferred, but ideally both should be used. </dev/null exec ffmpeg \ -re \ -stream_loop -1 \ -i "$file_to_cast" \ -c:v vp8 \ -b:v 2M \ -crf 10 \ -bf 0 \ -c:a opus \ -b:a 320k \ -ar 48000 \ -strict -2 \ -f rtsp \ -rtsp_transport tcp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } function preprocess_vp8 { local file_to_cast file_to_save file_to_cast="$1" file_to_save="$2" set -x # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. # -strict -2 :: Enable support for experimental codecs like opus. # -b:v 2M :: Target 2 megabit/s # -crf 10 :: Target a quality level and adjust bitrate accordingly. This should be preferred, but ideally both should be used. </dev/null exec ffmpeg \ -i "$file_to_cast" \ -c:v vp8 \ -b:v 2M \ -crf 10 \ -bf 0 \ -c:a opus \ -b:a 320k \ -ar 48000 \ -strict -2 \ "$file_to_save" } function webcam { # Uses on-webcam h264 encoding. local USERNAME PASSWORD USERNAME="$1" PASSWORD="$2" set -x </dev/null exec ffmpeg \ -re \ -input_format h264 \ -video_size 1920x1080 \ -i /dev/video0 \ -c:v copy \ -an \ -f rtsp \ -rtsp_transport tcp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } function encode_webcam { # Uses hardware accelerated gpu-based encoding. local USERNAME PASSWORD USERNAME="$1" PASSWORD="$2" set -x </dev/null exec ffmpeg \ -re \ -vaapi_device /dev/dri/renderD128 \ -i /dev/video0 \ -vf 'format=nv12,hwupload' \ -c:v h264_vaapi \ -an \ -f rtsp \ -rtsp_transport tcp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } function speed_up_preprocess_vp8 { local file_to_cast file_to_save file_to_cast="$1" file_to_save="$2" set -x # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. # -strict -2 :: Enable support for experimental codecs like opus. # -b:v 2M :: Target 2 megabit/s # -crf 10 :: Target a quality level and adjust bitrate accordingly. This should be preferred, but ideally both should be used. # Could also use -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" </dev/null exec ffmpeg \ -i "$file_to_cast" \ -filter:v "setpts=0.66666666*PTS" \ -filter:a "atempo=1.5" \ -c:v vp8 \ -b:v 2M \ -crf 10 \ -bf 0 \ -c:a opus \ -b:a 320k \ -ar 48000 \ -strict -2 \ "$file_to_save" } main "${@}"