Initial commit
This commit is contained in:
commit
f6559760b8
2 changed files with 141 additions and 0 deletions
0
README.md
Normal file
0
README.md
Normal file
141
virtplay.sh
Executable file
141
virtplay.sh
Executable file
|
@ -0,0 +1,141 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
# Default variables
|
||||
|
||||
RESOLUTION=1920x1080
|
||||
FPS=30
|
||||
CHANNELS=1
|
||||
RATE=44100
|
||||
TIMESTAMP=0
|
||||
VOLUME=1
|
||||
BORDER=true
|
||||
LOOPBACK=true
|
||||
VIDEO=true
|
||||
AUDIO=true
|
||||
VIDEODEVICE=/dev/video0
|
||||
AUDIODEVICE=/tmp/virtmic
|
||||
BUFFERFILE=/tmp/virtplay
|
||||
FFMPEGOPTIONS=""
|
||||
|
||||
##################
|
||||
|
||||
# Argument parser
|
||||
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
|
||||
|
||||
# Extremely jank stdin because for some reason ffmpeg crashes in this script whenever you pipe shit directly
|
||||
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 fake mic is enabled, delete the fake device
|
||||
if [[ $AUDIO == true ]]; then
|
||||
pactl unload-module module-pipe-source
|
||||
|
||||
# Delete the pipe used for it too
|
||||
if [[ -f $AUDIODEVICE ]]; then rm $AUDIODEVICE; fi
|
||||
fi
|
||||
# Gets rid of the stupid buffer file if it was used
|
||||
if [[ $FILE == $BUFFERFILE ]]; then
|
||||
eval rm $BUFFERFILE
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
# If video is both enabled and the input has a video stream, add video stuff to the ffmpeg command
|
||||
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 -vsync -1 -f v4l2 -pix_fmt yuv420p -s $RESOLUTION -r $FPS $VIDEODEVICE "
|
||||
fi
|
||||
|
||||
# If audio is enabled and the input has an audio stream, do some pulse wizardry and add it to ffmpeg
|
||||
if [[ $AUDIO == true ]] && ffprobe -i "$FILE" -show_streams -select_streams a -loglevel error | grep STREAM 2>&1 >/dev/null; then
|
||||
# Cleanup old pipes
|
||||
if [[ -f $AUDIODEVICE ]]; then rm $AUDIODEVICE; fi
|
||||
|
||||
# Creates a fake microphone and sets it as the default
|
||||
pactl load-module module-pipe-source source_name=virtmic file=$AUDIODEVICE format=s16le rate=$RATE channels=$CHANNELS
|
||||
pactl set-default-source virtmic
|
||||
|
||||
FFMPEGOPTIONS+=" -map 1:a -f s16le -af aresample=async=1000,aresample=$RATE,volume=$VOLUME -ar $RATE -ac $CHANNELS -y $AUDIODEVICE "
|
||||
|
||||
# If loopback is enabled, add even more ffmpeg stuff
|
||||
if [[ $LOOPBACK == true ]]; then
|
||||
FFMPEGOPTIONS+=" -map 1:a -af aresample=async=1000,aresample=$RATE,volume=$VOLUME -ar $RATE -ac $CHANNELS -buffer_duration 10 -f pulse default "
|
||||
fi
|
||||
fi
|
||||
|
||||
# So that Discord doesn't cut off the beginning of our high quality meme that we're playing
|
||||
sleep 1
|
||||
|
||||
ffmpeg -fflags +genpts -ss $TIMESTAMP -re -err_detect ignore_err -i "$FILE" -ss $TIMESTAMP -re -err_detect ignore_err -i "$FILE" $FFMPEGOPTIONS
|
||||
|
||||
# So that Discord doesn't cut off the end of the dank meme
|
||||
sleep 1
|
||||
|
||||
# Cleanup
|
||||
ctrl_c
|
Loading…
Reference in a new issue