How can I play looping music in the background as other functions are being performed?

Viewed 62

I am currently using the subprocess module to play .mp3 files. It works just fine getting them to play, but once I do subprocess.call(["afplay", "../music/songname.mp3"]), that's all the code will do until the entire duration of the song has finished playing. I want to make things happen while the song is playing. I don't know how easy this is but I've struggled to find people online asking about the same thing. Is it possible to use a different command with the same subprocess module and achieve this result? Is there a completely separate way to achieve this? I'm open to anything, but keep in mind I'm very new to this.

I have created a loop track so that, after a certain time in the song has been reached, it will instead play an identical track which has set beginning and end times that, when played back-to-back, create a perfect music loop. Once that first problem is solved, how can I rig this track to repeat infinitely in the background?

I'm very new to this.

3 Answers

You can try mixer from pygame module for playing sounds and repeat it infinitely in the 'background'.

import contextlib
with contextlib.redirect_stdout(None): # hide pygame intro text
    from pygame import mixer # import mixer from pygame module

mixer.init() # initialize the mixer module
mixer.music.load('songname.mp3') # load media file
mixer.music.set_volume(0.5) # set playing volume
mixer.music.play(-1) # play & loops media for n times in arguments, -1 always looping


# for demonstration
from random import randint, choice

def demo():
    a, b = randint(0,10), randint(0,10)
    while True:
        if int(input(f'{a} + {b} = ')) == a + b:
            print(choice(['Correct!', 'Nice!', 'Excellent!', 'Genius!', 'Wow!']))
            demo() if input('More (y/n)? ') == 'y' else print('Bye!'); break
        else:
            print(choice(['Wrong!', 'Nope!', 'OMG!', 'WTH!', 'Try Again!', 'LOL!']))


demo()

subprocess forks then execs a process, but it waits for the process to finish before returning. you will need to do this in a separate thread, use an asyncio suprocess interface or do an initial a fork yourself. it is a bit tricky. what is also complicated, is that you will likely not get a perfect gapless playback by looping subprocess commands, as python will likely take a millisecond or two to re-execute the command.

Related