Search code examples
pythonaudiopygame

Set output device for pygame mixer


I need to play audio files through different audio devices using pygame. Apparently this is possible by parameter devicename in method pygame.mixer.init(), but there is no documentation for it.

My questions:

1- How to set output device for pygame mixer (or channel/sound if possible)?

2- How to list all available device-names?


Solution

  • I found the solution. Pygame v2 has made all of this possible. Since pygame uses sdl2, we can get audio device names by pygame's own implementation of the sdl2 library.

    Updated method

    On the recent versions of pygame;

    To get the audio device names:

    import pygame
    import pygame._sdl2.audio as sdl2_audio
    
    def get_devices(capture_devices: bool = False) -> Tuple[str, ...]:
        init_by_me = not pygame.mixer.get_init()
        if init_by_me:
            pygame.mixer.init()
        devices = tuple(sdl2_audio.get_audio_device_names(capture_devices))
        if init_by_me:
            pygame.mixer.quit()
        return devices
    

    And to play an audio file through a specific device:

    from time import sleep
    import pygame
    
    def play(file_path: str, device: Optional[str] = None):
        if device is None:
            devices = get_devices()
            if not devices:
                raise RuntimeError("No device!")
            device = devices[0]
        print("Play: {}\r\nDevice: {}".format(file_path, device))
        pygame.mixer.init(devicename=device)
        pygame.mixer.music.load(file_path)
        pygame.mixer.music.play()
        try:
            while True:
                sleep(0.1)
        except KeyboardInterrupt:
            pass
        pygame.mixer.quit()
    

    Old method

    On the earlier versions of pygame v2;

    To get the audio device names:

    import pygame._sdl2 as sdl2
    
    pygame.init()
    is_capture = 0  # zero to request playback devices, non-zero to request recording devices
    num = sdl2.get_num_audio_devices(is_capture)
    names = [str(sdl2.get_audio_device_name(i, is_capture), encoding="utf-8") for i in range(num)]
    print("\n".join(names))
    pygame.quit()
    

    On my device, the code returns:

    HDA Intel PCH, 92HD87B2/4 Analog
    HDA Intel PCH, HDMI 0
    C-Media USB Headphone Set, USB Audio
    

    And to set the output audio device for pygame mixer:

    import pygame
    import time
    
    pygame.mixer.pre_init(devicename="HDA Intel PCH, 92HD87B2/4 Analog")
    pygame.mixer.init()
    pygame.mixer.music.load("audio.ogg")
    pygame.mixer.music.play()
    time.sleep(10)
    pygame.mixer.quit()