CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-vlc

VLC bindings for Python providing comprehensive multimedia functionality through LibVLC API.

Pending
Overview
Eval results
Files

discovery-renderers.mddocs/

Media Discovery and Renderers

Network media discovery, renderer discovery for casting, and media library management capabilities. These features enable building applications that can discover network media sources and cast to remote devices.

Capabilities

Media Discovery

The MediaDiscoverer class provides network media discovery capabilities for finding media sources on the network.

class MediaDiscoverer:
    def __init__(self, instance, service_name):
        """Create a media discoverer.
        
        Args:
            instance (Instance): VLC instance
            service_name (str): Name of discovery service
        """
        ...
    
    def start(self):
        """Start the media discovery service.
        
        Returns:
            int: 0 on success, -1 on error
        """
        ...
    
    def stop(self):
        """Stop the media discovery service."""
        ...
    
    def media_list(self):
        """Get the media list discovered by this service.
        
        Returns:
            MediaList: List of discovered media items
        """
        ...
    
    def event_manager(self):
        """Get the event manager for this media discoverer.
        
        Returns:
            EventManager: Event manager for discovery events
        """
        ...
    
    def is_running(self):
        """Check if the discoverer is currently running.
        
        Returns:
            bool: True if running, False otherwise
        """
        ...
    
    def release(self):
        """Release the media discoverer."""
        ...

Media Discovery Services

Static methods for enumerating available discovery services.

@staticmethod
def media_discoverer_list_get(instance, category):
    """Get list of available media discovery services.
    
    Args:
        instance (Instance): VLC instance
        category (MediaDiscovererCategory): Category of services to list
        
    Returns:
        list: List of (service_name, long_name) tuples
    """
    ...

@staticmethod  
def media_discoverer_list_release(services_list):
    """Release a media discoverer services list.
    
    Args:
        services_list (list): List returned by media_discoverer_list_get
    """
    ...

Renderer Discovery

The RendererDiscoverer class provides discovery of renderers (casting targets) on the network.

class RendererDiscoverer:
    def __init__(self, instance, service_name):
        """Create a renderer discoverer.
        
        Args:
            instance (Instance): VLC instance
            service_name (str): Name of renderer discovery service
        """
        ...
    
    def start(self):
        """Start the renderer discovery service.
        
        Returns:
            int: 0 on success, -1 on error
        """
        ...
    
    def stop(self):
        """Stop the renderer discovery service."""
        ...
    
    def event_manager(self):
        """Get the event manager for this renderer discoverer.
        
        Returns:
            EventManager: Event manager for renderer events
        """
        ...
    
    def release(self):
        """Release the renderer discoverer."""
        ...

Renderer Management

The Renderer class represents discovered casting targets.

class Renderer:
    def name(self):
        """Get the renderer name.
        
        Returns:
            str: Human-readable name of the renderer
        """
        ...
    
    def type(self):
        """Get the renderer type.
        
        Returns:
            str: Type of renderer (e.g., "chromecast", "upnp")
        """
        ...
    
    def icon_uri(self):
        """Get the renderer icon URI.
        
        Returns:
            str: URI to renderer icon or None
        """
        ...
    
    def flags(self):
        """Get renderer capability flags.
        
        Returns:
            int: Bitfield of renderer capabilities
        """
        ...
    
    def can_render_audio(self):
        """Check if renderer can handle audio.
        
        Note: Not directly available - check flags() & RendererFlags.Audio
        
        Returns:
            bool: True if can render audio
        """
        return (self.flags() & vlc.RendererFlags.Audio) != 0
    
    def can_render_video(self):
        """Check if renderer can handle video.
        
        Note: Not directly available - check flags() & RendererFlags.Video
        
        Returns:
            bool: True if can render video
        """
        return (self.flags() & vlc.RendererFlags.Video) != 0
    
    def hold(self):
        """Hold a reference to this renderer.
        
        Returns:
            Renderer: This renderer instance
        """
        ...
    
    def release(self):
        """Release this renderer."""
        ...

