Skip to content

feat[playback]: add per-section playback speed control#688

Open
0xjuanma wants to merge 5 commits intocharmbracelet:mainfrom
0xjuanma:feat/playback
Open

feat[playback]: add per-section playback speed control#688
0xjuanma wants to merge 5 commits intocharmbracelet:mainfrom
0xjuanma:feat/playback

Conversation

@0xjuanma
Copy link

@0xjuanma 0xjuanma commented Dec 9, 2025

  • I have read CONTRIBUTING.md.
  • I have created a discussion that was approved by a maintainer (for new features).

Summary

#685

Adds new playback speed control feature to VHS, allowing users to vary playback speed at different points in their recordings using the Playback@<speed> command. The value can be either an integer or float with 1 decimal place.

This enables speeding through setup sections while slowing down for important demonstrations, providing more control over the final output than the global Set PlaybackSpeed setting(which defines a single speed for the full GIF). Its effectively a way to set up multiple playback speeds as part of the tape file or commands being run.

To demonstrate this, I used one of my timer packages which makes it very easy to see the playback speed.

Output GIF:

TL;DR:
Stage 1 runs at 3x speed,
Stage 2 runs at 1x speed,
Stage 3 runs at 1x speed(for 10sec) then switches to 3x,
finally Stage 4 runs at 1x speed again.

helm-demo3

Here is the demo.tape used to generate the GIF above:

Output helm-demo.gif
Set FontSize 14
Set Width 800
Set Height 500
Set Theme "Darkside"

# Launch Helm(Note: helm is my timer TUI package)
Playback@1
Type "helm"
Enter
Sleep 1s

# Navigate down to show other options
Down
Sleep 500ms
Down
Sleep 500ms

# Pause on current selection
Sleep 500ms

# Select Demo timer
Enter
Sleep 1s

# Start stage(1)
Sleep 1s
Space

# Playback [Stage 1] at 3x speed
Playback@3.0
Sleep 50s

# Pause
Playback@1.0
Space
Sleep 1s

# Skip to next stage(2)
Type "n"
Sleep 1s

# Start [Stage 2] at 1x speed
Space
Playback@1.0
Sleep 30s

# Pause
Space
Sleep 1s

# Start [Stage 3] at 1x speed for 10sec
Type "n"
Space
Sleep 10s


# Update [Stage 3] Playback to 3x speed
Playback@3.0
Sleep 30s

Playback@1.0
# Pause
Space
Sleep 1s

# Skip to next [Stage 4] at 1x speed
Type "n"
Sleep 1s
Space
Sleep 20s

# End
Type "q"
Sleep 1s

Updates

  • Added Playback@<speed> command with @ syntax for section-based speed control(follows similar patterns a Type@Xms)
  • Implemented per-section playback speed rendering with FFmpeg filter chain
  • Added tests coverage for lexer, parser, and command execution
  • Documented playback command usage and added syntax highlighting

@0xjuanma 0xjuanma requested a review from a team as a code owner December 9, 2025 03:06
@0xjuanma 0xjuanma requested review from andreynering and meowgorithm and removed request for a team December 9, 2025 03:06
- [`Backspace`](#backspace) [`Enter`](#enter) [`Tab`](#tab) [`Space`](#space): special keys
- [`Ctrl[+Alt][+Shift]+<char>`](#ctrl): press control + key and/or modifier
- [`Sleep <time>`](#sleep): wait for a certain amount of time
- [`Playback@<speed>`](#playback): change playback speed for subsequent commands
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use the existing SET PlaybackSpeed inline like SET TypingSpeed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cwarden Great question! I wanted to leave the existing implementation as is, specially because "PlaybackSpeed" is a global setting.

This was a compromise on my part to ensure "PlaybackSpeed" remains global and the new "Playback@*" commands become anchors/markers for this section-base speed configuration.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't check for an existing pull request before adding the same feature, but reusing SET PlaybackSpeek. I don't feel that strongly about it, but making playback speed congruent with typing speed makes sense to me. There's an alternative implementation in 5b1c930 using this approach.

Copy link
Author

@0xjuanma 0xjuanma Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, as you pointed out I also went with the "Playback@" approach to try to follow what "TypingSpeed" and "Type@*" are currently doing.

I also don't have strong opinions about this, so I'll let the maintainers decide whats the better choice for this 👍🏽

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants