### Load and Unload PulseAudio Modules Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Shows how to list, load, and unload PulseAudio modules dynamically. Includes examples for loading null sinks, modules with argument lists, loopback modules, and error handling for non-existent modules. Requires root or appropriate permissions to load modules. ```python import pulsectl with pulsectl.Pulse('module-manager') as pulse: # List loaded modules modules = pulse.module_list() for mod in modules: print(f"Module {mod.index}: {mod.name}") print(f" Arguments: {mod.argument}") print(f" Used by: {mod.n_used}") # Get specific module info module = pulse.module_info(5) print(f"Module 5: {module.name}") # Load a null sink (virtual output device) null_sink_idx = pulse.module_load( 'module-null-sink', 'sink_name=virtual_speaker sink_properties=device.description=VirtualSpeaker' ) print(f"Loaded null sink module at index {null_sink_idx}") # Load module with argument list args = ['sink_name=my_sink', 'rate=48000', 'channels=2'] idx = pulse.module_load('module-null-sink', args) # Load loopback module (route audio between source and sink) loopback_idx = pulse.module_load( 'module-loopback', 'source=alsa_input.pci-0000_00_1f.3.analog-stereo sink=my_sink latency_msec=50' ) # Unload module pulse.module_unload(null_sink_idx) print("Module unloaded") # Error handling for module load try: pulse.module_load('module-nonexistent') except pulsectl.PulseError as e: print(f"Failed to load module: {e}") ``` -------------------------------- ### Interactive PulseAudio Tinkering Source: https://github.com/mk-fg/python-pulse-control/blob/master/README.rst Examples of querying sinks, inputs, sources, and modifying card profiles via the Python REPL. ```python >>> import pulsectl >>> pulse = pulsectl.Pulse('my-client-name') >>> pulse.sink_list() [] >>> pulse.sink_input_list() [] >>> pulse.sink_input_list()[0].proplist {'application.icon_name': 'mpv', 'application.language': 'C', 'application.name': 'mpv Media Player', ... 'native-protocol.version': '30', 'window.x11.display': ':1.0'} >>> pulse.source_list() [, ] >>> sink = pulse.sink_list()[0] >>> pulse.volume_change_all_chans(sink, -0.1) >>> pulse.volume_set_all_chans(sink, 0.5) >>> pulse.server_info().default_sink_name 'alsa_output.pci-0000_00_14.2.analog-stereo' >>> pulse.default_set(sink) >>> card = pulse.card_list()[0] >>> card.profile_list [, , ... ] >>> pulse.card_profile_set(card, 'output:hdmi-stereo') >>> help(pulse) ... >>> pulse.close() ``` -------------------------------- ### List and Set Sink Ports Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Demonstrates how to list available ports for sinks, check the active port, and set a new active port by name, object, or index. Requires an active PulseAudio server. ```python import pulsectl with pulsectl.Pulse('port-manager') as pulse: # List sink ports for sink in pulse.sink_list(): print(f"Sink: {sink.description}") print(f"Active port: {sink.port_active.name if sink.port_active else 'None'}") print(f"Available ports:") for port in sink.port_list: active = " (active)" if sink.port_active and port.name == sink.port_active.name else "" print(f" - {port.name}: {port.description}") print(f" Available: {port.available}, Priority: {port.priority}{active}") print("---") # Set sink port by name sink = pulse.sink_list()[0] pulse.port_set(sink, 'analog-output-headphones') # Set sink port by object headphone_port = next((p for p in sink.port_list if 'headphone' in p.name.lower()), None) if headphone_port: pulse.port_set(sink, headphone_port) # Low-level port set pulse.sink_port_set(sink.index, 'analog-output-speaker') pulse.source_port_set(0, 'analog-input-mic') ``` -------------------------------- ### Listen for PulseAudio Events Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Demonstrates how to subscribe to and handle PulseAudio events in real-time, including listing available event types and facilities. The callback function can be used to react to changes, additions, or removals of audio devices and streams. Use `PulseLoopStop` to exit the listening loop. ```python import pulsectl with pulsectl.Pulse('event-listener') as pulse: # Available event types print(f"Event types: {pulse.event_types}") # ['change', 'new', 'remove'] # Available facilities (what changed) print(f"Event facilities: {pulse.event_facilities}") # ['card', 'client', 'module', 'sample_cache', 'server', 'sink', 'sink_input', 'source', 'source_output'] # Define event callback def event_callback(ev): print(f"Event: type={ev.t}, facility={ev.facility}, index={ev.index}") # Access enum values for comparison if ev.t == pulsectl.PulseEventTypeEnum.new: print(" -> New device/stream added") elif ev.t == pulsectl.PulseEventTypeEnum.remove: print(" -> Device/stream removed") elif ev.t == pulsectl.PulseEventTypeEnum.change: print(" -> Device/stream changed") # Stop listening after receiving event (optional) # raise pulsectl.PulseLoopStop # Subscribe to all events pulse.event_mask_set('all') pulse.event_callback_set(event_callback) # Listen for events with timeout (10 seconds) print("Listening for events (10 seconds)...") pulse.event_listen(timeout=10) # Listen for specific event types only pulse.event_mask_set('sink', 'sink_input') # Only sink and stream events # Stop listening when condition met events_received = [] def stop_after_5_events(ev): events_received.append(ev) print(f"Event {len(events_received)}: {ev.facility} {ev.t}") if len(events_received) >= 5: raise pulsectl.PulseLoopStop pulse.event_callback_set(stop_after_5_events) pulse.event_listen() # Blocks until PulseLoopStop raised # Disable event listening pulse.event_mask_set('null') pulse.event_callback_set(None) ``` -------------------------------- ### Manage Sound Cards and Profiles Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Inspect card details and switch between available profiles like analog stereo or HDMI. ```python import pulsectl with pulsectl.Pulse('card-manager') as pulse: # List all cards cards = pulse.card_list() for card in cards: print(f"Card {card.index}: {card.name}") print(f"Driver: {card.driver}") print(f"Active profile: {card.profile_active.name}") print(f"Available profiles:") for profile in card.profile_list: status = " (active)" if profile.name == card.profile_active.name else "" available = " [available]" if profile.available else "" print(f" - {profile.name}: {profile.description}{available}{status}") print(f" Sinks: {profile.n_sinks}, Sources: {profile.n_sources}") print(f"Ports:") for port in card.port_list: print(f" - {port.name}: {port.description}") print(f" Available: {port.available}, Direction: {port.direction}") print("---") # Get card by name card = pulse.get_card_by_name('alsa_card.pci-0000_00_1f.3') # Get card by index card = pulse.card_info(0) # Set card profile by name pulse.card_profile_set(card, 'output:analog-stereo') # Set card profile by object hdmi_profile = next((p for p in card.profile_list if 'hdmi' in p.name.lower()), None) if hdmi_profile: pulse.card_profile_set(card, hdmi_profile) print(f"Switched to HDMI profile") # Disable card (set to "off" profile) pulse.card_profile_set(card, 'off') ``` -------------------------------- ### Initialize Pulse Client Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Initialize the Pulse client using a context manager for automatic cleanup. Supports specific server connections and manual connection control with timeouts. Thread-safe initialization is also available. ```python import pulsectl # Basic initialization with context manager (recommended) with pulsectl.Pulse('my-app-name') as pulse: # Get server information server_info = pulse.server_info() print(f"Server: {server_info.server_name}") print(f"Default sink: {server_info.default_sink_name}") print(f"Default source: {server_info.default_source_name}") ``` ```python # Connect to specific server with options with pulsectl.Pulse('my-app', server='unix:/run/user/1000/pulse/native') as pulse: print(pulse.server_info().host_name) ``` ```python # Manual connection control with timeout with pulsectl.Pulse('my-app', connect=False) as pulse: try: pulse.connect(autospawn=True, timeout=5.0) print("Connected successfully") except pulsectl.PulseError as e: print(f"Connection failed: {e}") ``` ```python # Thread-safe initialization with pulsectl.Pulse('my-app', threading_lock=True) as pulse: # Safe to call methods from multiple threads sinks = pulse.sink_list() ``` -------------------------------- ### Manage Default Sink and Source Devices Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Query and update the system's default audio input and output devices using names or object references. ```python import pulsectl with pulsectl.Pulse('default-manager') as pulse: # Get current defaults server_info = pulse.server_info() print(f"Default sink: {server_info.default_sink_name}") print(f"Default source: {server_info.default_source_name}") # Get default sink/source objects default_sink = pulse.sink_default_get() default_source = pulse.source_default_get() print(f"Default sink description: {default_sink.description}") print(f"Default source description: {default_source.description}") # Set default sink using object sinks = pulse.sink_list() if len(sinks) > 1: pulse.default_set(sinks[1]) # Set second sink as default # Set default sink by name pulse.sink_default_set('alsa_output.pci-0000_00_1f.3.analog-stereo') # Set default source using object sources = pulse.source_list() pulse.default_set(sources[0]) # Set default source by name pulse.source_default_set('alsa_input.pci-0000_00_1f.3.analog-stereo') ``` -------------------------------- ### List Audio Sources Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Retrieve and display information about all available audio input devices (sources), including microphones and monitor sources. Monitor sources capture audio from output devices. ```python import pulsectl with pulsectl.Pulse('source-lister') as pulse: # Get all sources sources = pulse.source_list() for source in sources: print(f"Index: {source.index}") print(f"Name: {source.name}") print(f"Description: {source.description}") print(f"Mute: {source.mute}") print(f"Volume: {source.volume.value_flat}") print(f"Monitor of sink: {source.monitor_of_sink}") # -1 if not a monitor print(f"Properties: {source.proplist}") print("---") # Get specific source by index source = pulse.source_info(1) print(f"Source 1: {source.description}") # Get source by name source = pulse.get_source_by_name('alsa_input.pci-0000_00_1f.3.analog-stereo') print(f"Found source: {source.description}") ``` -------------------------------- ### Play Server-Side Audio Samples Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Trigger playback of pre-loaded audio samples on the PulseAudio server. ```python import pulsectl with pulsectl.Pulse('sample-player') as pulse: # Play a sample by name (must be loaded on server) # Common samples: bell, audio-volume-change, etc. try: pulse.play_sample('bell') print("Played 'bell' sample") except pulsectl.PulseOperationInvalid: print("Sample 'bell' not found on server") # Play on specific sink sink = pulse.sink_list()[0] pulse.play_sample('audio-volume-change', sink=sink) # Play by sink index pulse.play_sample('audio-volume-change', sink=0) # Play with custom volume (0.0 to 1.0) pulse.play_sample('bell', volume=0.5) # Play with custom properties pulse.play_sample( 'bell', sink=sink, volume=0.8, proplist_str='media.role=event' ) ``` -------------------------------- ### Manage Sink Input Volume Source: https://github.com/mk-fg/python-pulse-control/blob/master/README.rst Demonstrates how to retrieve, modify, and apply volume settings to a sink input using PulseVolumeInfo. ```python from pulsectl import Pulse, PulseVolumeInfo with Pulse('volume-example') as pulse: sink_input = pulse.sink_input_list()[0] # first random sink-input stream volume = sink_input.volume print(volume.values) # list of per-channel values (floats) print(volume.value_flat) # average level across channels (float) time.sleep(1) volume.value_flat = 0.3 # sets all volume.values to 0.3 pulse.volume_set(sink_input, volume) # applies the change time.sleep(1) n_channels = len(volume.values) new_volume = PulseVolumeInfo(0.5, n_channels) # 0.5 across all n_channels # new_volume = PulseVolumeInfo([0.15, 0.25]) # from a list of channel levels (stereo) pulse.volume_set(sink_input, new_volume) # pulse.sink_input_volume_set(sink_input.index, new_volume) # same as above ``` -------------------------------- ### Listen for Server Events Source: https://github.com/mk-fg/python-pulse-control/blob/master/README.rst Registers a callback to handle PulseAudio server events and listens for a specified duration. ```python import pulsectl with pulsectl.Pulse('event-printer') as pulse: # print('Event types:', pulsectl.PulseEventTypeEnum) # print('Event facilities:', pulsectl.PulseEventFacilityEnum) # print('Event masks:', pulsectl.PulseEventMaskEnum) def print_events(ev): print('Pulse event:', ev) ### Raise PulseLoopStop for event_listen() to return before timeout (if any) # raise pulsectl.PulseLoopStop pulse.event_mask_set('all') pulse.event_callback_set(print_events) pulse.event_listen(timeout=10) ``` -------------------------------- ### PulseAudio Reconnection Pattern Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Demonstrates how to handle PulseAudio disconnections and implement automatic reconnection. Ensure proper resource cleanup using a try-finally block. ```python import pulsectl pulse = pulsectl.Pulse('reconnecting-client', connect=False) try: while True: try: if not pulse.connected: pulse.connect(autospawn=True, wait=True, timeout=5.0) print("Connected to PulseAudio") # Do work... sinks = pulse.sink_list() print(f"Found {len(sinks)} sinks") except (pulsectl.PulseDisconnected, pulsectl.PulseOperationFailed): print("Connection lost, reconnecting...") continue except pulsectl.PulseError as e: print(f"Fatal error: {e}") break finally: pulse.close() ``` -------------------------------- ### Handle PulseAudio Exceptions Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Demonstrates catching specific PulseAudio exceptions like PulseIndexError, PulseOperationFailed, and PulseDisconnected for robust error management. ```python import pulsectl try: with pulsectl.Pulse('error-handler') as pulse: # PulseIndexError - object not found by index try: sink = pulse.sink_info(9999) except pulsectl.PulseIndexError: print("Sink not found") # PulseOperationFailed - operation rejected try: pulse.sink_default_set('nonexistent-sink') except pulsectl.PulseOperationFailed: print("Failed to set default sink") # PulseOperationInvalid - invalid operation parameters try: pulse.module_load('module-nonexistent') except pulsectl.PulseOperationInvalid as e: print(f"Invalid module: {e}") # PulseDisconnected - server connection lost try: pulse.event_mask_set('all') pulse.event_callback_set(lambda ev: None) pulse.event_listen(timeout=60) except pulsectl.PulseDisconnected: print("Lost connection to PulseAudio server") except pulsectl.PulseError as e: # Base exception for all pulse errors (including connection failure) print(f"PulseAudio error: {e}") ``` -------------------------------- ### Search PulseAudio Objects Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Uses the lookup module to find sinks, sources, or streams based on property patterns, regex, or type aliases. ```python import pulsectl from pulsectl.lookup import pulse_obj_lookup with pulsectl.Pulse('lookup-demo') as pulse: # Find sink inputs by application name matches = pulse_obj_lookup(pulse, 'mpv') for obj in matches: print(f"Found: {obj.name}") # Explicit type specification matches = pulse_obj_lookup(pulse, 'sink-input:mpv') # Search multiple types matches = pulse_obj_lookup(pulse, 'sink-input/source-output:firefox') # Use short aliases: si (sink-input), so (source-output), src (source) matches = pulse_obj_lookup(pulse, 'si/so:mpv') # Search by specific property matches = pulse_obj_lookup(pulse, 'application.name:Firefox') matches = pulse_obj_lookup(pulse, 'media.role:music') # Search multiple properties (any match) matches = pulse_obj_lookup(pulse, 'application.name/application.process.binary:mpv') # Regex search (prefix value with :) matches = pulse_obj_lookup(pulse, 'application.name::^mpv') # Starts with 'mpv' matches = pulse_obj_lookup(pulse, 'device.description::Analog') # Contains 'Analog' matches = pulse_obj_lookup(pulse, 'sink:device.description::HDMI') # HDMI sinks # Find sinks by driver matches = pulse_obj_lookup(pulse, 'sink:alsa.driver_name:snd_hda_intel') # Find by device bus matches = pulse_obj_lookup(pulse, 'sink/source:device.bus:pci') # Escape special characters in property names matches = pulse_obj_lookup(pulse, r'key\/with\/slashes\:and\:colons:value') # Use results for obj in pulse_obj_lookup(pulse, 'si:media.role:music'): pulse.volume_set_all_chans(obj, 0.5) print(f"Set volume for music stream: {obj.name}") ``` -------------------------------- ### Connect to PulseAudio CLI Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Establishes connections to the PulseAudio CLI socket for advanced operations. Supports local sockets, remote TCP connections, custom timeouts, and raw socket access. ```python import pulsectl # Connect to local CLI (default socket) with pulsectl.connect_to_cli() as cli: # Send command (like pacmd) cli.write('dump\n') # Read response line by line for line in cli: if line.strip() == '### EOF': break print(line, end='') # Send more commands cli.write('list-sinks\n') for line in cli: if line.strip() == '### EOF': break print(line, end='') # Connect to remote server via TCP with pulsectl.connect_to_cli(server=('192.168.1.100', 4712)) as cli: cli.write('info\n') for line in cli: if line.strip() == '### EOF': break print(line, end='') # Connect with custom timeout cli = pulsectl.connect_to_cli( server='/run/user/1000/pulse/cli', socket_timeout=5.0, attempts=3, retry_delay=0.5 ) try: cli.write('help\n') # Process response... finally: cli.close() # Get raw socket instead of file object sock = pulsectl.connect_to_cli(as_file=False) sock.send(b'dump\n') data = sock.recv(65536) sock.close() ``` -------------------------------- ### List Recording Streams Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Retrieve and inspect active recording streams (source outputs) and their associated application properties. ```python import pulsectl with pulsectl.Pulse('recording-lister') as pulse: # Get all recording streams source_outputs = pulse.source_output_list() for stream in source_outputs: print(f"Index: {stream.index}") print(f"Name: {stream.name}") print(f"Source index: {stream.source}") print(f"Mute: {stream.mute}") print(f"Corked (paused): {stream.corked}") print(f"Volume: {stream.volume.value_flat}") print(f"Client index: {stream.client}") print(f"Application: {stream.proplist.get('application.name')}") print("---") # Get specific source output by index stream = pulse.source_output_info(5) print(f"Recording stream 5: {stream.name}") ``` -------------------------------- ### List Playback Streams Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Retrieve and inspect active playback streams (sink inputs) and their associated application properties. ```python import pulsectl with pulsectl.Pulse('stream-lister') as pulse: # Get all playback streams sink_inputs = pulse.sink_input_list() for stream in sink_inputs: print(f"Index: {stream.index}") print(f"Name: {stream.name}") print(f"Sink index: {stream.sink}") print(f"Mute: {stream.mute}") print(f"Corked (paused): {stream.corked}") print(f"Volume: {stream.volume.value_flat}") print(f"Client index: {stream.client}") # Application properties proplist = stream.proplist print(f"Application name: {proplist.get('application.name')}") print(f"Application binary: {proplist.get('application.process.binary')}") print(f"Media name: {proplist.get('media.name')}") print(f"Media role: {proplist.get('media.role')}") print("---") # Get specific sink input by index stream = pulse.sink_input_info(42) print(f"Stream 42: {stream.name}") ``` -------------------------------- ### Interact with PulseAudio Enums Source: https://github.com/mk-fg/python-pulse-control/blob/master/README.rst Shows how to compare and inspect EnumValue objects returned by the library. ```python >>> pulsectl.PulseEventTypeEnum.change == 'change' True >>> pulsectl.PulseEventTypeEnum.change >>> pulsectl.PulseEventTypeEnum ``` -------------------------------- ### List Audio Sinks Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Retrieve and display information about all available audio output devices (sinks). Includes details like index, name, description, mute status, volume, channel count, and driver. ```python import pulsectl with pulsectl.Pulse('sink-lister') as pulse: # Get all sinks sinks = pulse.sink_list() for sink in sinks: print(f"Index: {sink.index}") print(f"Name: {sink.name}") print(f"Description: {sink.description}") print(f"Mute: {sink.mute}") print(f"Volume: {sink.volume.values}") # Per-channel volumes print(f"Volume (flat): {sink.volume.value_flat}") # Average volume print(f"Channels: {sink.channel_count}") print(f"Channel list: {sink.channel_list}") print(f"State: {sink.state}") print(f"Driver: {sink.driver}") print(f"Properties: {sink.proplist}") print("---") # Get specific sink by index sink = pulse.sink_info(0) print(f"Sink 0: {sink.description}") # Get sink by name sink = pulse.get_sink_by_name('alsa_output.pci-0000_00_1f.3.analog-stereo') print(f"Found sink: {sink.description}") ``` -------------------------------- ### Move Audio Streams Between Devices Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Relocate active sink inputs and source outputs to different hardware devices. ```python import pulsectl with pulsectl.Pulse('stream-mover') as pulse: # List available sinks sinks = pulse.sink_list() for s in sinks: print(f"Sink {s.index}: {s.description}") # Move a sink input to a different sink sink_inputs = pulse.sink_input_list() if sink_inputs and len(sinks) > 1: stream = sink_inputs[0] target_sink = sinks[1] print(f"Moving '{stream.name}' from sink {stream.sink} to {target_sink.index}") pulse.sink_input_move(stream.index, target_sink.index) # Verify the move updated_stream = pulse.sink_input_info(stream.index) print(f"Stream now on sink: {updated_stream.sink}") # Move source output to different source sources = pulse.source_list() source_outputs = pulse.source_output_list() if source_outputs and len(sources) > 1: recording = source_outputs[0] target_source = sources[1] pulse.source_output_move(recording.index, target_source.index) print(f"Moved recording stream to {target_source.description}") ``` -------------------------------- ### PulseAudio Enum and Type Information Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Illustrates the use of PulseAudio enumeration values for type-safe comparisons and iteration. This includes event types, facilities, masks, sink/source states, port availability, direction, and update modes. ```python import pulsectl # Event enums print("Event types:", pulsectl.PulseEventTypeEnum) # print("Event facilities:", pulsectl.PulseEventFacilityEnum) # print("Event masks:", pulsectl.PulseEventMaskEnum) # Available masks for event_mask_set() # Enum value comparison (works with strings) ev_type = pulsectl.PulseEventTypeEnum.change print(ev_type == 'change') # True print(ev_type == pulsectl.PulseEventTypeEnum.new) # False # Sink/Source state enum print("States:", pulsectl.PulseStateEnum) # # Port availability enum print("Port availability:", pulsectl.PulsePortAvailableEnum) # # Direction enum (for card ports) print("Direction:", pulsectl.PulseDirectionEnum) # # Update mode enum (for stream_restore) print("Update modes:", pulsectl.PulseUpdateEnum) # ``` ```python with pulsectl.Pulse('enum-demo') as pulse: # Check sink state for sink in pulse.sink_list(): if sink.state == pulsectl.PulseStateEnum.running: print(f"Sink {sink.name} is actively playing audio") elif sink.state == pulsectl.PulseStateEnum.idle: print(f"Sink {sink.name} is idle") elif sink.state == pulsectl.PulseStateEnum.suspended: print(f"Sink {sink.name} is suspended") # Check port availability for sink in pulse.sink_list(): for port in sink.port_list: if port.available == pulsectl.PulsePortAvailableEnum.yes: print(f"Port {port.name} is available") # Channel position enum (instance-specific) print("Channel positions:", pulse.channel_list_enum) # Compare channel values for sink in pulse.sink_list(): if pulse.channel_list_enum.front_left in sink.channel_list_raw: print(f"Sink {sink.name} has front-left channel") ``` -------------------------------- ### Manage Stream Restore Database Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Interact with the module-stream-restore database to read, update, or delete volume, mute, and device settings for specific applications. ```python import pulsectl from pulsectl import PulseExtStreamRestoreInfo with pulsectl.Pulse('stream-restore') as pulse: # Check if stream-restore module is available version = pulse.stream_restore_test() if version is None: print("module-stream-restore not loaded") else: print(f"stream-restore version: {version}") # List all saved stream entries entries = pulse.stream_restore_list() for entry in entries: print(f"Name: {entry.name}") print(f" Volume: {entry.volume.value_flat}") print(f" Mute: {entry.mute}") print(f" Device: {entry.device}") print(f" Channels: {entry.channel_list}") # Save/update entry by name pulse.stream_restore_write( 'sink-input-by-application-name:Firefox', volume=0.8, mute=False, channel_list='front-left,front-right', device='alsa_output.pci-0000_00_1f.3.analog-stereo' ) # Save entry using PulseExtStreamRestoreInfo object entry = PulseExtStreamRestoreInfo( 'sink-input-by-application-name:mpv', volume=0.5, channel_list=['front-left', 'front-right'], mute=False, device=None # Use default device ) pulse.stream_restore_write(entry, apply_immediately=True) # Update multiple entries at once entries_to_save = [ PulseExtStreamRestoreInfo('sink-input-by-application-name:vlc', volume=0.7), PulseExtStreamRestoreInfo('sink-input-by-application-name:spotify', volume=0.6), ] pulse.stream_restore_write(entries_to_save, mode='merge') # Mode options: # 'merge' (default) - merge with existing entries # 'replace' - replace matching entries # 'set' - replace ALL entries (dangerous!) # Delete specific entry pulse.stream_restore_delete('sink-input-by-application-name:Firefox') # Delete multiple entries pulse.stream_restore_delete([ 'sink-input-by-application-name:vlc', 'sink-input-by-application-name:spotify' ]) # Clear all entries (use with caution!) # pulse.stream_restore_write([], mode='set') ``` -------------------------------- ### Increase Sink Volume Source: https://github.com/mk-fg/python-pulse-control/blob/master/README.rst Iterates through available sinks and adjusts volume for all channels. ```python import pulsectl with pulsectl.Pulse('volume-increaser') as pulse: for sink in pulse.sink_list(): # Volume is usually in 0-1.0 range, with >1.0 being soft-boosted pulse.volume_change_all_chans(sink, 0.1) ``` -------------------------------- ### Monitor Audio Peak Levels Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Read peak sample values from sources or streams for applications like VU meters or silence detection. ```python import pulsectl import time with pulsectl.Pulse('peak-detector') as pulse: # Get peak from default source (microphone) default_source = pulse.source_default_get() # Monitor for 0.5 seconds and return max peak value (0.0 to 1.0) peak = pulse.get_peak_sample(default_source.index, timeout=0.5) print(f"Microphone peak level: {peak * 100:.1f}%") # Monitor by source name peak = pulse.get_peak_sample(default_source.name, timeout=0.3) # Monitor using None for default source peak = pulse.get_peak_sample(None, timeout=0.5) # Monitor specific stream's audio sink_inputs = pulse.sink_input_list() if sink_inputs: stream = sink_inputs[0] sink = pulse.sink_info(stream.sink) # Get peak for specific stream via sink's monitor source peak = pulse.get_peak_sample( sink.monitor_source, # Monitor source index timeout=0.5, stream_idx=stream.index # Monitor this specific stream ) print(f"Stream '{stream.name}' peak: {peak * 100:.1f}%") # Simple VU meter loop print("Monitoring microphone levels (Ctrl+C to stop):") try: while True: peak = pulse.get_peak_sample(None, timeout=0.1) bars = int(peak * 50) print(f"\r[{'█' * bars}{' ' * (50 - bars)}] {peak * 100:5.1f}%", end='') time.sleep(0.05) except KeyboardInterrupt: print("\nStopped") ``` -------------------------------- ### Control Audio Volume Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Adjust volume levels for sinks, sources, and streams using flat averages or per-channel configurations. Values above 1.0 enable software amplification. ```python import pulsectl from pulsectl import PulseVolumeInfo with pulsectl.Pulse('volume-control') as pulse: sink = pulse.sink_list()[0] # Get current volume (flat average across channels) current_vol = pulse.volume_get_all_chans(sink) print(f"Current volume: {current_vol * 100:.0f}%") # Set volume to 50% on all channels pulse.volume_set_all_chans(sink, 0.5) # Increase volume by 10% on all channels pulse.volume_change_all_chans(sink, 0.1) # Decrease volume by 5% pulse.volume_change_all_chans(sink, -0.05) # Per-channel volume control volume = sink.volume print(f"Per-channel volumes: {volume.values}") # Set different levels per channel (stereo example) new_volume = PulseVolumeInfo([0.3, 0.7]) # Left 30%, Right 70% pulse.volume_set(sink, new_volume) # Create volume from single value for N channels channels = len(sink.volume.values) uniform_volume = PulseVolumeInfo(0.5, channels) # 50% on all channels pulse.volume_set(sink, uniform_volume) # Control sink input (application) volume for stream in pulse.sink_input_list(): if 'mpv' in stream.proplist.get('application.name', '').lower(): pulse.volume_set_all_chans(stream, 0.8) print(f"Set mpv volume to 80%") # Low-level volume set by index pulse.sink_volume_set(sink.index, PulseVolumeInfo(0.6, 2)) pulse.sink_input_volume_set(stream.index, PulseVolumeInfo(0.5, 2)) ``` -------------------------------- ### Control Mute State Source: https://context7.com/mk-fg/python-pulse-control/llms.txt Toggle or set the mute state for sinks, sources, and specific application streams. ```python import pulsectl with pulsectl.Pulse('mute-control') as pulse: # Mute a sink sink = pulse.sink_list()[0] pulse.mute(sink, True) # Mute print(f"Sink muted: {sink.mute}") pulse.mute(sink, False) # Unmute print(f"Sink muted: {sink.mute}") # Toggle mute pulse.mute(sink, not sink.mute) # Mute a source (microphone) source = pulse.source_list()[0] pulse.mute(source, True) # Mute specific application stream for stream in pulse.sink_input_list(): if stream.proplist.get('application.name') == 'Firefox': pulse.mute(stream, True) print("Firefox muted") # Low-level mute by index pulse.sink_mute(sink.index, True) pulse.sink_input_mute(stream.index, False) pulse.source_mute(source.index, True) pulse.source_output_mute(5, False) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.