Renderer Discovery Services

Static methods for managing renderer discovery services.

@staticmethod
def renderer_discoverer_list_get(instance):
    """Get list of available renderer discovery services.
    
    Args:
        instance (Instance): VLC instance
        
    Returns:
        list: List of (service_name, long_name) tuples
    """
    ...

@staticmethod
def renderer_discoverer_list_release(services_list):
    """Release a renderer discoverer services list.
    
    Args:
        services_list (list): List returned by renderer_discoverer_list_get
    """
    ...

Media Player Renderer Integration

Methods on MediaPlayer for using discovered renderers.

# Renderer methods on MediaPlayer
def set_renderer(self, renderer):
    """Set a renderer for casting output.
    
    Args:
        renderer (Renderer): Renderer to cast to, or None to stop casting
        
    Returns:
        int: 0 on success, -1 on error
    """
    ...

Discovery Categories

Enumeration for media discovery service categories.

class MediaDiscovererCategory:
    """Media discovery service categories."""
    Devices = 0
    Lan = 1
    Podcasts = 2
    LocalDirs = 3

Discovery Event Types

Event types for discovery operations.

class EventType:
    # Media Discoverer Events
    MediaDiscovererStarted = 0x500
    MediaDiscovererEnded = 0x501
    
    # Renderer Discoverer Events  
    RendererDiscovererItemAdded = 0x700
    RendererDiscovererItemDeleted = 0x701

Renderer Flags

Capability flags for renderers.

class RendererFlags:
    """Renderer capability flags."""
    Audio = 0x01
    Video = 0x02
    
# Usage: Check renderer capabilities with bitwise operations
# has_audio = (renderer.flags() & vlc.RendererFlags.Audio) != 0
# has_video = (renderer.flags() & vlc.RendererFlags.Video) != 0

Usage Examples

Media Discovery Basic Usage

import vlc
import time

def on_discoverer_started(event):
    print("Media discoverer started")

def on_discoverer_ended(event):
    print("Media discoverer ended")

# Create instance and list available discovery services
instance = vlc.Instance()
services = vlc.MediaDiscoverer.media_discoverer_list_get(
    instance, vlc.MediaDiscovererCategory.Lan
)

print("Available LAN discovery services:")
for service_name, long_name in services:
    print(f"  {service_name}: {long_name}")

if services:
    # Create discoverer for first service
    service_name = services[0][0]
    discoverer = vlc.MediaDiscoverer(instance, service_name)
    
    # Attach events
    em = discoverer.event_manager()
    em.event_attach(vlc.EventType.MediaDiscovererStarted, on_discoverer_started)
    em.event_attach(vlc.EventType.MediaDiscovererEnded, on_discoverer_ended)
    
    # Start discovery
    print(f"Starting discovery with service: {service_name}")
    discoverer.start()
    
    # Wait for discovery
    time.sleep(5)
    
    # Get discovered media
    media_list = discoverer.media_list()
    if media_list:
        count = media_list.count()
        print(f"Discovered {count} media items:")
        
        for i in range(count):
            media = media_list.item_at_index(i)
            if media:
                mrl = media.get_mrl()
                print(f"  {i}: {mrl}")
    
    # Stop discovery
    discoverer.stop()
    discoverer.release()

# Clean up
vlc.MediaDiscoverer.media_discoverer_list_release(services)

Comprehensive Media Discovery

import vlc
import time

