Created
February 18, 2023 21:27
-
-
Save funnierinspanish/fd50432588eae785b64974d67c9bfbb7 to your computer and use it in GitHub Desktop.
A bash script that allows the user to pick a gphoto2 compatible camera connected to their linux device to create a virtual webcam using v4l2loopback
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
## | |
# Error "An error occurred in the io-library ('Timeout reading from or writing to the port'): No error description available ERROR: Movie capture error... Exiting." | |
# -> https://github.com/gphoto/gphoto2/issues/495 | |
## | |
generate_virtual_camera_names() { | |
local length=$1 | |
local test_strings=() | |
for i in $(seq 0 $((length - 1))); do | |
test_strings+=("Virtual_Camera_$i") | |
done | |
(IFS=,; echo "${test_strings[*]}") | |
} | |
generate_virtual_camera_ids() { | |
local length=$1 | |
local test_strings=() | |
for i in $(seq 0 $((length - 1))); do | |
test_strings+=($((10 + $i))) | |
done | |
(IFS=,; echo "${test_strings[*]}") | |
} | |
cleanup () { | |
echo; echo 'Removing v4l2loopback' | |
sudo modprobe -r v4l2loopback | |
echo; echo 'Removing /dev/video10 device' | |
sudo rm -fr /dev/video10 | |
} | |
if [[ $1 == "cleanup" ]]; then | |
echo "Cleaning things up..." | |
cleanup | |
exit 0 | |
fi | |
on_exit () { | |
trap TERM | |
cleanup | |
exit 0 | |
} | |
trap "on_exit" INT | |
start_camera() { | |
echo "Attaching camera $1 to virtual device at /dev/video10" | |
# gphoto2 --port $1 --stdout --capture-movie | ffmpeg -hide_banner -loglevel panic -nostats -i - -vcodec rawvideo -pix_fmt yuv420p -f v4l2 /dev/video10 | |
gphoto2 --port $1 --stdout --capture-movie | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -f v4l2 /dev/video10 | |
} | |
create_virtual_camera() { | |
echo "Creating virtual camera device /dev/video10" | |
echo; | |
#sudo modprobe v4l2loopback exclusive_caps=1 video_nr=10,11 card_label="Virtual Camera","Virtual Camera Aux" | |
sudo modprobe v4l2loopback exclusive_caps=1 video_nr=10 card_label="Virtual Camera" devices=1 | |
echo; | |
} | |
########## | |
## Menu | |
# By Alexander Klimetschek | |
# At https://unix.stackexchange.com/a/415155 | |
########## | |
function select_option { | |
# little helpers for terminal print control and key input | |
ESC=$( printf "\033") | |
cursor_blink_on() { printf "$ESC[?25h"; } | |
cursor_blink_off() { printf "$ESC[?25l"; } | |
cursor_to() { printf "$ESC[$1;${2:-1}H"; } | |
print_option() { printf " $1 "; } | |
print_selected() { printf " $ESC[7m $1 $ESC[27m"; } | |
get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; } | |
key_input() { read -s -n3 key 2>/dev/null >&2 | |
if [[ $key = $ESC[A ]]; then echo up; fi | |
if [[ $key = $ESC[B ]]; then echo down; fi | |
if [[ $key = "" ]]; then echo enter; fi; } | |
# initially print empty new lines (scroll down if at bottom of screen) | |
for opt; do printf "\n"; done | |
# determine current screen position for overwriting the options | |
local lastrow=`get_cursor_row` | |
local startrow=$(($lastrow - $#)) | |
# ensure cursor and input echoing back on upon a ctrl+c during read -s | |
trap "cursor_blink_on; stty echo; printf '\n'; exit" 2 | |
cursor_blink_off | |
local selected=0 | |
while true; do | |
# print options by overwriting the last lines | |
local idx=0 | |
for opt; do | |
cursor_to $(($startrow + $idx)) | |
if [ $idx -eq $selected ]; then | |
print_selected "$opt" | |
else | |
print_option "$opt" | |
fi | |
((idx++)) | |
done | |
# user key control | |
case `key_input` in | |
enter) break;; | |
up) ((selected--)); | |
if [ $selected -lt 0 ]; then selected=$(($# - 1)); fi;; | |
down) ((selected++)); | |
if [ $selected -ge $# ]; then selected=0; fi;; | |
esac | |
done | |
# cursor position back to normal | |
cursor_to $lastrow | |
printf "\n" | |
cursor_blink_on | |
return $selected | |
} | |
echo "Select one option using up/down keys and enter to confirm:" | |
echo | |
options=$(gphoto2 --auto-detect | awk 'NR > 2 { print $0 }') | |
IFS=$'\n' read -d '' -ra optionsArr <<< "$options" | |
select_option "${optionsArr[@]}" | |
choice=$? | |
echo "Creating Virtual Camera for ${optionsArr[$choice]}" | |
echo "..." | |
cleanup | |
sleep 1 | |
create_virtual_camera | |
name=$(echo ${optionsArr[$choice]} | sed 's/\susb:/\n/g' | awk 'NR==1') | |
port=usb:$(echo ${optionsArr[$choice]} | sed 's/\susb:/\n/g' | awk 'NR==2') | |
sleep 1 | |
start_camera "${port% }" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment