X-Git-Url: http://git.scottworley.com/srec/blobdiff_plain/990069b559e1e3396745a09b2d2fe8612450a37e..7a85446a6afdda20c39452fe2ab8b9bd292556ad:/srec.py diff --git a/srec.py b/srec.py index 36000c9..7780e51 100644 --- a/srec.py +++ b/srec.py @@ -4,6 +4,9 @@ # under the terms of the GNU General Public License as published by the # Free Software Foundation, version 3. +from dataclasses import dataclass +from datetime import datetime +import os import subprocess from typing import Callable @@ -12,33 +15,51 @@ gi.require_version("Gtk", "4.0") from gi.repository import Gtk # nopep8 pylint: disable=wrong-import-position -recording = None +@dataclass +class Recording: + filename: str + process: subprocess.Popen[bytes] + + +recording: Recording | None = None + + +def make_filename() -> str: + directory = os.environ.get( + 'XDG_VIDEOS_DIR', + os.path.expanduser('~/Videos/SRec')) + os.makedirs(directory, exist_ok=True) + timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + return os.path.join(directory, f'srec {timestamp}.mkv') + + +def video_source(stack: Gtk.Stack) -> list[str]: + if stack.get_child_by_name('not_recording').get_first_child().get_active(): + return ['-f', 'x11grab', '-i', ':0.0+0,0'] + return ['-f', 'v4l2', '-i', '/dev/video0'] def on_start_recording(_: Gtk.Button, stack: Gtk.Stack) -> None: global recording # pylint: disable=global-statement assert recording is None - screen_size = '1366x768' # TODO - command = [ - 'ffmpeg', - '-video_size', screen_size, - '-framerate', '25', - '-f', 'x11grab', '-i', ':0.0+0,0', - '-f', 'pulse', '-ac', '2', '-i', 'default', - 'screen-recording.mkv'] # nopep8 + filename = make_filename() + command = (['ffmpeg', '-framerate', '25'] + video_source(stack) + + ['-f', 'pulse', '-ac', '2', '-i', 'default', filename]) # pylint: disable=consider-using-with - recording = subprocess.Popen(command, stdin=subprocess.PIPE) + recording = Recording( + filename=filename, + process=subprocess.Popen(command, stdin=subprocess.PIPE)) stack.set_visible_child_name("recording") def on_stop_recording(_: Gtk.Button, stack: Gtk.Stack) -> None: global recording # pylint: disable=global-statement assert recording is not None - stdin = recording.stdin + stdin = recording.process.stdin assert stdin is not None stdin.write(b'q') stdin.flush() - recording.wait() + recording.process.wait() recording = None stack.set_visible_child_name("not_recording") @@ -57,16 +78,22 @@ def make_button(label: str, action: Callable[[ def on_activate(app: Gtk.Application) -> None: win = Gtk.ApplicationWindow(application=app) win.set_title('SRec') - stack = Gtk.Stack() + win.set_icon_name('srec') - start_recording = make_button("Start Recording", on_start_recording, stack) - stack.add_named(start_recording, "not_recording") + stack = Gtk.Stack() - box = Gtk.Box() - box.set_orientation(Gtk.Orientation.VERTICAL) - stop_recording = make_button("Stop Recording", on_stop_recording, stack) - box.append(stop_recording) - stack.add_named(box, "recording") + nr_box = Gtk.Box() + nr_box.set_orientation(Gtk.Orientation.VERTICAL) + screen = Gtk.CheckButton(label='Screen') + nr_box.append(screen) + nr_box.append(Gtk.CheckButton(label='Webcam', active=True, group=screen)) + nr_box.append(make_button("Start Recording", on_start_recording, stack)) + stack.add_named(nr_box, "not_recording") + + r_box = Gtk.Box() + r_box.set_orientation(Gtk.Orientation.VERTICAL) + r_box.append(make_button("Stop Recording", on_stop_recording, stack)) + stack.add_named(r_box, "recording") win.set_child(stack) win.present()