CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-mpv

A python interface to the mpv media player

Pending
Overview
Eval results
Files

playlist-media.mddocs/

Playlist and Media Loading

Comprehensive playlist management, file loading with options, and track selection for audio, video, and subtitle tracks. Supports local files, URLs, streaming sources, and advanced track management.

Capabilities

File Loading

Load individual media files with various modes and options.

def loadfile(self, filename: str, mode: str = 'replace', index: int = None, **options):
    """
    Load a media file into the player.

    Parameters:
    - filename: Path to file or URL to load
    - mode: Loading mode ('replace', 'append', 'append-play')
    - index: Playlist position for insertion (for append modes)
    - options: Additional options as key-value pairs

    Loading modes:
    - 'replace': Replace current playlist with this file
    - 'append': Add to end of playlist
    - 'append-play': Add to playlist and play immediately
    """

def loadlist(self, playlist: str, mode: str = 'replace'):
    """
    Load a playlist file.

    Parameters:
    - playlist: Path to playlist file (.m3u, .pls, etc.)
    - mode: Loading mode ('replace', 'append', 'append-play')
    """

Playlist Management

Complete playlist control including navigation, modification, and organization.

def playlist_append(self, filename: str, **options):
    """
    Append a file to the current playlist.

    Parameters:
    - filename: File path or URL to append
    - options: File-specific options
    """

def playlist_next(self, mode: str = 'weak'):
    """
    Move to next playlist entry.

    Parameters:
    - mode: Transition mode ('weak', 'force')
           'weak': Only if current file is not playing
           'force': Always move to next entry
    """

def playlist_prev(self, mode: str = 'weak'):
    """
    Move to previous playlist entry.

    Parameters:
    - mode: Transition mode ('weak', 'force')
    """

def playlist_play_index(self, idx: int):
    """
    Play playlist entry at specific index.

    Parameters:
    - idx: Playlist index (0-based)
    """

def playlist_clear(self):
    """Clear the entire playlist."""

def playlist_remove(self, index: str = 'current'):
    """
    Remove entry from playlist.

    Parameters:
    - index: Index to remove ('current' or numeric index)
    """

def playlist_move(self, index1: int, index2: int):
    """
    Move playlist entry from one position to another.

    Parameters:
    - index1: Source index
    - index2: Destination index
    """

def playlist_shuffle(self):
    """Shuffle the playlist randomly."""

def playlist_unshuffle(self):
    """Restore original playlist order."""

@property
def playlist_filenames(self) -> list:
    """List of filenames in the current playlist."""

Audio Track Management

Add, remove, and control audio tracks during playback.

def audio_add(self, url: str, flags: str = 'select', title: str = None, lang: str = None):
    """
    Add an audio track.

    Parameters:
    - url: Path or URL to audio file
    - flags: Selection flags ('select', 'auto', 'cached')
    - title: Custom track title
    - lang: Language code for the track
    """

def audio_remove(self, audio_id: int = None):
    """
    Remove an audio track.

    Parameters:
    - audio_id: Track ID to remove (None for current)
    """

def audio_reload(self, audio_id: int = None):
    """
    Reload an audio track.

    Parameters:
    - audio_id: Track ID to reload (None for current)
    """

Video Track Management

Add, remove, and control video tracks including album art.

def video_add(self, url: str, flags: str = 'select', title: str = None, lang: str = None, albumart: bool = None):
    """
    Add a video track.

    Parameters:
    - url: Path or URL to video file
    - flags: Selection flags ('select', 'auto', 'cached')
    - title: Custom track title
    - lang: Language code for the track
    - albumart: Whether track is album art
    """

def video_remove(self, video_id: int = None):
    """
    Remove a video track.

    Parameters:
    - video_id: Track ID to remove (None for current)
    """

def video_reload(self, video_id: int = None):
    """
    Reload a video track.

    Parameters:
    - video_id: Track ID to reload (None for current)
    """

Subtitle Management

Comprehensive subtitle track control including timing and positioning.

def sub_add(self, url: str, flags: str = 'select', title: str = None, lang: str = None):
    """
    Add a subtitle track.

    Parameters:
    - url: Path or URL to subtitle file
    - flags: Selection flags ('select', 'auto', 'cached')
    - title: Custom track title
    - lang: Language code for the track
    """

def sub_remove(self, sub_id: int = None):
    """
    Remove a subtitle track.

    Parameters:
    - sub_id: Track ID to remove (None for current)
    """

def sub_reload(self, sub_id: int = None):
    """
    Reload a subtitle track.

    Parameters:
    - sub_id: Track ID to reload (None for current)
    """

def sub_step(self, skip: int):
    """
    Step through subtitle entries.

    Parameters:
    - skip: Number of subtitle entries to skip (positive or negative)
    """

def sub_seek(self, skip: int):
    """
    Seek to next/previous subtitle.

    Parameters:
    - skip: Direction and count (1 for next, -1 for previous)
    """

Playlist Properties

# Playlist information
playlist_count: int          # Number of entries in playlist
playlist_pos: int           # Current playlist position (0-based)
playlist_pos_1: int         # Current playlist position (1-based)

# Playlist behavior
loop_playlist: str          # Playlist looping ('no', 'inf', 'force')
shuffle: bool              # Playlist shuffle state

# Track information
track_list: list           # List of all available tracks
audio_id: int             # Current audio track ID
video_id: int             # Current video track ID
sub_id: int               # Current subtitle track ID

Usage Examples

Basic Playlist Operations

