summary refs log tree commit diff
path: root/bin/gpctl
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2022-11-18 18:15:24 +0100
committerRobert Günzler <r@gnzler.io>2022-11-18 18:38:22 +0100
commit7d322f5aa22afa2ed85d9453ad80cb3fe799eedf (patch)
treea05410506a5709635b019f43b94dde3753be11a0 /bin/gpctl
parent8e3c8385ba791f462f5be4b6ff28b5a88dd59ad4 (diff)
bin/gpctl: refactor
Diffstat (limited to 'bin/gpctl')
-rwxr-xr-xbin/gpctl94
1 files changed, 53 insertions, 41 deletions
diff --git a/bin/gpctl b/bin/gpctl
index e74a71f..a92c65a 100755
--- a/bin/gpctl
+++ b/bin/gpctl
@@ -1,4 +1,4 @@
-#!/bin/env python3.8
+#!/bin/env python3
 
 import argparse
 import logging
@@ -42,21 +42,21 @@ def take_photo(gp, outdir='.'):
 
 
 def webcam(gp,
-           outdir='.',
            resolution=constants.Webcam.Resolution.R720p,
            fov=constants.Webcam.FOV.Wide):
     # prepare v4l2 device
-    if not os.path.exists('/dev/video9'):
-        logging.info('Creating v4l2 device node at /dev/video9')
-        subprocess.run([
-            'doas -n modprobe v4l2loopback video_nr=9 card_label=GoPro9 exclusive_caps=1'
-        ],
-                       shell=True,
-                       check=True)
-
-    logging.info('Starting webcam mode')
-    gp.webcamFOV(fov)
-    gp.startWebcam(resolution)
+    logging.info('Creating v4l2 device node')
+    v4l2p = subprocess.run([
+        'doas -n modprobe v4l2loopback && doas -n v4l2loopback-ctl add -n GoPro -x 1 || true'
+    ],
+                           shell=True,
+                           check=True,
+                           capture_output=True)
+    vnode = v4l2p.stdout.decode('utf-8').strip()
+
+    logging.info(f'Starting webcam mode ({vnode})')
+    gp.webcamFOV(fov=fov)
+    gp.startWebcam(resolution=resolution)
 
     try:
         # gracefull handle sigterm
@@ -67,12 +67,9 @@ def webcam(gp,
         # pipe video from camera to v4l2 device
         udp_stream = f"udp://{gp.getWebcamIP()}:8554"
         ffmpeg_args = [
-            f"ffmpeg -hide_banner -loglevel warning -probesize 3072 -fflags nobuffer -flags low_delay -i {udp_stream} -vsync 2 -ar 44100 -vcodec rawvideo -pix_fmt yuv420p -f v4l2 /dev/video9"
+            f"ffmpeg -hide_banner -loglevel warning -vsync 2 -fflags nobuffer -flags low_delay -probesize 3072 -nostdin -i {udp_stream} -ar 44100 -f v4l2 -vcodec rawvideo -pix_fmt yuv420p {vnode}"
         ]
         logging.info('Running ffmpeg')
-        # [
-        #     'ffmpeg -hide_banner -loglevel warning -probesize 5000 -analyzeduration 22000 -r 30 -i udp://@:8554 -an -vcodec rawvideo -pix_fmt yuv420p -r 30 -s 1280x720 -flush_packets 1 -f v4l2 /dev/video9'
-        # ]
         subprocess.run(ffmpeg_args, shell=True, check=True)
     except (KeyboardInterrupt, SystemExit, Exception):
         # allow camera to shut down
@@ -80,51 +77,66 @@ def webcam(gp,
         # stop webcam mode
         logging.info('Stopping webcam mode')
         gp.stopWebcam()
+        subprocess.run([f"doas -n v4l2loopback-ctl del {vnode}"],
+                       shell=True,
+                       check=True)
         # done
         logging.info('Exiting...')
 
 
 parser = argparse.ArgumentParser(description='gopro cli utility')
 parser.add_argument('-o',
-                    '--output',
-                    nargs=1,
+                    '--output-directory',
                     type=str,
-                    metavar='OUTPUT',
-                    default='.',
+                    default=['.'],
                     help='Directory to save files to.')
 parser.add_argument('-r',
                     '--resolution',
                     nargs=1,
                     type=str,
-                    metavar='RES',
-                    choices=('1080', '720', '420'),
+                    choices=('1080p', '720p', '420p'),
                     default='1080p',
                     help='Video resolution')
-parser.add_argument('-f',
-                    '--fps',
-                    nargs=1,
-                    type=str,
-                    metavar='FPS',
-                    default='60',
-                    help='Video frame rate')
+# parser.add_argument('-f',
+#                     '--fps',
+#                     type=str,
+#                     default=['60'],
+#                     help='Video frame rate')
 parser.add_argument('-v',
                     '--fov',
-                    nargs=1,
                     type=str,
-                    metavar='FOV',
                     choices=('wide', 'linear', 'narrow'),
-                    default='wide',
+                    default=['wide'],
                     help='Video field of view')
 
-parser.add_argument('--take-photo',
-                    action='store_true',
-                    help='Take a photo and save it to OUTPUT.')
-parser.add_argument('--webcam',
-                    action='store_true',
-                    help='Start webcam mode and register as v4l2 device')
+group = parser.add_mutually_exclusive_group()
+group.add_argument('--take-photo',
+                   action='store_true',
+                   help='Take a photo and save it to OUTPUT.')
+group.add_argument('--webcam',
+                   action='store_true',
+                   help='Start webcam mode and register as v4l2 device')
 
 args = parser.parse_args()
 
+res = constants.Webcam.Resolution.R720p
+if args.resolution:
+    if args.resolution == '1080p':
+        res = constants.Webcam.Resolution.R1080p
+    elif args.resolution == '720p':
+        res = constants.Webcam.Resolution.R720p
+    elif args.resolution == '480p':
+        res = constants.Webcam.Resolution.R480p
+
+fov = constants.Webcam.FOV.Wide
+if args.fov:
+    if args.fov == 'wide':
+        fov = constants.Webcam.FOV.Wide
+    elif args.fov == 'linear':
+        fov = constants.Webcam.FOV.Linear
+    elif args.fov == 'narrow':
+        fov = constants.Webcam.FOV.Narrow
+
 # get camera network device from environment
 # should be up and connected (with an ip address assigned)
 gp = setup_cam(os.getenv('GOPRO_DEVICE', 'gp0'))
@@ -132,9 +144,9 @@ gp = setup_cam(os.getenv('GOPRO_DEVICE', 'gp0'))
 
 try:
     if args.take_photo:
-        take_photo(gp, args.output)
+        take_photo(gp, outdir=args.output_directory[0])
     if args.webcam:
-        webcam(gp)
+        webcam(gp, resolution=res, fov=fov)
 
 except Exception as err:
     logging.error(f"error: {err}")