class MediaDiscoveryManager:
    def __init__(self, instance):
        self.instance = instance
        self.discoverers = []
        self.discovered_media = {}
    
    def discover_all_categories(self):
        """Start discovery for all available categories."""
        categories = [
            vlc.MediaDiscovererCategory.Devices,
            vlc.MediaDiscovererCategory.Lan, 
            vlc.MediaDiscovererCategory.Podcasts,
            vlc.MediaDiscovererCategory.LocalDirs
        ]
        
        category_names = ["Devices", "LAN", "Podcasts", "Local Directories"]
        
        for category, name in zip(categories, category_names):
            print(f"\n=== {name} Discovery ===")
            services = vlc.MediaDiscoverer.media_discoverer_list_get(
                self.instance, category
            )
            
            if not services:
                print(f"No {name.lower()} discovery services available")
                continue
            
            for service_name, long_name in services:
                print(f"Starting {service_name}: {long_name}")
                
                try:
                    discoverer = vlc.MediaDiscoverer(self.instance, service_name)
                    em = discoverer.event_manager()
                    
                    # Setup events with service context
                    em.event_attach(
                        vlc.EventType.MediaDiscovererStarted,
                        lambda e, sn=service_name: self.on_started(e, sn)
                    )
                    em.event_attach(
                        vlc.EventType.MediaDiscovererEnded,
                        lambda e, sn=service_name: self.on_ended(e, sn)
                    )
                    
                    discoverer.start()
                    self.discoverers.append((service_name, discoverer))
                    
                except Exception as e:
                    print(f"Failed to start {service_name}: {e}")
            
            vlc.MediaDiscoverer.media_discoverer_list_release(services)
    
    def on_started(self, event, service_name):
        print(f"✓ {service_name} discovery started")
    
    def on_ended(self, event, service_name):
        print(f"✗ {service_name} discovery ended")
    
    def collect_discovered_media(self):
        """Collect all discovered media from active discoverers."""
        print("\n=== Discovered Media ===")
        
        for service_name, discoverer in self.discoverers:
            if discoverer.is_running():
                media_list = discoverer.media_list()
                if media_list:
                    count = media_list.count()
                    if count > 0:
                        print(f"\n{service_name} ({count} items):")
                        items = []
                        
                        for i in range(count):
                            media = media_list.item_at_index(i)
                            if media:
                                mrl = media.get_mrl()
                                items.append(mrl)
                                print(f"  {i+1}: {mrl}")
                        
                        self.discovered_media[service_name] = items
    
    def stop_all(self):
        """Stop all discoverers."""
        print("\nStopping all discoverers...")
        for service_name, discoverer in self.discoverers:
            discoverer.stop()
            discoverer.release()
        self.discoverers.clear()

# Usage
instance = vlc.Instance()
manager = MediaDiscoveryManager(instance)

# Start discovery for all categories
manager.discover_all_categories()

# Wait for discovery
print("\nWaiting for discovery to complete...")
time.sleep(10)

# Collect results
manager.collect_discovered_media()

# Stop all discoverers
manager.stop_all()

# Summary
print(f"\nDiscovered media in {len(manager.discovered_media)} services:")
for service, items in manager.discovered_media.items():
    print(f"  {service}: {len(items)} items")

Renderer Discovery and Casting

import vlc
import time

def on_renderer_added(event):
    """Handle renderer discovered."""
    renderer = event.u.item
    print(f"✓ Renderer discovered: {renderer.name()} ({renderer.type()})")

def on_renderer_deleted(event):
    """Handle renderer removed."""
    renderer = event.u.item  
    print(f"✗ Renderer removed: {renderer.name()}")

# Create instance and list renderer discovery services
instance = vlc.Instance()
services = vlc.RendererDiscoverer.renderer_discoverer_list_get(instance)

print("Available renderer discovery services:")
for service_name, long_name in services:
    print(f"  {service_name}: {long_name}")

discovered_renderers = []

if services:
    # Start discovery for all renderer services
    discoverers = []
    
    for service_name, long_name in services:
        try:
            print(f"Starting {service_name} renderer discovery...")
            rd = vlc.RendererDiscoverer(instance, service_name)
            
            # Attach events
            em = rd.event_manager()
            em.event_attach(vlc.EventType.RendererDiscovererItemAdded, on_renderer_added)
            em.event_attach(vlc.EventType.RendererDiscovererItemDeleted, on_renderer_deleted)
            
            rd.start()
            discoverers.append(rd)
            
        except Exception as e:
            print(f"Failed to start {service_name}: {e}")
    
    # Wait for renderer discovery
    print("\nDiscovering renderers...")
    time.sleep(10)
    
    # Create a media player for casting test
    player = vlc.MediaPlayer('/path/to/video.mp4')
    
    # Example: Cast to first discovered renderer (if any)
    # Note: This is conceptual - actual renderer objects would come from events
    print("\nTesting casting (conceptual example):")
    print("To cast to a renderer, you would:")
    print("1. Get renderer from discovery events")
    print("2. Use player.set_renderer(renderer)")
    print("3. Start playback with player.play()")
    
    # Stop all discoverers
    print("\nStopping renderer discovery...")
    for rd in discoverers:
        rd.stop()
        rd.release()

# Clean up
vlc.RendererDiscoverer.renderer_discoverer_list_release(services)

Advanced Renderer Discovery with Event Handling

import vlc
import time

class RendererManager:
    def __init__(self, instance):
        self.instance = instance
        self.discoverers = []
        self.available_renderers = {}
        
    def start_discovery(self):
        """Start discovery for all available renderer services."""
        services = vlc.RendererDiscoverer.renderer_discoverer_list_get(self.instance)
        
        print("Starting renderer discovery...")
        for service_name, long_name in services:
            try:
                rd = vlc.RendererDiscoverer(self.instance, service_name)
                em = rd.event_manager()
                
                # Bind events with service context
                em.event_attach(
                    vlc.EventType.RendererDiscovererItemAdded,
                    lambda e, sn=service_name: self.on_renderer_added(e, sn)
                )
                em.event_attach(
                    vlc.EventType.RendererDiscovererItemDeleted,
                    lambda e, sn=service_name: self.on_renderer_deleted(e, sn)
                )
                
                rd.start()
                self.discoverers.append((service_name, rd))
                print(f"  Started {service_name}: {long_name}")
                
            except Exception as e:
                print(f"  Failed to start {service_name}: {e}")
        
        vlc.RendererDiscoverer.renderer_discoverer_list_release(services)
    
    def on_renderer_added(self, event, service_name):
        """Handle renderer discovered."""
        renderer = event.u.item
        renderer_id = f"{service_name}:{renderer.name()}"
        
        # Store renderer info  
        flags = renderer.flags()
        self.available_renderers[renderer_id] = {
            'name': renderer.name(),
            'type': renderer.type(),
            'service': service_name,
            'can_audio': (flags & vlc.RendererFlags.Audio) != 0,
            'can_video': (flags & vlc.RendererFlags.Video) != 0,
            'icon_uri': renderer.icon_uri(),
            'renderer_obj': renderer.hold()  # Keep reference
        }
        
        print(f"📺 Found renderer: {renderer.name()}")
        print(f"   Type: {renderer.type()}")
        print(f"   Audio: {'✓' if (flags & vlc.RendererFlags.Audio) else '✗'}")
        print(f"   Video: {'✓' if (flags & vlc.RendererFlags.Video) else '✗'}")
        if renderer.icon_uri():
            print(f"   Icon: {renderer.icon_uri()}")
    
    def on_renderer_deleted(self, event, service_name):
        """Handle renderer removed."""
        renderer = event.u.item
        renderer_id = f"{service_name}:{renderer.name()}"
        
        if renderer_id in self.available_renderers:
            # Release held reference
            self.available_renderers[renderer_id]['renderer_obj'].release()
            del self.available_renderers[renderer_id]
            print(f"📺 Renderer removed: {renderer.name()}")
    
    def list_renderers(self):
        """List all currently available renderers."""
        print(f"\nAvailable renderers ({len(self.available_renderers)}):")
        for renderer_id, info in self.available_renderers.items():
            print(f"  {renderer_id}")
            print(f"    Type: {info['type']}")
            print(f"    Capabilities: Audio={info['can_audio']}, Video={info['can_video']}")
    
    def cast_to_renderer(self, renderer_id, media_path):
        """Cast media to a specific renderer."""
        if renderer_id not in self.available_renderers:
            print(f"Renderer {renderer_id} not available")
            return None
        
        info = self.available_renderers[renderer_id]
        renderer_obj = info['renderer_obj']
        
        print(f"Casting to {info['name']}...")
        
        # Create player and set renderer
        player = vlc.MediaPlayer(media_path)
        result = player.set_renderer(renderer_obj)
        
        if result == 0:
            print("✓ Renderer set successfully")
            player.play()
            return player
        else:
            print("✗ Failed to set renderer")
            return None
    
    def stop_discovery(self):
        """Stop all renderer discovery."""
        print("Stopping renderer discovery...")
        
        # Release all held renderer references
        for info in self.available_renderers.values():
            info['renderer_obj'].release()
        self.available_renderers.clear()
        
        # Stop and release discoverers
        for service_name, rd in self.discoverers:
            rd.stop()
            rd.release()
        self.discoverers.clear()

