#!/bin/bash # Default variables RESOLUTION=1920x1080 FPS=30 CHANNELS=2 RATE=48000 TIMESTAMP=0 VOLUME=1 BORDER=true LOOPBACK=true VIDEO=true AUDIO=true VIDEODEVICE=/dev/video50 AUDIODEVICE=/tmp/virtmic BUFFERFILE=/tmp/virtplay FFMPEGOPTIONS="" ################## while [ ! $# == 0 ]; do case "$1" in -r | --resolution) RESOLUTION=$2 ;; -f | --fps) FPS=$2 ;; -b | --border) BORDER=$2 ;; -l | --loopback) LOOPBACK=$2 ;; -ar | --audio-rate) RATE=$2 ;; -c | --channels) CHANNELS=$2 ;; -ao | --audio-only) VIDEO=false; AUDIO=true ;; -vo | --video-only) VIDEO=true; AUDIO=false ;; -vd | --video-device) VIDEODEVICE=$2 ;; -ad | --audio-device) AUDIODEVICE=$2 ;; -bf | --buffer-file) BUFFERFILE=$2 ;; -t | --timestamp) TIMESTAMP=$2 ;; -v | --volume) VOLUME=$2 ;; -h | --help | "") echo "VirtPlay v3 - Plays a video/audio file through a virtual webcam and microphone" echo "" echo "Usage: $0 [options] [value] [file]" echo "" echo "-h, --help | Shows this help statement" echo "-r, --resolution [$RESOLUTION] | Changes the output resolution of the virtual webcam" echo "-f, --fps [$FPS] | Changes the FPS of the fake webcam" echo "-ar, --audio-rate [$RATE] | Changes the audio samping rate of the virtual microphone" echo "-c, --channels [$CHANNELS] | Changes the number of audio channels" echo "-b, --border [$BORDER] | Enables or disables changing the output's aspect ratio" echo "-l, --loopback [$LOOPBACK] | Enables or disables audio loopback" echo "-t, --timestamp | Jumps output to timestamp in either seconds or [HH:]MM:SS[.m...]" echo "-v, --volume [$VOLUME] | Sets the volume of the virtual microphone where 1 is 100%" echo "-ao, --audio-only | Create a virtual microphone only" echo "-vo, --video-only | Create a virtual webcam only" echo "-vd, --video-device [$VIDEODEVICE] | Changes which video device to output to" echo "-ad, --audio-device [$AUDIODEVICE] | Changes the path for the fake audio device" echo "-bf, --buffer-file [$BUFFERFILE] | Changes the path of the file that will be used when piping from stdin because bash is stupid" exit ;; *) if [[ -f $1 ]]; then FILE="$1" fi ;; esac shift done if [[ ! $FILE ]]; then echo "No file specified! Listening on stdin..." FILE="$BUFFERFILE" eval cat /dev/stdin > $BUFFERFILE fi trap ctrl_c INT function ctrl_c() { if [[ $AUDIO == true ]]; then pactl unload-module module-pipe-source if [[ $LOOPBACK == true ]]; then pactl unload-module module-loopback fi fi if [[ $FILE == $BUFFERFILE ]]; then eval rm $BUFFERFILE fi exit } if [[ $VIDEO == true ]] && ffprobe -i "$FILE" -show_streams -select_streams v -loglevel error | grep STREAM 2>&1 >/dev/null; then if ! lsmod | grep v4l2loopback; then echo "v4l2loopback not loaded! Please run 'modprobe v4l2loopback' and try again." exit 1 fi FFMPEGOPTIONS+=" -map 0:v -ss $TIMESTAMP -vsync -1 -f v4l2 -pix_fmt yuv420p -s $RESOLUTION -r $FPS $VIDEODEVICE " #ffmpeg -i $FILE -f v4l2 -pix_fmt yuv420p -s $RESOLUTION -r $FPS $VIDEODEVICE fi if [[ $AUDIO == true ]] && ffprobe -i "$FILE" -show_streams -select_streams a -loglevel error | grep STREAM 2>&1 >/dev/null; then pactl load-module module-pipe-source source_name=virtmic file=$AUDIODEVICE format=s16le rate=$RATE channels=$CHANNELS pactl set-default-source virtmic if [[ $LOOPBACK == true ]]; then pactl load-module module-loopback fi FFMPEGOPTIONS+=" -map 1:a -ss $TIMESTAMP -f s16le -af aresample=async=1000,aresample=$RATE,volume=$VOLUME -ar $RATE -ac $CHANNELS -y $AUDIODEVICE " #eval ffmpeg -re -i "$FILE" -f s16le -ar 48000 -ac 2 -y $AUDIODEVICE fi sleep 1 ffmpeg -re -err_detect ignore_err -i "$FILE" -re -err_detect ignore_err -i "$FILE" $FFMPEGOPTIONS sleep 1 if [[ $AUDIO == true ]]; then pactl unload-module module-pipe-source pactl unload-module module-loopback if [[ "$FILE" = "$BUFFERFILE" ]]; then eval rm $BUFFERFILE fi fi