Class: TUITD::VideoRecorder
- Inherits:
-
Object
- Object
- TUITD::VideoRecorder
- Defined in:
- lib/tui_td/video_recorder.rb
Overview
Records TUI sessions as video using ffmpeg.
Frames are captured via the existing Screenshot pipeline and piped directly to ffmpeg’s stdin as PNG images — no temporary frame files.
Usage:
recorder = VideoRecorder.new("session.mp4", driver: driver, framerate: 30)
recorder.start
# ... interact with TUI ...
recorder.stop # => "session.mp4"
Constant Summary collapse
- QUALITY_CRF =
{ "high" => 18, "medium" => 23, "low" => 28, }.freeze
- DEFAULT_QUALITY =
"high"- DEFAULT_FRAMERATE =
30- DEFAULT_CODEC =
"libx264"
Instance Attribute Summary collapse
-
#codec ⇒ Object
readonly
Returns the value of attribute codec.
-
#framerate ⇒ Object
readonly
Returns the value of attribute framerate.
-
#output_path ⇒ Object
readonly
Returns the value of attribute output_path.
-
#quality ⇒ Object
readonly
Returns the value of attribute quality.
Class Method Summary collapse
-
.available? ⇒ Boolean
Check whether ffmpeg is available on the system.
Instance Method Summary collapse
-
#initialize(output_path, driver:, framerate: DEFAULT_FRAMERATE, codec: DEFAULT_CODEC, quality: DEFAULT_QUALITY) ⇒ VideoRecorder
constructor
A new instance of VideoRecorder.
-
#recording? ⇒ Boolean
Is recording currently active?.
-
#start ⇒ Object
Start recording.
-
#stop ⇒ Object
Stop recording.
Constructor Details
#initialize(output_path, driver:, framerate: DEFAULT_FRAMERATE, codec: DEFAULT_CODEC, quality: DEFAULT_QUALITY) ⇒ VideoRecorder
Returns a new instance of VideoRecorder.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tui_td/video_recorder.rb', line 32 def initialize(output_path, driver:, framerate: DEFAULT_FRAMERATE, codec: DEFAULT_CODEC, quality: DEFAULT_QUALITY) raise Error, "ffmpeg not found. Install ffmpeg to use video recording." unless self.class.available? @output_path = File.(output_path) @driver = driver @framerate = framerate @codec = codec @quality = quality @ffmpeg_io = nil @capture_thread = nil @running = false @mutex = Mutex.new @frame_interval = 1.0 / framerate end |
Instance Attribute Details
#codec ⇒ Object (readonly)
Returns the value of attribute codec.
30 31 32 |
# File 'lib/tui_td/video_recorder.rb', line 30 def codec @codec end |
#framerate ⇒ Object (readonly)
Returns the value of attribute framerate.
30 31 32 |
# File 'lib/tui_td/video_recorder.rb', line 30 def framerate @framerate end |
#output_path ⇒ Object (readonly)
Returns the value of attribute output_path.
30 31 32 |
# File 'lib/tui_td/video_recorder.rb', line 30 def output_path @output_path end |
#quality ⇒ Object (readonly)
Returns the value of attribute quality.
30 31 32 |
# File 'lib/tui_td/video_recorder.rb', line 30 def quality @quality end |
Class Method Details
.available? ⇒ Boolean
Check whether ffmpeg is available on the system.
49 50 51 |
# File 'lib/tui_td/video_recorder.rb', line 49 def self.available? system("which ffmpeg > /dev/null 2>&1") end |
Instance Method Details
#recording? ⇒ Boolean
Is recording currently active?
94 95 96 |
# File 'lib/tui_td/video_recorder.rb', line 94 def recording? @mutex.synchronize { @running } end |
#start ⇒ Object
Start recording. Spawns ffmpeg and begins frame capture.
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/tui_td/video_recorder.rb', line 54 def start @mutex.synchronize do raise Error, "Recording already in progress" if @running @ffmpeg_io = IO.popen(ffmpeg_command, "w", err: File::NULL) @running = true end @capture_thread = Thread.new { capture_loop } true end |
#stop ⇒ Object
Stop recording. Waits for ffmpeg to finalize and returns the output path.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/tui_td/video_recorder.rb', line 67 def stop @mutex.synchronize do return nil unless @running @running = false end @capture_thread&.join(5) begin @capture_thread&.kill rescue StandardError nil end @capture_thread = nil begin @ffmpeg_io&.close_write @ffmpeg_io&.close rescue StandardError nil end @ffmpeg_io = nil @output_path end |