import mpv

player = mpv.MPV()

# Load single file
player.loadfile('/path/to/video1.mp4')

# Append files to playlist
player.playlist_append('/path/to/video2.mp4')
player.playlist_append('/path/to/video3.mp4')

# Load entire playlist file
player.loadlist('/path/to/playlist.m3u')

# Navigate playlist
player.playlist_next()      # Next video
player.playlist_prev()      # Previous video
player.playlist_play_index(0)  # Jump to first video

# Playlist information
print(f"Playlist has {player.playlist_count} entries")
print(f"Currently playing: {player.playlist_pos}")
print(f"Files: {player.playlist_filenames}")

Advanced File Loading

# Load with specific options
player.loadfile('/path/to/video.mp4', 
                start=30,           # Start at 30 seconds
                end=120,            # Stop at 2 minutes
                volume=75,          # Set volume
                loop_file='inf')    # Loop this file

# Load and append with play
player.loadfile('/path/to/first.mp4', mode='replace')
player.loadfile('/path/to/second.mp4', mode='append-play')

# Insert at specific position
player.loadfile('/path/to/insert.mp4', mode='append', index=1)

Track Management

# Add external audio track
player.audio_add('/path/to/commentary.mp3', 
                 title='Director Commentary',
                 lang='en')

# Add subtitle file
player.sub_add('/path/to/subtitles.srt',
               title='English Subtitles',
               lang='en')

# Add video track (for videos with multiple angles)
player.video_add('/path/to/angle2.mp4',
                 title='Camera Angle 2')

# Get track information
tracks = player.track_list
for track in tracks:
    print(f"Track {track['id']}: {track['type']} - {track.get('title', 'Untitled')}")

# Switch tracks
player.audio_id = 2  # Switch to audio track 2
player.sub_id = 1    # Switch to subtitle track 1

Playlist Manipulation

# Create and manage playlist
files = [
    '/path/to/episode1.mp4',
    '/path/to/episode2.mp4', 
    '/path/to/episode3.mp4'
]

# Add all files
for i, file in enumerate(files):
    if i == 0:
        player.loadfile(file, mode='replace')
    else:
        player.playlist_append(file)

# Shuffle and loop
player.shuffle = True
player.loop_playlist = 'inf'

# Remove specific entries
player.playlist_remove(1)  # Remove second entry
player.playlist_remove('current')  # Remove current entry

# Reorder playlist
player.playlist_move(0, 2)  # Move first to third position

Streaming and URLs

# Stream from URL
player.play('https://example.com/stream.m3u8')

# YouTube with youtube-dl integration (if available)
player.play('https://www.youtube.com/watch?v=dQw4w9WgXcQ')

# Add external tracks for streams
player.sub_add('https://example.com/subtitles.vtt')
player.audio_add('https://example.com/alternate_audio.mp3')

# Radio streams
player.play('http://stream.example.com:8000/radio')

Subtitle Control

# Add and configure subtitles
player.sub_add('/path/to/subtitles.srt')

# Subtitle timing and appearance
player.sub_delay = 0.5      # Delay by 500ms
player.sub_scale = 1.2      # Increase size by 20%
player.sub_pos = 90         # Position at 90% from top

# Navigate through subtitles
player.sub_step(1)          # Next subtitle
player.sub_step(-1)         # Previous subtitle
player.sub_seek(1)          # Seek to next subtitle timing

# Toggle subtitle visibility
player.sub_visibility = False

Playlist Events and Monitoring

# Monitor playlist changes
@player.property_observer('playlist-pos')
def playlist_changed(name, value):
    if value is not None:
        current_file = player.playlist_filenames[value]
        print(f"Now playing: {current_file}")

@player.property_observer('playlist-count')
def playlist_size_changed(name, value):
    print(f"Playlist now has {value} entries")

# Handle end of playlist
@player.event_callback('end-file')
def handle_file_end(event):
    if player.playlist_pos == player.playlist_count - 1:
        print("Reached end of playlist")

# Auto-play next with custom logic
@player.event_callback('end-file')
def auto_advance(event):
    if event.data == mpv.MpvEventEndFile.EOF:
        if player.playlist_pos < player.playlist_count - 1:
            player.playlist_next('force')
        else:
            print("Playlist completed")

Complex Playlist Scenarios

# Multi-format playlist with options
playlist_items = [
    ('/path/to/intro.mp4', {'volume': 100}),
    ('/path/to/main.mkv', {'audio-delay': 0.2}),
    ('/path/to/credits.mp4', {'speed': 1.5})
]

# Load with per-file options
for i, (filename, options) in enumerate(playlist_items):
    if i == 0:
        player.loadfile(filename, **options)
    else:
        player.playlist_append(filename, **options)

# Dynamic playlist modification
def add_related_content():
    current_file = player.filename
    if 'episode' in current_file:
        # Add next episode automatically
        next_episode = current_file.replace('episode1', 'episode2')
        if os.path.exists(next_episode):
            player.playlist_append(next_episode)

# Monitor for automatic playlist expansion
@player.property_observer('playlist-pos')
def auto_expand_playlist(name, value):
    if value == player.playlist_count - 2:  # Near end of playlist
        add_related_content()

Install with Tessl CLI

npx tessl i tessl/pypi-mpv@1.0.2

docs

advanced-rendering.md

core-playback.md

event-handling.md

index.md

input-keybinding.md

playlist-media.md

property-management.md

screenshots-overlays.md

streaming.md

tile.json