How can I play audio (playsound) in the background of a Python script?
Asked Answered
C

10

6

I am just writing a small Python game for fun and I have a function that does the beginning narrative.

I am trying to get the audio to play in the background, but unfortunately the MP3 file plays first before the function continues.

How do I get it to run in the background?

import playsound

def displayIntro():
    playsound.playsound('storm.mp3',True)
    print('')
    print('')
    print_slow('The year is 1845, you have just arrived home...')

Also, is there a way of controlling the volume of the playsound module?

I am using a Mac, and I am not wedded to using playsound. It just seems to be the only module that I can get working.

Cardinalate answered 10/6, 2017 at 10:18 Comment(0)
G
17

In Windows:

Use winsound.SND_ASYNC to play them asynchronously:

import winsound
winsound.PlaySound("filename", winsound.SND_ASYNC | winsound.SND_ALIAS )

To stop playing

winsound.PlaySound(None, winsound.SND_ASYNC)

On Mac or other platforms:

You can try this Pygame/SDL

pygame.mixer.init()
pygame.mixer.music.load("file.mp3")
pygame.mixer.music.play()
Gateway answered 10/6, 2017 at 10:26 Comment(4)
Hey, thank you. I managed to get the pygame sound to work, thank you. However it is not playing in the background. Any idea how to do that?Cardinalate
Sorry, I had left a playsound code in the script. The pygame mixer isn't playing any sound :/Cardinalate
Fixed it, it just wouldn't play .mp3 files. It works with .wav filesCardinalate
Yes try to convert mp3 to wav using pymedia i guessGateway
C
22

Just change True to False (I use Python 3.7.1)

import playsound
playsound.playsound('storm.mp3', False)
print ('...')
Capella answered 7/1, 2019 at 12:57 Comment(6)
Info: This does not work using Ubuntu 20.04. It gives the following error: NotImplementedError: block=False cannot be used on this platform yetNicholasnichole
This worked for me on Windows with Python 3.7.3Retrogradation
after some testing it looks like this only works on windows due to the underlying Gstreamer implementation that is only configured for windows driversErvinervine
This seems to work on Ubuntu 20.04 too now.Sphacelus
win10 ModuleNotFoundError: No module named 'playsound'Luella
so install playsound if you didn't, and if you did it's an errorConnatural
G
17

In Windows:

Use winsound.SND_ASYNC to play them asynchronously:

import winsound
winsound.PlaySound("filename", winsound.SND_ASYNC | winsound.SND_ALIAS )

To stop playing

winsound.PlaySound(None, winsound.SND_ASYNC)

On Mac or other platforms:

You can try this Pygame/SDL

pygame.mixer.init()
pygame.mixer.music.load("file.mp3")
pygame.mixer.music.play()
Gateway answered 10/6, 2017 at 10:26 Comment(4)
Hey, thank you. I managed to get the pygame sound to work, thank you. However it is not playing in the background. Any idea how to do that?Cardinalate
Sorry, I had left a playsound code in the script. The pygame mixer isn't playing any sound :/Cardinalate
Fixed it, it just wouldn't play .mp3 files. It works with .wav filesCardinalate
Yes try to convert mp3 to wav using pymedia i guessGateway
A
4

There is a library in Pygame called mixer and you can add an MP3 file to the folder with the Python script inside and put code like this inside:

from pygame import mixer

mixer.init()
mixer.music.load("mysong.mp3")
mixer.music.play()
Aila answered 23/12, 2018 at 19:15 Comment(1)
This is the same as in the accepted answer (but much better explained).Syngamy
R
3

Well, you could just use pygame.mixer.music.play(x):

#!/usr/bin/env python3
# Any problems contact me on Instagram, @vulnerabilties
import pygame

pygame.mixer.init()
pygame.mixer.music.load('filename.extention')
pygame.mixer.music.play(999)

# Your code here
Ranie answered 23/12, 2018 at 19:10 Comment(1)
Is @vulnerabilties on Instagram you? Or somebody else? Can you elaborate?Syngamy
R
3

You could try just_playback. It's a wrapper I wrote around miniaudio that plays audio in the background while providing playback control functionality like pausing, resuming, seeking and setting the playback volume.

Razzia answered 12/3, 2021 at 11:8 Comment(0)
B
2

A nice way to do it is to use vlc. Very common and supported library.

pip install python-vlc

Then writing your code

import vlc

#Then instantiate a MediaPlayer object

player = vlc.MediaPlayer("/path/to/song.mp3")

#And then use the play method

player.play()

#You can also use the methods pause() and stop if you need.

player.pause()
player.stop

#And for the super fancy thing you can even use a playlist :)

playlist = ['/path/to/song1.mp3', '/path/to/song2.mp3', '/path/to/song3.mp3']

    for song in playlist:
        player = vlc.MediaPlayer(song)
        player.play()
Breughel answered 21/8, 2021 at 23:5 Comment(0)
E
1
from pygame import mixer

mixer.music.init()
mixer.music.load("audio.mp3") # Paste The audio file location 
mixer.play() 
Extracellular answered 14/2, 2019 at 9:56 Comment(2)
While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.Livengood
The code is practically identical to the code in Rinzler786's answer (though the code comment is a slight improvement). And that answer has an explanation.Syngamy
P
1

I used a separate thread to play the sound without blocking the main thread. It works on Ubuntu as well.

from threading import Thread
from playsound import playsound

def play(path):
    """
    Play sound file in a separate thread
    (don't block current thread)
    """
    def play_thread_function:
        playsound(path)

    play_thread = Thread(target=play_thread_function)
    play_thread.start()
Pyrazole answered 17/9, 2021 at 8:24 Comment(0)
I
1

This is a solution to reproduce similar length sounds. This solution worked to me to solve the error:

The specified device is not open or recognized by MCI.

Here follow the syntax as a class method, but you can change it to work even without a class.

Import these packages:

import multiprocessing
import threading
import time

Define this function:

def _reproduce_sound_nb(self, str_, time_s):
        def reproduce_and_kill(str_, time_sec=time_s):
            p = multiprocessing.Process(target=playsound, args=(str_,))
            p.start()
            time.sleep(time_sec)
            p.terminate()
        threading.Thread(target=reproduce_and_kill, args=(str_, time_s), daemon=True).start()
    

In the main program/method:

self._reproduce_sound_nb(sound_path, 3) # path to the sound, seconds after sound stop -> to manage the process end
Incorporation answered 5/10, 2021 at 13:16 Comment(1)
why have you used both multiprocessing and threading at the same time?Turbot
C
0

Use vlc

import vlc
player = None
def play(sound_file):
    global player
    if player is not None:
        player.stop()
    player = vlc.MediaPlayer("file://" + sound_file)
    player.play()
Checkrein answered 7/6, 2021 at 19:43 Comment(2)
Can you expand this answer? E.g., what is required to be installed? VLC media player? Or something else (some development files not part of the VLC media player installation)? Or completely independent of VLC media player itself (some stand-alone libraries)? What platform did you test this on? (But without "Edit:", "Update:", or similar - the question/answer should appear as if it was written today.)Syngamy
rambopython's answer is less terse.Syngamy

© 2022 - 2024 — McMap. All rights reserved.