From 44784c106bbfba2d22b050dfcc7cc79699f9e09d Mon Sep 17 00:00:00 2001 From: Anjandev Momi Date: Fri, 21 Aug 2020 04:45:59 -0700 Subject: [PATCH] camera: low latency preview and picture - Take pictures by pressing "s" when the preview opens. - Depends on sxmo_autorotate.sh - movie is not currently working. See comments in code - uses sxiv for image previews of photos taken during that photoshoot - TODO: use sxiv keyhandlers to add a delete photo function - See: /usr/share/examples/sxiv/key-handler - I dont know how we would distribute this --- scripts/core/sxmo_appmenu.sh | 1 + scripts/core/sxmo_camera.sh | 147 +++++++++++++++++++++++++++++++++-- scripts/core/sxmo_xinit.sh | 1 + 3 files changed, 143 insertions(+), 6 deletions(-) diff --git a/scripts/core/sxmo_appmenu.sh b/scripts/core/sxmo_appmenu.sh index d37b7f6..a6fa136 100755 --- a/scripts/core/sxmo_appmenu.sh +++ b/scripts/core/sxmo_appmenu.sh @@ -176,6 +176,7 @@ programchoicesinit() { Rotate ↻ ^ 1 ^ key greater Flip ⇄ ^ 1 ^ key question Flip ⇅ ^ 1 ^ key bar + Thumbnail ⊡ ^ 0 ^ key Return " WINNAME=Sxiv && return elif echo "$WMCLASS" | grep -i "st-256color"; then diff --git a/scripts/core/sxmo_camera.sh b/scripts/core/sxmo_camera.sh index 9e02ff9..61a23d2 100755 --- a/scripts/core/sxmo_camera.sh +++ b/scripts/core/sxmo_camera.sh @@ -1,8 +1,143 @@ -#!/usr/bin/env sh -err() { - printf %b "$1" | dmenu -fn Terminus-20 -c -l 10 - exit 1 + #!/usr/bin/env sh + +SXMO_IMAGESDIR="$XDG_PICTURES_DIR/sxmo" + +node_rear="ov5640 3-004c" +route_rear="ov5640" +mode_rear="1920x1080@20" + +node_front="gc2145 3-003c" +route_front="gc2145" +mode_front="1600x1200@15" + +pixfmt='UYVY' + +set_route () { + camera="$1" + if [ "$camera" = "$route_rear" ] + then + link1='"gc2145 3-003c":0->"sun6i-csi":0[0]' + link2='"ov5640 3-004c":0->"sun6i-csi":0[1]' + elif [ "$camera" = "$route_front" ] + then + link1='"ov5640 3-004c":0->"sun6i-csi":0[0]' + link2='"gc2145 3-003c":0->"sun6i-csi":0[1]' + fi + + media-ctl -d /dev/media1 --links "$link1" && media-ctl -d /dev/media1 --links "$link2" || exit 1 +} + +setup () { + node="$1" + mode="$2" + + res="${mode%%@*}" + speed="${mode##*@}" + + busfmt='UYVY8_2X8' + + setup="media-ctl -d /dev/media1 --set-v4l2 '\"$node\":0[fmt:$busfmt/$res@1/$speed]'" + eval "$setup" + + height="${res%%x*}" + width="${res##*x}" + + v4l2-ctl --device /dev/video1 --set-fmt-video="width=$width,height=$height,pixelformat=$pixfmt" +} + +still () { + node="$1" + mode="$2" + angle="$3" + skip="$4" + + setup "$node" "$mode" + + speed="30" + res="${mode%%@*}" + speed="${mode##*@}" + + height="${res##*x}" + width="${res%%x*}" + + mkdir "$SXMO_IMAGESDIR" + + SCREENSHOT_PRE="$(date)" + + mplayer tv:// -tv driver=v4l2:width=$width:height=$height:device=/dev/video1 -fps $speed -vf rotate="$angle",screenshot="$SXMO_IMAGESDIR/$SCREENSHOT_PRE" + + find "$SXMO_IMAGESDIR" -iname "$SCREENSHOT_PRE*" | sxiv -t -i - + + # mpv command doesnt work =( https://wiki.archlinux.org/index.php/Webcam_setup#MPlayer + # mpv --demuxer-lavf-format=video4linux2 --demuxer-lavf-o-set=input_format=rawvideo:video_size=1920x1080:framerate=20 av://v4l2:/dev/video1 --profile=low-latency + +} + +movie () { + # Not working but shows off the performance of this script + node="$1" + mode="$2" + angle="$3" + skip="$4" + + setup "$node" "$mode" + + speed="30" + res="${mode%%@*}" + speed="${mode##*@}" + + height="${res##*x}" + width="${res%%x*}" + + VIDEO_NAME="$SXMO_IMAGESDIR"/"$(date)".mkv + # this command gives the best performance but I cannot get a video preview with this command =( + # please note, to stop recording, you need to type `killall ffmpeg` in a terminal + ffmpeg -f v4l2 -framerate $speed -video_size $res -i /dev/video1 -preset ultrafast -filter:v fps=fps=$speed -f matroska "$VIDEO_NAME" + + + save="Save: $VIDEO_NAME" + playback="Playback: $(ffprobe -v quiet -of csv=p=0 -show_entries format=duration "$VIDEO_NAME")" + delete="Delete Recording" + + DONE=0 + + while [ $DONE != 1 ]; do + result="$(printf %b "$save\n$playback\n$delete" | dmenu -fn Terminus-30 -c -p "Record" -l 20)" + if [ "$result" = "$save" ]; then + return 0 + elif [ "$result" = "$playback" ]; then + mpv "$VIDEO_NAME" + else + rm "$VIDEO_NAME" + return 0 + fi + done + + + # outputs 10 fps =( + # ffmpeg -f v4l2 -framerate $speed -video_size $res -i /dev/video1 -preset ultrafast -filter:v fps=fps=$speed -f matroska pipe: | tee file.mkv | mplayer - -fps $speed -vf screenshot + + # I tried forking ffmpeg to background and using mplayer. When mplayer closes, killall ffmpeg. It didnt work =( + #mplayer tv:// -tv driver=v4l2:width=$width:height=$height:device=/dev/video1 -fps $speed -vf screenshot + } -media-ctl -d /dev/media1 --set-v4l2 '"ov5640 3-004c":0[fmt:UYVY8_2X8/1280x720]' || err "Couldn't open camera, is camera enabled?" -mpv --video-rotate=90 av://v4l2:/dev/video1 + +type="$(printf %b "picture\nmovie" | dmenu -fn Terminus-30 -c -p "Record" -l 20)" +camera="$(printf %b "front\nrear" | dmenu -fn Terminus-30 -c -p "Record" -l 20)" + +# Note: "angle" is set according to mplayer's conventions. See man mplayer and look for "rotate" + +[ "$camera" = "rear" ] && set_route "$route_rear" && skip=5 && node="$node_rear" && mode="$mode_rear" && angle="1" +[ "$camera" = "front" ] && set_route "$route_front" && skip=0 && node="$node_front" && mode="$mode_front" && angle="2" + +# our angle variables are set for rotnormal orientation +# rotating will ruin the preview +RUNNING_AUTO="$(ps aux | grep "sh /usr/bin/sxmo_autorotate.sh" | grep -v grep | cut -f2 -d' ')" +[ -n "$RUNNING_AUTO" ] && echo "$RUNNING_AUTO" | tr '\n' ' ' | xargs kill -9; notify-send "Turning autorotate off" +sxmo_rotate.sh isrotated && sxmo_rotate.sh rotnormal + +[ "$type" = "picture" ] && still "$node" "$mode" "$angle" "$skip" +[ "$type" = "movie" ] && movie "$node" "$mode" "$angle" "$skip" + +[ -n "$RUNNING_AUTO" ] && sxmo_autorotate.sh diff --git a/scripts/core/sxmo_xinit.sh b/scripts/core/sxmo_xinit.sh index 1b2675a..16ca646 100755 --- a/scripts/core/sxmo_xinit.sh +++ b/scripts/core/sxmo_xinit.sh @@ -12,6 +12,7 @@ envvars() { [ -z "$XDG_CACHE_HOME" ] && export XDG_CACHE_HOME=~/.cache [ -z "$XDG_DATA_HOME" ] && export XDG_DATA_HOME=~/.local/share [ -z "$XDG_RUNTIME_HOME" ] && export XDG_RUNTIME_HOME=~/.local/run + [ -z "$XDG_PICTURES_DIR" ] && export XDG_PICTURES_DIR=~/Pictures } setupxdgruntimedir() {