Skip to content

Instantly share code, notes, and snippets.

@baptx
Last active July 23, 2024 13:38
Show Gist options
  • Save baptx/7faaaf876ef38db040ce0e25bde41625 to your computer and use it in GitHub Desktop.
Save baptx/7faaaf876ef38db040ce0e25bde41625 to your computer and use it in GitHub Desktop.
PinePhone video recording using ffmpeg with preview
#!/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