Last active
July 23, 2024 13:38
-
-
Save baptx/7faaaf876ef38db040ce0e25bde41625 to your computer and use it in GitHub Desktop.
PinePhone video recording using ffmpeg with preview
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
#!/usr/bin/env bash | |
# PinePhone video recording using ffmpeg with preview | |
# Based on https://gitlab.com/Alaraajavamma/fastvideo | |
# Video recording requires a recent Linux kernel version like 6.6: https://forum.pine64.org/showthread.php?tid=16539&pid=122700#pid122700 | |
# The script is based on v4l2loopback (setup instructions can be found at the end of the script) | |
# Close the first preview window to start recording and close the second preview window to end recording (you need to wait that the GUI or ffmpeg ends before recording a new video) | |
# | |
# For quick access, you can create a file like ~/.local/share/applications/megavideo.desktop with this content (adjust executable path if needed): | |
# [Desktop Entry] | |
# Name=MegaVideo | |
# Exec=/opt/megavideo/pinephone_record_with_preview_gui.sh | |
# Terminal=false | |
# Icon=camera-video | |
# Type=Application | |
# X-Purism-FormFactor=Workstation;Mobile; | |
# | |
# And this content in /opt/megavideo/pinephone_record_with_preview_gui.sh: | |
# yad --title="Video recording" --text="Camera preview will be displayed in a new window" --form --field="Open rear camera":fbtn "/opt/megavideo/pinephone_record_with_preview.sh" --field="Open front camera":fbtn "/opt/megavideo/pinephone_record_with_preview.sh front" --buttons-layout=center --button="Quit" | |
WIDTH=1280 | |
HEIGHT=720 | |
FPS=30 | |
# enable microphone audio in case it is disabled | |
amixer set Capture cap | |
CAMERA="ov5640" | |
SECONDARY_CAMERA="gc2145" | |
if [ "$1" == "front" ]; then | |
CAMERA="gc2145" | |
SECONDARY_CAMERA="ov5640" | |
fi | |
MATCH="$(media-ctl -d1 -p | grep sun6i-csi)" | |
if [ "$MATCH" ]; then | |
DEVICE="1" | |
else | |
DEVICE="0" | |
fi | |
MAIN_SENSOR="$(media-ctl -d$DEVICE -p | awk '/: '"$CAMERA"'/ {print "\"" $4, $5 "\""}')" | |
SECONDARY_SENSOR="$(media-ctl -d$DEVICE -p | awk '/: '"$SECONDARY_CAMERA"'/ {print "\"" $4, $5 "\""}')" | |
VIDEO_SOURCE="$(media-ctl -d$DEVICE -p | awk '/\/dev\/video/ {print $NF}')" | |
media-ctl -d$DEVICE -l"$SECONDARY_SENSOR:0->1:0[0],$MAIN_SENSOR:0->1:0[1]" | |
media-ctl -d$DEVICE -V"$MAIN_SENSOR:0[fmt:UYVY8_2X8/${WIDTH}x${HEIGHT}@1/$FPS]" | |
# Use same date format as Megapixels app based on ISO 8601 | |
TIMENOW="VID"$(date +%Y%m%d%H%M%S) | |
# libx264 recording without preview | |
#ffmpeg -input_format yuv420p -s ${WIDTH}x${HEIGHT} -f video4linux2 -thread_queue_size 4096 -i $VIDEO_SOURCE -f pulse -thread_queue_size 256 -i alsa_input.platform-sound.HiFi__hw_PinePhone_0__source -c:a aac -c:v libx264 -preset ultrafast -qp 23 ~/Videos/$TIMENOW.mp4 | |
# mjpeg configuration (does not work for front camera: "No JPEG data found in image") | |
# https://www.reddit.com/r/PINE64official/comments/olyqor/how_i_record_video_on_my_pinephone_in_tolerable/ | |
# https://www.reddit.com/r/pinephone/comments/p7eg2c/video_recording_using_gstreamer_on_the_pinephone/ | |
#media-ctl -d$DEVICE --set-v4l2 "$MAIN_SENSOR:0[fmt:JPEG_1X8/${WIDTH}x${HEIGHT}@1/$FPS]" | |
#v4l2-ctl --device $VIDEO_SOURCE --set-fmt-video="width=$WIDTH,height=$HEIGHT,pixelformat=JPEG" | |
# mjpeg recording with preview | |
#ffmpeg -f v4l2 -framerate 30 -video_size ${WIDTH}x${HEIGHT} -input_format mjpeg -i $VIDEO_SOURCE -f pulse -i alsa_input.platform-sound.HiFi__hw_PinePhone_0__source -c:a pcm_s16le -c:v mjpeg -b:v 64000k ~/Videos/$TIMENOW.avi -map 0:v -vf "format=yuv420p" -f xv display | |
# attempt to rotate recording and preview did not work: https://raspberrypi.stackexchange.com/questions/111713/is-there-a-way-to-rotate-the-cameras-image-at-the-driver-level-not-processing/114253#114253 | |
#if [ "$2" == "portrait" ]; then | |
# v4l2-ctl --device $VIDEO_SOURCE --set-ctrl=rotate=90 | |
#fi | |
# libx264 recording with preview (delay in preview: https://superuser.com/questions/343586/how-to-display-and-capture-webcam-stream-at-the-same-time/1551806#1551806) | |
#ffmpeg -input_format yuv420p -s ${WIDTH}x${HEIGHT} -f video4linux2 -thread_queue_size 4096 -i $VIDEO_SOURCE -f pulse -thread_queue_size 256 -i alsa_input.platform-sound.HiFi__hw_PinePhone_0__source -c:a aac -c:v libx264 -preset ultrafast -qp 23 ~/Videos/$TIMENOW.mp4 -f xv display | |
# libx264 recording with preview (no delay in preview: https://askubuntu.com/questions/165727/is-it-possible-for-two-processes-to-access-the-webcam-at-the-same-time/1244152#1244152) | |
# modprobe commands with root password are not needed when adding "options v4l2loopback exclusive_caps=1 video_nr=4" in a file like /etc/modprobe.d/dkms.conf and "v4l2loopback" in /etc/modules-load.d/modules.conf or /etc/modules (https://unix.stackexchange.com/questions/680689/load-kernel-module-at-boot-time-with-options/680698#680698) | |
# use video_nr=4 if the first video device that does not exist yet is /dev/video4 and so on | |
# thread_queue_size for audio increased from 256 to 512 due to error "Thread message queue blocking; consider raising the thread_queue_size option" (default value was 8) | |
quit() { | |
sleep 5 # wait a few seconds to be sure that the full video is recorded | |
killall ffmpeg | |
killall yad # close GUI automatically to know when the recording is finished (killing all ffmpeg and yad processes is ok as long as you don't have others running at the same time) | |
#sudo modprobe -r v4l2loopback | |
} | |
recording() { | |
ffmpeg -input_format yuv420p -s ${WIDTH}x${HEIGHT} -f video4linux2 -thread_queue_size 4096 -i /dev/video4 -f pulse -thread_queue_size 512 -i alsa_input.platform-sound.HiFi__hw_PinePhone_0__source -c:a aac -c:v libx264 -preset ultrafast -qp 23 ~/Videos/$TIMENOW.mp4 & | |
ffplay /dev/video4 | |
quit | |
} | |
#sudo modprobe -r v4l2loopback # can fix issue "Some buffers are still owned by the caller on close" | |
#sudo modprobe v4l2loopback exclusive_caps=1 video_nr=4 | |
ffmpeg -i $VIDEO_SOURCE -f v4l2 -codec:v rawvideo -pix_fmt yuv420p /dev/video4 & | |
sleep 1 # avoid error "Not a video capture device" | |
ffplay -vf "drawtext=text='Close window to start recording':fontcolor=white:fontsize=24:box=1:boxcolor=black@0.5:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2" /dev/video4 # preview and start recording when the first preview window is closed (https://stackoverflow.com/questions/17623676/text-on-video-ffmpeg/17624103#17624103) | |
recording |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment