How to Programmatically Control Video Playback with video-use
video-use does not provide a native playback API; instead, you programmatically control video playback by leveraging the toolkit's path resolution and segment extraction utilities to interface with standard media players like ffplay or Python video libraries.
video-use is a conversation-driven video editing toolkit that transforms raw footage into polished edits through transcription, EDL generation, and FFmpeg rendering. While the repository excels at automated editing workflows in browser-use/video-use, it deliberately delegates video playback to external tools rather than implementing its own player. This architecture allows developers to programmatically control playback using standard subprocess management or Python video libraries while maintaining compatibility with the video-use pipeline.
Locating Source Video Paths with resolve_path
Before controlling playback, you must resolve video paths exactly as the video-use pipeline does. The resolve_path function in helpers/render.py standardizes path handling, supporting both absolute and relative paths relative to your working directory.
This function ensures that the same path resolution logic used during rendering applies to your playback commands:
# helpers/render.py
def resolve_path(maybe_path: str, base: Path) -> Path:
"""Resolve a path that may be absolute or relative to `base`."""
p = Path(maybe_path)
if p.is_absolute():
return p
return (base / p).resolve()
Source: helpers/render.py#L87-L92
Controlling Video Playback with ffplay
Since video-use requires FFmpeg for rendering, you can use the bundled ffplay utility for programmatic playback. Launch ffplay via subprocess.Popen to obtain a process handle that supports pause, resume, and termination signals.
The following pattern opens a video non-blocking, allowing you to control playback through Unix signals:
import subprocess
from pathlib import Path
from helpers.render import resolve_path
def play_video(video_path: str, base_dir: Path = Path.cwd()) -> subprocess.Popen:
"""
Open a video with ffplay. Returns a Popen object so you can
control playback (pause, resume, terminate).
"""
full_path = resolve_path(video_path, base_dir)
# -autoexit makes ffplay quit when the file ends
cmd = ["ffplay", "-autoexit", "-nodisp", str(full_path)]
proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
return proc
# Example usage
player = play_video("raw/intro.mp4")
# Control playback programmatically
player.send_signal(subprocess.signal.SIGSTOP) # pause
player.send_signal(subprocess.signal.SIGCONT) # resume
player.terminate() # stop playback
Key implementation details:
resolve_pathensures consistency with the rendering pipeline's path handlingSIGSTOPpauses the process immediately without closing the file handleSIGCONTresumes playback from the exact frame where it pausedffplayis included with standard FFmpeg installations required by video-use
Previewing Specific Segments Without Re-encoding
To preview specific edit points defined in your EDL, use the extract_segment function from helpers/render.py. This utility extracts precise time ranges using FFmpeg, creating temporary files that you can feed directly into your playback pipeline.
Source: helpers/render.py#L52-L70
from helpers.render import extract_segment, resolve_path
from pathlib import Path
def preview_segment(source: str, start: float, duration: float,
grade: str = "") -> subprocess.Popen:
"""
Extract a segment and play it immediately without re-encoding the full source.
"""
src_path = resolve_path(source, Path.cwd())
out_path = Path("tmp") / f"{Path(source).stem}_preview.mp4"
# Extract the segment (grade_filter can be empty or an FFmpeg preset)
extract_segment(
source=src_path,
seg_start=start,
duration=duration,
grade_filter=grade,
out_path=out_path,
preview=True,
draft=False,
)
# Play the extracted clip
return subprocess.Popen(["ffplay", "-autoexit", str(out_path)])
# Example: Play 5-second segment starting at 12 seconds
player = preview_segment("raw/scene1.mp4", start=12.0, duration=5.0)
This approach lets you verify edit decisions before rendering the final composition, using the same segment logic that powers the main rendering pipeline.
Alternative: Fine-Grained Control with moviepy
For applications requiring frame-level control or GUI integration, combine video-use's path resolution with moviepy. This Python library lets you preview segments within your application without spawning external processes:
from moviepy.editor import VideoFileClip
from helpers.render import resolve_path
def play_with_moviepy(video_path: str, start: float = 0.0,
end: float | None = None):
"""Play video using moviepy for embedded preview windows."""
resolved = str(resolve_path(video_path, Path.cwd()))
clip = VideoFileClip(resolved).subclip(start, end)
clip.preview() # Opens interactive window; close to stop
clip.close()
# Play from 30 seconds to end
play_with_moviepy("raw/tutorial.mp4", start=30.0)
Install moviepy via pip install moviepy to use this alternative playback method.
Key Source Files for Playback Integration
Understanding these core files helps you extend video-use's functionality:
helpers/render.py— Containsresolve_pathandextract_segmentfunctions essential for path handling and segment extractionhelpers/transcribe.py— Implements ElevenLabs Scribe integration for word-level JSON transcripts that define your edit pointshelpers/timeline_view.py— Generates composite PNGs (filmstrip + waveform) for visual timeline references during playback
Summary
- video-use delegates playback to standard FFmpeg-based tools rather than implementing a native player, requiring external tools like ffplay or Python libraries
- Use
resolve_pathfromhelpers/render.pyto ensure path consistency with the rendering pipeline when loading videos for playback - Control ffplay via subprocess signals (
SIGSTOPfor pause,SIGCONTfor resume,terminate()for stop) to achieve programmatic playback management - Leverage
extract_segmentto preview specific EDL-defined time ranges without re-encoding full source files - Implement moviepy when you need embedded Python playback with frame-accurate seeking and GUI integration
Frequently Asked Questions
Does video-use include a built-in video player?
No, video-use does not implement a dedicated playback API. According to the source code in browser-use/video-use, the toolkit focuses exclusively on conversation-driven editing workflows including transcription, EDL generation, and FFmpeg rendering. Playback is delegated to external tools like ffplay, mpv, or Python video libraries that you control programmatically using standard subprocess management.
How do I pause and resume video playback programmatically?
When using ffplay via subprocess.Popen, send Unix signals to the process object: SIGSTOP pauses playback immediately while maintaining the file handle, and SIGCONT resumes from the exact frame where playback stopped. For Windows compatibility, consider using psutil to suspend and resume processes, or switch to moviepy which provides higher-level playback control through Python function calls.
Can I preview specific time segments without rendering the full video?
Yes, use the extract_segment function defined in helpers/render.py (lines 52-70) to extract precise time ranges using FFmpeg. This function creates a temporary file containing only your specified segment, which you can then feed into ffplay or any player. This approach lets you verify edit decisions defined in your EDL before committing to final rendering.
What dependencies do I need for video playback control?
You need FFmpeg (which video-use already requires for rendering) to access the ffplay utility. For the Python-based approaches, ensure you have subprocess and pathlib available in your standard library. Optional dependencies include moviepy (pip install moviepy) for embedded preview windows, and psutil for advanced process management on Windows systems where Unix signals are not available.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →