咨询:基于Python 3与GTK3开发双声卡音乐播放器的可用模块
Hey there! Let me break this down clearly for you since you’re building a neat multi-soundcard music player with Python 3 and GTK3. First off, the VLC Python bindings you’re already using do support targeting specific soundcards—you just need to know the right settings to configure it. Let me walk you through that first, then suggest some alternative modules if you want more options.
VLC actually has built-in support for routing audio to specific devices, which is perfect for your use case. Here’s how to make it work:
- First, list all available audio output devices on your system to get their identifiers:
import vlc instance = vlc.Instance() # Enumerate and print all available audio devices for idx, device in enumerate(instance.audio_output_device_enum()): print(f"Device {idx}: ID = {device.device}, Name = {device.description}") vlc.libvlc_audio_output_device_release(device)
- Route a VLC player instance to a specific device:
Once you have the target device’s ID or name, you can assign it to a media player instance. You can create multiple player instances to send different audio to different soundcards:
# Initialize the main VLC instance instance = vlc.Instance() # Create first player for your speaker player_speaker = instance.media_player_new() media_speaker = instance.media_new("/path/to/speaker-audio.mp3") player_speaker.set_media(media_speaker) # Assign to your speaker device (replace with your device's ID/name) player_speaker.audio_output_device_set(None, "your-speaker-device-id") # Create second player for your display/aux track player_display = instance.media_player_new() media_display = instance.media_new("/path/to/display-audio.mp3") player_display.set_media(media_display) # Assign to your second soundcard player_display.audio_output_device_set(None, "your-display-device-id") # Start both playbacks player_speaker.play() player_display.play()
Note: Device identifiers vary by system (Linux uses ALSA/PulseAudio IDs, for example), so use the first code snippet to get the exact values you need.
If you want to explore options beyond VLC, here are three solid choices that work great with Python and GTK3:
- SoundDevice (built on PortAudio)
This lightweight, cross-platform library makes it easy to target specific devices and handle various audio formats (pair it withsoundfileto read MP3/FLAC/WAV files).
import sounddevice as sd import soundfile as sf # List all available devices to find indices print(sd.query_devices()) # Load audio data audio1, sample_rate = sf.read("/path/to/audio1.mp3") audio2, _ = sf.read("/path/to/audio2.mp3") # Play audio1 on device index 0 (speaker) sd.play(audio1, sample_rate, device=0) # Play audio2 on device index 1 (display) sd.play(audio2, sample_rate, device=1) # Wait for playback to finish (or run in threads to avoid blocking GTK UI) sd.wait()
It integrates smoothly with GTK3’s event loop if you use non-blocking playback with callbacks.
- PyAudio (PortAudio-based)
For more low-level control over audio streams, PyAudio is a great choice. It’s ideal if you need real-time mixing or processing alongside your UI.
import pyaudio import wave # List available devices pa = pyaudio.PyAudio() for i in range(pa.get_device_count()): device_info = pa.get_device_info_by_index(i) print(f"Device {i}: {device_info['name']}") # Play audio on device 0 wf1 = wave.open("/path/to/audio1.wav", "rb") stream1 = pa.open( format=pa.get_format_from_width(wf1.getsampwidth()), channels=wf1.getnchannels(), rate=wf1.getframerate(), output=True, output_device_index=0 ) data1 = wf1.readframes(1024) while data1 != b"": stream1.write(data1) data1 = wf1.readframes(1024) # Repeat for device 2 with another audio file wf2 = wave.open("/path/to/audio2.wav", "rb") stream2 = pa.open( format=pa.get_format_from_width(wf2.getsampwidth()), channels=wf2.getnchannels(), rate=wf2.getframerate(), output=True, output_device_index=1 ) data2 = wf2.readframes(1024) while data2 != b"": stream2.write(data2) data2 = wf2.readframes(1024) # Cleanup stream1.stop_stream() stream1.close() stream2.stop_stream() stream2.close() pa.terminate()
- Pygame Mixer
While known for game development, Pygame’s mixer module supports targeting specific soundcards. It works best with WAV files, but you can convert other formats or use helper libraries to handle MP3s.
import pygame # Initialize mixer for first soundcard (speaker) pygame.mixer.init(devicename="your-speaker-device-name") sound1 = pygame.mixer.Sound("/path/to/audio1.wav") sound1.play() # Quit and re-initialize for second soundcard (display) pygame.mixer.quit() pygame.mixer.init(devicename="your-display-device-name") sound2 = pygame.mixer.Sound("/path/to/audio2.wav") sound2.play()
All these options play nicely with GTK3—just run playback in separate threads to avoid freezing your UI, and update your GTK widgets with playback status as needed. Since you’re already using VLC, starting there makes sense because it handles a huge range of audio formats out of the box without extra conversion steps.
内容的提问来源于stack exchange,提问作者david dumont

