tucue 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97054b40943e2128666fdce09762dcc347ed314e8f61cb3af56fb4150379fca5
4
- data.tar.gz: d713fe563c046f18a36123afe12d1f1ce5fdcfb33cc56bc7d374ce83ffb7417f
3
+ metadata.gz: b13df268982a614c075c660f19f057f249be6f0da5f542cd48755bf3f10ba79d
4
+ data.tar.gz: d44cddbf91c73703b81d359dfabbf23af5e05507af59e8a16fdc166d1acbdcea
5
5
  SHA512:
6
- metadata.gz: 4f810dcd87e5ede57616c2672572da421cb98d242af2b22e0e5355f9bf3f7989159d552e0939d02a8c4ce62d0d95fe185d42727371fa9428ce226f8097801174
7
- data.tar.gz: 0cf0d7c900293762b8d3a924a12be24679e94e0dc42d26ba382a1666813adfc380c84e857d4f52cf2f8894a6fa70efee68f321ccc0c9c6542866b88f0317df36
6
+ metadata.gz: df62e31a13f104dc63717aecaefc7dd41ae64463db3730a283a7f67d528ae0c9e61edaa983274cdf55643c10eb3fbefe0b8fb09e57381363092f845e8be03b9b
7
+ data.tar.gz: ee69e7d79e3ecd3a19803e4044b248a34018f6985d33389f5db083626a084dffb1da4f366bf41c8f488a1a96b06402bb1b13b649901b7b75613a8f8943465bb1
data/CLAUDE.md CHANGED
@@ -23,6 +23,7 @@ moments, and exporting them.
23
23
 
24
24
  - [x] Play mp3 / wav files
25
25
  - [x] Rewind / fast-forward in 5- and 15-second steps
26
+ - [x] Adjust playback speed in steps (0.5x – 2.0x)
26
27
  - [x] Mark the current position (with an optional label)
27
28
  - [x] Export the mark list to a file (CSV / JSON)
28
29
 
@@ -99,6 +100,9 @@ IPC notes (see `lib/tucue/player.rb`):
99
100
  | `←` | -5 seconds |
100
101
  | `]` | +15 seconds |
101
102
  | `[` | -15 seconds |
103
+ | `+` / `=` | Speed up one step (max 2.0x) |
104
+ | `-` | Slow down one step (min 0.5x) |
105
+ | `0` | Reset speed to 1.0x |
102
106
  | `m` | Mark the current position |
103
107
  | `e` | Export the marks |
104
108
  | `q` | Quit |
