Play music and get user input simultaneously? - python

Can I get input and play music from pygame at the same time?
The code I have now:
from pygame import mixer
mixer.init()
mixer.music.load('song.mp3')
mixer.music.play()
var = raw_input("Input: ")
print "you said ", var
while pygame.mixer.music.get_busy():
pygame.time.Clock().tick(10)
It works fine until I enter something, and then the program stops:
Input: test
you said test
Traceback (most recent call last):
File "play.py", line 10, in <module>
while pygame.mixer.music.get_busy():
NameError: name 'pygame' is not defined

from pygame import mixer
puts mixer in your namespace, but not pygame
You can either:
while mixer.music.get_busy():
or
import pygame
from pygame import mixer
importing pygame as well as it's subpackages you need is usually a good approach

Related

How can I play another music list with Pygame? [duplicate]

I am looking to iterate through a list of songs such as Songs = ["Song1.mp3", "Song2.mp3", "Song3.mp3"] and I want to play each song one after each other.
I have tried various methods, the most suggested seemed to use pygame, however, I have not been able to debug the tremendous amount of errors that come with using it. My main source code and attempt at this is as shown below:
from tkinter import *
import pygame
from random import choice
import os
pygame.mixer.init()
Songs = os.listdir("Music\\")
def Play():
Song = choice(Songs)
pygame.mixer.music.load("Music\\" + Song)
pygame.mixer.music.play()
while True:
play()
Upon running this I receive error pygame.error: ModPlug_Load failed.
I am running this concurrently inside of a slideshow program I have, I want this code to run as background music and I plan on checking for the end of the song in a Function I already have set.
Use pygame.mixer.music.get_busy() to detect if a music stream is actively playing. Play the next song from the list when no stream is active. e.g:
import pygame
play_list = ["song1.mp3", "song2.mp3", "song3.mp3"]
current_list = []
pygame.init()
clock = pygame.time.Clock()
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if not pygame.mixer.music.get_busy():
if not current_list:
current_list = play_list[:]
current_song = current_list.pop(0)
pygame.mixer.music.load(current_song)
pygame.mixer.music.play()
pygame.quit()
exit()
You can register a custom event which will be triggered when the music is done playing using pygame.mixer.music.set_endevent().
Also you need to run the while loop in a child thread if you want to run concurrently with main application.
Below is an example:
import os
import random
import threading
import tkinter as tk
import pygame
pygame.init()
# create a custom event
MUSIC_DONE = pygame.event.custom_type()
# register the event
pygame.mixer.music.set_endevent(MUSIC_DONE)
folder = "Music\\"
Songs = os.listdir(folder)
def next_song():
try:
song = random.choice(Songs)
pygame.mixer.music.load(os.path.join(folder, song))
pygame.mixer.music.play()
# update song name
song_var.set(song)
except Exception as e:
print(e)
def pygame_loop():
next_song()
while pygame.get_init():
for event in pygame.event.get():
if event.type == MUSIC_DONE:
# current song done playing, play next song
next_song()
root = tk.Tk()
# label to show the current song being played
song_var = tk.StringVar()
tk.Label(root, textvariable=song_var).pack()
# start the pygame loop in a child thread
threading.Thread(target=pygame_loop).start()
root.mainloop()
# quit pygame
pygame.quit()
If it's a desktop app, you have multiple options to play a file, usually, it depends:
Also to avoid Tkinter being stuck, you need to use threads or multiprocess. I recommend you soundfile player, you will find examples here https://realpython.com/playing-and-recording-sound-python/

Control VLC player using python-vlc module

Controlling the VLC media player using python-vlc module
I have tried the code below but am getting the error:
Traceback (most recent call last): File "", line 1, in
import vlc File "vlc.py", line 2, in <module>
# -*- coding: utf-8 -*-
AttributeError: 'module' object has no attribute 'MediaPlayer'
Using code:
import vlc
media_player = vlc.MediaPlayer("path_to_your_song.mp3")
media_player.play()
I want the script to run and play the file
Just change the path,your good to go..
from vlc import Instance
import time
import os
class VLC:
def __init__(self):
self.Player = Instance('--loop')
def addPlaylist(self):
self.mediaList = self.Player.media_list_new()
path = r"C:\Users\dell5567\Desktop\engsong"
songs = os.listdir(path)
for s in songs:
self.mediaList.add_media(self.Player.media_new(os.path.join(path,s)))
self.listPlayer = self.Player.media_list_player_new()
self.listPlayer.set_media_list(self.mediaList)
def play(self):
self.listPlayer.play()
def next(self):
self.listPlayer.next()
def pause(self):
self.listPlayer.pause()
def previous(self):
self.listPlayer.previous()
def stop(self):
self.listPlayer.stop()
Create a object
player = VLC()
Add playlist
player.addPlaylist()
Play the song
player.play()
time.sleep(9)
Play the next song
player.next()
time.sleep(9)
Pause the song
player.pause()
time.sleep(9)
Resume the song
player.play()
time.sleep(9)
Previous song
player.previous()
time.sleep(9)
Stop the song
player.stop()
You need to create a vlc Instance.
The minimum required would be something like this, but there are many variations.
>>> import vlc
>>> i = vlc.Instance()
>>> media_player = i.media_player_new()
>>> media_player.set_mrl('./vp1.mp3')
>>> media_player.play()

