# How to Programmatically Control Video Playback with video-use

> Control video playback programmatically using video-use. Learn how to leverage path resolution and segment extraction to interface with standard media players and libraries.

- Repository: [Browser Use/video-use](https://github.com/browser-use/video-use)
- Tags: how-to-guide
- Published: 2026-07-10

---

**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`](https://github.com/browser-use/video-use/blob/main/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:

```python

# 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`](https://github.com/browser-use/video-use/blob/main/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:

```python
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_path`** ensures consistency with the rendering pipeline's path handling
- **`SIGSTOP`** pauses the process immediately without closing the file handle
- **`SIGCONT`** resumes playback from the exact frame where it paused
- **`ffplay`** is 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`](https://github.com/browser-use/video-use/blob/main/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`](https://github.com/browser-use/video-use/blob/main/helpers/render.py#L52-L70)

```python
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:

```python
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`](https://github.com/browser-use/video-use/blob/main/helpers/render.py)** — Contains `resolve_path` and `extract_segment` functions essential for path handling and segment extraction
- **[`helpers/transcribe.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe.py)** — Implements ElevenLabs Scribe integration for word-level JSON transcripts that define your edit points
- **[`helpers/timeline_view.py`](https://github.com/browser-use/video-use/blob/main/helpers/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_path`** from [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) to ensure path consistency with the rendering pipeline when loading videos for playback
- **Control ffplay via subprocess signals** (`SIGSTOP` for pause, `SIGCONT` for resume, `terminate()` for stop) to achieve programmatic playback management
- **Leverage `extract_segment`** to 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`](https://github.com/browser-use/video-use/blob/main/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.