data/README.md CHANGED
@@ -11,11 +11,12 @@ The name is a blend of **TUI** and **Cue** (pronounced "too-cue").
11
11
  ```
12
12
  ┌─────────────────────────────────┐
13
13
  │ File: interview.mp3 │
14
- │ 00:01:23 / 00:45:10 ####---- │
14
+ │ 00:01:23 / 00:45:10 ####---- 1.25x
15
15
  ├─────────────────────────────────┤
16
16
  │ [Space] play/pause │
17
17
  │ [<-] -5s [->] +5s │
18
18
  │ [[] -15s []] +15s │
19
+ │ [-] slower [+] faster [0] reset speed │
19
20
  │ [m] mark [e] export │
20
21
  │ [q] quit │
21
22
  ├─────────────────────────────────┤
@@ -81,6 +82,9 @@ bundle exec tucue --start 01:02:03 interview.mp3
81
82
  | `←` | -5 seconds |
82
83
  | `]` | +15 seconds |
83
84
  | `[` | -15 seconds |
85
+ | `+` / `=` | Speed up one step (max 2x) |
86
+ | `-` | Slow down one step (min 0.5x) |
87
+ | `0` | Reset speed to 1x |
84
88
  | `m` | Mark the current position (prompts for an optional label) |
85
89
  | `e` | Export the marks |
86
90
  | `q` | Quit |
data/lib/tucue/player.rb CHANGED
@@ -16,6 +16,10 @@ module Tucue
16
16
  # Max seconds to wait for the IPC socket to appear.
17
17
  SOCKET_TIMEOUT = 5
18
18
 
19
+ # Selectable playback speeds, from half to double, centered on 1.0.
20
+ SPEED_STEPS = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0].freeze
21
+ DEFAULT_SPEED_INDEX = SPEED_STEPS.index(1.0)
22
+
19
23
  def initialize(file, socket_path: "/tmp/tucue.sock", start_at: nil, extra_args: [])
20
24
  @file = file
21
25
  @socket_path = socket_path
@@ -25,6 +29,7 @@ module Tucue
25
29
  @socket = nil
26
30
  @request_id = 0
27
31
  @mutex = Mutex.new
32
+ @speed_index = DEFAULT_SPEED_INDEX
28
33
  end
29
34
 
30
35
  attr_reader :file
@@ -71,6 +76,29 @@ module Tucue
71
76
  command("seek", seconds, "relative")
72
77
  end
73
78
 
79
+ # Current playback speed multiplier (e.g. 1.0, 1.25).
80
+ def speed
81
+ SPEED_STEPS[@speed_index]
82
+ end
83
+
84
+ # Step the speed up one notch (capped at the fastest step).
85
+ def speed_up
86
+ @speed_index = [@speed_index + 1, SPEED_STEPS.size - 1].min
87
+ apply_speed
88
+ end
89
+
90
+ # Step the speed down one notch (capped at the slowest step).
91
+ def speed_down
92
+ @speed_index = [@speed_index - 1, 0].max
93
+ apply_speed
94
+ end
95
+
96
+ # Reset the speed back to 1.0.
97
+ def reset_speed
98
+ @speed_index = DEFAULT_SPEED_INDEX
99
+ apply_speed
100
+ end
101
+
74
102
  # Current playback position in seconds, or nil if unavailable.
75
103
  def time_pos
76
104
  get_property("time-pos")
@@ -92,6 +120,12 @@ module Tucue
92
120
 
93
121
  private
94
122
 
123
+ # Push the current speed to mpv and return it.
124
+ def apply_speed
125
+ set_property("speed", speed)
126
+ speed
127
+ end
128
+
95
129
  def mpv_available?
96
130
  ENV["PATH"].to_s.split(File::PATH_SEPARATOR).any? do |dir|
97
131
  File.executable?(File.join(dir, "mpv"))
data/lib/tucue/ui.rb CHANGED
@@ -72,6 +72,12 @@ module Tucue
72
72
  @player.seek(SEEK_LARGE)
73
73
  when "["
74
74
  @player.seek(-SEEK_LARGE)
75
+ when "+", "="
76
+ @status = "Speed #{format_speed(@player.speed_up)}"
77
+ when "-"
78
+ @status = "Speed #{format_speed(@player.speed_down)}"
79
+ when "0"
80
+ @status = "Speed #{format_speed(@player.reset_speed)}"
75
81
  when "m"
76
82
  add_mark
77
83
  when "e"
@@ -125,7 +131,7 @@ module Tucue
125
131
  pos = @player.time_pos
126
132
  dur = @player.duration
127
133
  @window.setpos(row, 0)
128
- @window.addstr(" #{format_time(pos)} / #{format_time(dur)} #{progress_bar(pos, dur)}")
134
+ @window.addstr(" #{format_time(pos)} / #{format_time(dur)} #{progress_bar(pos, dur)} #{format_speed(@player.speed)}")
129
135
 
130
136
  row += 1
131
137
  @window.setpos(row, 0)
@@ -135,6 +141,7 @@ module Tucue
135
141
  "[Space] play/pause",
136
142
  "[<-] -#{SEEK_SMALL}s [->] +#{SEEK_SMALL}s",
137
143
  "[[] -#{SEEK_LARGE}s []] +#{SEEK_LARGE}s",
144
+ "[-] slower [+] faster [0] reset speed",
138
145
  "[m] mark [e] export",
139
146
  "[q] quit"
140
147
  ].each do |line|
@@ -172,6 +179,11 @@ module Tucue
172
179
  ("#" * filled) + ("-" * (PROGRESS_WIDTH - filled))
173
180
  end
174
181
 
182
+ # Format a speed multiplier compactly, e.g. 0.5x, 1x, 1.25x.
183
+ def format_speed(value)
184
+ "#{format("%g", value)}x"
185
+ end
186
+
175
187
  # Format seconds as HH:MM:SS.
176
188
  def format_time(seconds)
177
189
  return "--:--:--" if seconds.nil?
data/lib/tucue/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tucue
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tucue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - takkanm