# Usage example
instance = vlc.Instance()
renderer_mgr = RendererManager(instance)

# Start discovery
renderer_mgr.start_discovery()

# Wait for discovery
print("Waiting for renderer discovery...")
time.sleep(15)

# List found renderers
renderer_mgr.list_renderers()

# Example casting (if renderers found)
if renderer_mgr.available_renderers:
    first_renderer = list(renderer_mgr.available_renderers.keys())[0]
    print(f"\nAttempting to cast to: {first_renderer}")
    
    # Cast to first available renderer
    player = renderer_mgr.cast_to_renderer(first_renderer, '/path/to/video.mp4')
    
    if player:
        print("Casting for 10 seconds...")
        time.sleep(10)
        player.stop()
        
        # Stop casting by clearing renderer
        player.set_renderer(None)
        print("Stopped casting")

# Clean up
renderer_mgr.stop_discovery()

Media Discovery with Playback

import vlc
import time

# Discover and play network media
instance = vlc.Instance()

# Get UPnP discovery service
services = vlc.MediaDiscoverer.media_discoverer_list_get(
    instance, vlc.MediaDiscovererCategory.Lan
)

upnp_service = None
for service_name, long_name in services:
    if 'upnp' in service_name.lower():
        upnp_service = service_name
        break

if upnp_service:
    print(f"Using UPnP discovery service: {upnp_service}")
    
    # Create discoverer
    discoverer = vlc.MediaDiscoverer(instance, upnp_service)
    discoverer.start()
    
    # Wait for discovery
    print("Discovering UPnP media servers...")
    time.sleep(8)
    
    # Get discovered media
    media_list = discoverer.media_list()
    if media_list and media_list.count() > 0:
        print(f"Found {media_list.count()} UPnP media sources")
        
        # Play first discovered media
        first_media = media_list.item_at_index(0)
        if first_media:
            print(f"Playing: {first_media.get_mrl()}")
            
            player = vlc.MediaPlayer()
            player.set_media(first_media)
            player.play()
            
            # Play for a while
            time.sleep(30)
            player.stop()
    else:
        print("No UPnP media servers found")
    
    # Clean up
    discoverer.stop()
    discoverer.release()
else:
    print("No UPnP discovery service available")

vlc.MediaDiscoverer.media_discoverer_list_release(services)

Install with Tessl CLI

npx tessl i tessl/pypi-python-vlc

docs

audio-control.md

core-playback.md

data-structures.md

discovery-renderers.md

event-system.md

index.md

low-level-functions.md

media-lists.md

video-control.md

tile.json