Class: AsciinemaWin::Recorder

Inherits:
Object
  • Object
show all
Defined in:
lib/asciinema_win/recorder.rb

Overview

Terminal session recorder for Windows

Captures terminal output by periodically sampling the screen buffer and detecting changes between frames. Produces asciicast v2 compatible recordings that can be played back or uploaded to asciinema.org.

Examples:

Record an interactive session

recorder = AsciinemaWin::Recorder.new(title: "Demo")
recorder.record("session.cast") do
  # Recording runs until Ctrl+D or block exits
end

Record a command

recorder = AsciinemaWin::Recorder.new(command: "dir /s")
recorder.record("command.cast")

Constant Summary collapse

DEFAULT_IDLE_TIME_LIMIT =

Default maximum idle time between events (seconds)

2.0
DEFAULT_CAPTURE_INTERVAL =

Default interval between screen captures (seconds)

0.1
MIN_CAPTURE_INTERVAL =

Minimum interval between captures to avoid CPU thrashing

0.033

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(title: nil, command: nil, idle_time_limit: DEFAULT_IDLE_TIME_LIMIT, capture_interval: DEFAULT_CAPTURE_INTERVAL, env_vars: %w[SHELL TERM COMSPEC]) ⇒ Recorder

Create a new recorder

Parameters:

  • title (String, nil) (defaults to: nil)

    Recording title

  • command (String, nil) (defaults to: nil)

    Command to record in subprocess

  • idle_time_limit (Float) (defaults to: DEFAULT_IDLE_TIME_LIMIT)

    Maximum idle time (capped in output)

  • capture_interval (Float) (defaults to: DEFAULT_CAPTURE_INTERVAL)

    Time between screen captures

  • env_vars (Array<String>) (defaults to: %w[SHELL TERM COMSPEC])

    Environment variable names to capture



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/asciinema_win/recorder.rb', line 56

def initialize(
  title: nil,
  command: nil,
  idle_time_limit: DEFAULT_IDLE_TIME_LIMIT,
  capture_interval: DEFAULT_CAPTURE_INTERVAL,
  env_vars: %w[SHELL TERM COMSPEC]
)
  @title = title
  @command = command
  @idle_time_limit = idle_time_limit.to_f
  @capture_interval = [capture_interval.to_f, MIN_CAPTURE_INTERVAL].max
  @env_vars = env_vars

  @state = :idle
  @writer = nil
  @start_time = nil
  @last_buffer = nil
  @capture_thread = nil
  @stop_requested = false
  @markers = []
end

Instance Attribute Details

#capture_intervalFloat (readonly)

Returns Interval between screen captures.

Returns:

  • (Float)

    Interval between screen captures



41
42
43
# File 'lib/asciinema_win/recorder.rb', line 41

def capture_interval
  @capture_interval
end

#commandString? (readonly)

Returns Command to record.

Returns:

  • (String, nil)

    Command to record



35
36
37
# File 'lib/asciinema_win/recorder.rb', line 35

def command
  @command
end

#env_varsArray<String> (readonly)

Returns Environment variables to capture.

Returns:

  • (Array<String>)

    Environment variables to capture



44
45
46
# File 'lib/asciinema_win/recorder.rb', line 44

def env_vars
  @env_vars
end

#idle_time_limitFloat (readonly)

Returns Maximum idle time between events.

Returns:

  • (Float)

    Maximum idle time between events



38
39
40
# File 'lib/asciinema_win/recorder.rb', line 38

def idle_time_limit
  @idle_time_limit
end

#stateSymbol (readonly)

Returns Current recording state (:idle, :recording, :paused, :stopped).

Returns:

  • (Symbol)

    Current recording state (:idle, :recording, :paused, :stopped)



47
48
49
# File 'lib/asciinema_win/recorder.rb', line 47

def state
  @state
end

#titleString? (readonly)

Returns Recording title.

Returns:

  • (String, nil)

    Recording title



32
33
34
# File 'lib/asciinema_win/recorder.rb', line 32

def title
  @title
end

Instance Method Details

#add_marker(label = "") ⇒ Hash?

Add a marker at the current position

Parameters:

  • label (String) (defaults to: "")

    Marker label

Returns:

  • (Hash, nil)

    The marker { time:, label: }, or nil if not recording



132
133
134
135
136
137
138
139
140
# File 'lib/asciinema_win/recorder.rb', line 132

def add_marker(label = "")
  return unless @writer && @start_time

  time = current_time
  @writer.write_marker(time, label)
  marker = { time: time, label: label }
  @markers << marker
  marker
end

#pausevoid

This method returns an undefined value.

Pause recording (stops capturing but keeps file open)



105
106
107
108
109
# File 'lib/asciinema_win/recorder.rb', line 105

def pause
  return unless @state == :recording

  @state = :paused
end

#record(output_path) {|Recorder| ... } ⇒ Hash

Start recording to a file

Parameters:

  • output_path (String)

    Path to save the recording

Yields:

  • (Recorder)

    Block for interactive recording

Returns:

  • (Hash)

    Recording statistics

Raises:



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/asciinema_win/recorder.rb', line 84

def record(output_path, &block)
  raise RecordingError, "Already recording" if @state == :recording

  @state = :recording
  @stop_requested = false
  @markers = []

  begin
    if @command
      record_command(output_path)
    else
      record_interactive(output_path, &block)
    end
  ensure
    @state = :stopped
  end
end

#resumevoid

This method returns an undefined value.

Resume recording after pause



114
115
116
117
118
# File 'lib/asciinema_win/recorder.rb', line 114

def resume
  return unless @state == :paused

  @state = :recording
end

#stopvoid

This method returns an undefined value.

Stop recording



123
124
125
126
# File 'lib/asciinema_win/recorder.rb', line 123

def stop
  @stop_requested = true
  @state = :stopped
end