#!/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" = "h264" ]; then h264 "${@}" elif [ "$cmd" = "software_h264" ]; then software_h264 "${@}" 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" exec ffmpeg \ -re \ -stream_loop -1 \ -i "$file_to_cast" \ -c copy \ -f rtsp \ -rtsp_transport udp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } function h264 { local file_to_cast file_to_cast="$3" local USERNAME PASSWORD USERNAME="$1" PASSWORD="$2" # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. 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 h264_vaapi \ -bf 0 \ -c:a aac \ -b:a 160k \ -ar 44100 \ -f rtsp \ -rtsp_transport udp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } function software_h264 { local file_to_cast file_to_cast="$3" local USERNAME PASSWORD USERNAME="$1" PASSWORD="$2" # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. exec ffmpeg \ -re \ -stream_loop -1 \ -i "$file_to_cast" \ -c:v h264 \ -bf 0 \ -c:a aac \ -b:a 160k \ -ar 44100 \ -f rtsp \ -rtsp_transport udp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } function preprocess_h264 { local file_to_cast file_to_save file_to_cast="$1" file_to_save="$2" # -bf 0 :: Disable b-frames because webrtc doesn't support h264 streams with b-frames. exec ffmpeg \ -i "$file_to_cast" \ -c:v h264 \ -bf 0 \ -c:a aac \ -b:a 160k \ -ar 44100 \ "$file_to_save" } function preprocess_vp8 { local file_to_cast file_to_save file_to_cast="$1" file_to_save="$2" # -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 1M :: Target 1 megabit/s # -crf 10 :: Target a quality level and adjust bitrate accordingly. This should be preferred, but ideally both should be used. exec ffmpeg \ -i "$file_to_cast" \ -c:v vp8 \ -b:v 1M \ -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" exec ffmpeg \ -re \ -input_format h264 \ -video_size 1920x1080 \ -i /dev/video0 \ -c:v copy \ -an \ -f rtsp \ -rtsp_transport udp \ "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" exec ffmpeg \ -re \ -vaapi_device /dev/dri/renderD128 \ -i /dev/video0 \ -vf 'format=nv12,hwupload' \ -c:v h264_vaapi \ -an \ -f rtsp \ -rtsp_transport udp \ "rtsp://$USERNAME:$PASSWORD@172.16.16.251:8554/fetch" } main "${@}"