After my song (music.mp3) ends, it doesn't replay. I have the following code:
# import pygame and other code
pygame.mixer.music.load('music.mp3')
pygame.mixer.music.play()
pygame.mixer.music.rewind()
pygame.init()
Shouldn't it be replaying itself? And if not, how do I make it replay whenever it ends?
Your code does not do what you think it does. It starts playing the MP3 but the play() call doesn't wait until the file is played, it immediately returns, playing the music asynchronously. So starting a song and immediately rewinding in the next line of code does not make any sense. If you want the music to play more than once, have a look at the loop argument of pygame.mixer.music.play(). It allows to play the music a given number of times or indefinitely.
The play function takes an integer number of times to play the sound. -1 sets it to infinite.
pygame.mixer.music.play(-1)
EDIT:
It's proper practice to initiate pygame before setting up the mixer, as pygame.init() also calls pygame.mixer.init().
Related
I'm trying to make a game with pygame and then I would like to make it sound some music.
musica = pygame.mixer.Sound("song.mp3")
musica.play()
(I don't see necessary showing more code because nothing more interacts with the sound)
The music plays and it's all good, but after like 20 seconds pass, the music stops for some reason (real song lasts almost 4 minutes).
If you are dealing with background music, perhaps you mean to use pygme.mixer.music.load()? Followed by pygame.mixer.music.play() to play the music? Or pass -1 as parameter to pygame.mixer.music.play(-1) if you want the music to loop?
pygame.mixer.music.load("song.mp3")
pygame.mixer.music.play()
However, a way to potentially get around this (assuming there is something else in your program that's accidentally interfering with it) is using threading.
Import threading at the top of your program then define a function that plays the music, e.g.
import threading
def musicplayer():
musica = pygame.mixer.Sound("song.mp3")
musica.play()
x = threading.Thread(target=musicplayer, args=(), daemon=True)
x.start()
This makes the music playing independent of the rest of your code which could fix your issue.
I am just playing around with Python playing MP3 files and bumped into pygame
I got it to play the music but somehow I need to add time.sleep(SECONDS) in order for the music to play or else it'll just exist right away when I run in terminal
Is there a reason for this or I am not doing it right?
import pygame, time
from pygame.locals import *
pygame.mixer.pre_init(44100, 16, 2, 4096)
pygame.init()
pygame.mixer.music.load("path/to/mp3/file")
pygame.mixer.music.play()
time.sleep(32)
I am not trying to create a game or anything, as I mentioned I am just playing around with Python
To speak to the "why" -- pygame.mixer.music isn't really designed to be a foreground process: the idea is that this is background music to play while something else runs. If the user says they want to exit a game, they'll usually be annoyed if that game keeps running until the current background-music track is finished.
If you want to block until the music is finished, one inefficient-but-easy way to do that is with a loop that checks for completion:
while pygame.mixer.music.get_busy():
time.sleep(0.1)
I have a Raspberry Pi 3b that I'm using to play music. When a button (GPIO) is pressed, I want to play a list of songs. I'm doing this using the vlc media list player. I build a media list by grabbing N random mp3 files from a directory.
eg:
i=vlc.Instance()
l=i.media_list_new()
l.insert_media(i.media_new(...)) # this loops and grabs random mp3s
p=i.media_list_player_new()
p.set_media_list(l)
p.play()
Another GPIO signal will call p.stop(). What I want to know at that point is which songs in the media list have been played. This way I can track them and not play them again the next time the Play button is pressed, but the unplayed tracks in the list should still be eligible to play.
So far I don't see any way to get any info from the media list player on what item in the list it's on or another way to tell what has been played from the list.
I tried an alternative of manually looping through a list of songs and using a regular player (not list player), but when I do this I have to do a while True loop to make the player wait for one song to finish before playing the next one. This loop also seems to block my GPIO event handler for some reason and pressing the STOP button goes undetected (have to cancel the script to stop).
My advice would be: Don't use the MediaListPlayer.
Use a MediaList along with a MediaPlayer and listen for libvlc_MediaListEndReached https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc.html
loop to make the player wait for one song to finish before playing the next one
Use libvlc events.
Actually got this working using the MediaListPlayer and events. I added an event handler for MediaListPlayerNextItemSet that calls a function that increments a counter, so I know how many songs in the list were played now.
Ok so basically I'm working on this pygame game and I'm using the mixer sub module for sounds. However, in pygame if you want to stop a sound, the sound must finish its cycle until it can be stopped. For all my sounds this is ok as they can be a looped 1 second sound. However, I use a falling sound which needs to constantly play in a cycle, but cycling a falling sound that is only 1 second long doesn't sound very effective. So, ultimately I want to know if there is a way to stop a 7 second sound loop instantly without it finishing a cycle.
According to the pygame documentation for pygame.mixer
pygame.mixer.pause()
will temporarily stop playback of all sound channels. You can start them all playing again with;
pygame.mixer.unpause()
For an individual sound, whilst it will stop after a full cycle, you can immediately affect it's volume with;
pygame.mixer.Sound.set_volume(0)
So what I'd try first is stopping the sound at the same time as setting it's volume to zero and seeing if that solves your problem. Alternatively, you can split your mixer into Channels for better controlling sound playback, which will give you the ability to use
pygame.mixer.Channel.pause()
pygame.mixer.Channel.unpause()
On specific groups of sounds rather than all sound. You create a mixer channel with;
pygame.mixer.Channel(id)
You can then play specific sounds on that channel with;
pygame.mixer.Channel.play(Sound, loops=0, maxtime=0, fade_ms=0)
This would also allow you to more dynamically adjust the levels of various types of sounds in your game - for example, environment, music, weather, voices and how they overlap each other, just keep in mind a channel can only play one sound at a time. Because of this, it may by prudent to use;
free_channel = pygame.mixer.find_channel()
free_channel.play(Sound)
or more simply;
pygame.mixer.find_channel().play(Sound)
For everything except your 'falling' channel.
I'm using the pygame function pygame.time.delay() to make pygame freeze while presenting some pictures or text, and I want to play a sound at the same time.
The problem, I think, is that in order for pygame mixer to work the main loop must be running, so putting the system on wait it also stops the mixer.
Any easy way to solve this problem? thanks
pygame.time.delay() is a bad idea for waiting while presenting things, it not only will prevent you from playing music it can also freeze your screen (blank screen).
You should process events and update the display although you have static image.
Some alternatives are:
Use a counter in your loop to know how long you should keep the same image in the screen.
Use a timer to receive a User Event that will notify you that you need to change the current state.