pygame sound not playing after time.sleep() function

Any ideas why the code below does not play the sound? If the s.play() were to be outside the clock() function, it work.
import time
import pygame
pygame.init()
s = pygame.mixer.Sound("0614.wav")
def clock ():
x = input("How long to start the alarm for? ")
delay = float(x)
print ("Alarm Started")
time.sleep(delay)
print ("!!!!ALARM!!!!!")
s.play()
clock()
Is your file "0614.wav" in the same folder as form the program is executed?.
To see the error use try-except block and then print the error.

Pygame plays a mp3 file faster than normal speed

I use Python to play a short mp3 audio file. But the playing speed is faster than other music players.
My Code:
import pygame
import time
pygame.mixer.init(frequency=22050, size=16, channels=2, buffer=4096)
file=r'test.mp3'
try:
pygame.mixer_music.load(file)
pygame.mixer_music.play()
while pygame.mixer_music.get_busy():
time.sleep(0.1)
except Exception as err:
print(err)
Please help me to solve this issue!
This will work:
import time, os
from pygame import mixer
from pydub import AudioSegment
# original file: "slow.mp3"
# new fast file: "fast.mp3"
# speed: 1.3 (1.0 is actual speed)
def speed_swifter(sound, speed=1.0):
sound_with_altered_frame_rate = sound._spawn(sound.raw_data, overrides={"frame_rate": int(sound.frame_rate * speed)})
return sound_with_altered_frame_rate
newSpeed = 1.3
sound = AudioSegment.from_file("slow.mp3")
speed_sound = speed_swifter(sound, newSpeed)
speed_sound.export(os.path.join("fast.mp3"), format="mp3")
mixer.init()
mixer.music.load("fast.mp3")
mixer.music.play()
while mixer.music.get_busy():
time.sleep(0.1)
import pygame, mutagen.mp3
song_file = "your_music.mp3"
mp3 = mutagen.mp3.MP3(song_file)
pygame.mixer.init(frequency=mp3.info.sample_rate)
pygame.mixer.music.load(song_file)
pygame.mixer.music.play()

Error while re-opening sound file in python

I was in the process of making a program that simply repeats any text you enter, and seemed to be working when I first tested it. The problem is that the second time I attempt to type anything, it crashes and says that permission was denied to the sound file I was recording it to. I believe it is because the file was already opened, but none the less I do not know how to fix it. I am using the gTTS and Pygame modules.
from gtts import gTTS
from tempfile import TemporaryFile
from pygame import mixer
#Plays Sound
def play():
mixer.init()
mixer.music.load("Speech.mp3")
mixer.music.play()
#Voice
def voice(x):
text = gTTS(text= x, lang= 'en')
with open("Speech.mp3", 'wb') as f:
text.write_to_fp(f)
f.close()
play()
#Prompts user to enter text for speech
while True:
voice_input = input("What should Wellington Say: ")
voice(voice_input)
Figured it out. I added this function:
def delete():
sleep(2)
mixer.music.load("Holder.mp3")
os.remove("Speech.mp3")
And call it after .play(), so it now simply deletes the file when it is done and then re-creates it when you need to use it next.
To expand on my comment above (with help from this thread), I think play() may be locking the file. You can manually try the following:
def play():
mixer.init()
mixer.music.load("Speech.mp3")
mixer.music.play()
while pygame.mixer.music.get_busy():
pygame.time.Clock().tick(10)
or
def play():
mixer.init()
mixer.music.load("Speech.mp3")
mixer.music.play()
mixer.music.stop()
But this second fix might have the consequence of not hearing anything played back.
I fixed the problem by writing to a temporary file and using os.rename:
from gtts import gTTS
from pygame import mixer
import os
play_name = 'Speech.mp3'
save_name = "%s.%s" % (play_name, '.tmp')
def play():
mixer.music.load(play_name)
mixer.music.play()
def voice(x):
text = gTTS(text=x, lang='en')
with open(save_name, 'wb') as tmp_file:
text.write_to_fp(tmp_file)
os.rename(save_name, play_name)
try:
mixer.init()
while True:
voice_input = raw_input("What should Wellington Say: ")
voice(voice_input)
play()
except KeyboardInterrupt:
pass
I ran a test where I typed in a very long sentence and then another sentence while the first one was playing and everything still worked.

Categories

Resources