Playing music with pyspotify, what am I missing? - python

Im new to Python and I am trying to make a class where I will play some music with the spotify library pyspotify. I have the code below and I taught that it would be playing music if I run the play method. This does not work because I can't hear any music playing, no error messages appear from what I can see. What do I have to do more?
import spotify
import threading
class Music:
session = None
def __init__(self):
logged_in_event = threading.Event()
def connection_state_listener(session):
if session.connection.state is spotify.ConnectionState.LOGGED_IN:
logged_in_event.set()
self.session = spotify.Session()
loop = spotify.EventLoop(self.session)
loop.start()
self.session.on(
spotify.SessionEvent.CONNECTION_STATE_UPDATED,
connection_state_listener)
self.session.login('accountname', 'password')
logged_in_event.wait()
print self.session.connection.state
print self.session.user
def play(self):
track = self.session.get_track('spotify:track:2Foc5Q5nqNiosCNqttzHof')
track.load()
self.session.player.load(track)
self.session.player.play(play=True)
And in another Python file I do:
music = Music.Music()
music.play()

I added the line
audio = spotify.AlsaSink(session)
and now it works!

Related

Python, how to execute a line of code without it stopping the rest of the code from executing?

first of all, im a beginner.
Want i want to accomplish is that music plays while the script is executing.
What it does right now it plays the music, waits until the music is over and then executes the rest of the code. That is not what i want. Here my Code:
import os
import subprocess
import multiprocessing
import threading
from playsound import playsound
CurrentPath = os.path.dirname(os.path.normpath(__file__))
os.chdir(CurrentPath)
def music():
Music = "Music.mp4"
#subprocess.run(["ffplay", "-nodisp", "-autoexit", "-hide_banner", Music])
playsound("Music.mp4")
def other_things():
print("Hello World")
#musicp = multiprocessing.Process(target=music())
#restp = multiprocessing.Process(target=other_things())
musicp = threading.Thread(target=music())
restp = threading.Thread(target=other_things())
restp.start()
musicp.start()
LIke you can see i even tried multithreading but it still waits until the music is over before it goes to the rest of the code.
Don't call the functions in the target parameter of the Thread function - delete the brackets to reference the function, not its return value
musicp = threading.Thread(target=music) # instead of music()
restp = threading.Thread(target=other_things) # instead of other_things()

Playing sound and a program

What I want to do is get an audio file to play while a def (function) is running.
I've looked it up and seen that threading works but it is wayyyy to complicated for me to work out. Is there a way you guys can explain it to me? I was using winsound to play the audio file, and SND_FILENAME.
Try this:
from multiprocessing import Process
def play():
#winsound stuff
def function():
#functiony stuff
if __name__ == '__main__':
p = Process(target=play)
d = Process(target=function)
p.start()
d.start()

How to change the volume of playback in MediaListPlayer with LibVLC?

I'm using a MediaListPlayer instance to execute a playlist. On a standard MediaPlayer instance you can use MediaPlayer.audio_set_volume(newVolume), but when I try to use the same method(audio_set_volume(newVolume)) on a MediaListPLayer instance, I get an error.:
AtributeError: 'MediaListPLayer' object has no attribute 'audio_set_volume'. What is the replacement of that method for the MediaListPlayer?
This is the code:
from vlc import Instance
playlist = ['/home/user/Music/01 Signs.mp3','/home/user/Music/2U.mp3']
player = Instance()
mediaListPlayer = player.media_list_player_new()
mediaList = player.media_list_new()
for element in playlist:
mediaList.add_media(player.media_new(element))
mediaListPlayer.set_media_list(mediaList)
mediaListPlayer.play()
mediaListPlayer.audio_set_volume(80)
Two years later was wondering the same thing. So here is a solution that worked for me:
import vlc
inst = vlc.Instance()
player = inst.media_list_player_new()
media_list = inst.media_list_new(["example.mp3"])
player.set_media_list(media_list)
player.play()
player.get_media_player().audio_set_volume(50)
MediaListPlayer.get_media_player() returns the MediaPlayer that can be used to control the volume of the MediaListPlayer during playback.
As I said in my comment, it does look like an oversight.
However, I have managed to set the initial volume by hacking a sub_player but once it is set and you invoke the list player, I haven't found a way of adjusting it after that.
import vlc
import time
playlist=['/home/rolf/vp1.mp3','/home/rolf/vp.mp3']
inst = vlc.Instance()
sub_player = inst.media_player_new()
player = inst.media_list_player_new()
mediaList = inst.media_list_new(playlist)
player.set_media_list(mediaList)
volume = 60
sub_player.audio_set_volume(volume)
sub_player.play()
playing = set([1,2,3,4])
player.play()
while player.get_state() in playing:
time.sleep(1)
I have posted a question on videolan ,https://forum.videolan.org/viewtopic.php?f=32&t=139505 so someone with a greater knowledge of these things might provide a better solution. If I get an answer, I'll post it here.

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.

using gstreamer, playing a playlist without stopping the sink

I want to add playlist functionality to my music player. The first track in the list plays. And typing "next" in the console and hitting return should start playing the next track but song stops playing and nothing happens.
setting the state to GST_STATE_READY instead of GST_STATE_NULL before
changing the "location" also does not work.
Can someone correct my code and tell me where I am wrong?
import pygst, gobject, time, sys
pygst.require("0.10")
import gst
class AudioPlayer:
def __init__(self):
self.songs = ['Holy Diver.mp3','Paranoid.mp3','Fast as a Shark.mp3']
# create a new gstreamer pipeline
self.pipeline = gst.Pipeline("mypipeline")
# add a file source to the pipeline
self.filesrc = gst.element_factory_make("filesrc","source")
self.pipeline.add(self.filesrc)
# add a generic decoder to the pipeline and link it to thesource
self.decode = gst.element_factory_make("decodebin","decode")
self.decode.connect("new-decoded-pad", self.decode_link)
self.pipeline.add(self.decode)
self.filesrc.link(self.decode)
# add a convertor to the pipeline
self.convert = gst.element_factory_make("audioconvert","convert")
self.pipeline.add(self.convert)
# add an alsa sink to the pipeline and link it to theconvertor
self.sink = gst.element_factory_make("alsasink", "sink")
self.pipeline.add(self.sink)
self.convert.link(self.sink)
# start playing
self.filesrc.set_property("location", self.songs.pop(0))
self.pipeline.set_state(gst.STATE_PLAYING)
def decode_link(self, dbin, pad, islast):
pad.link(self.convert.get_pad("sink"))
def next(self):
self.convert.unlink(self.sink)
self.filesrc.set_state(gst.STATE_NULL)
self.filesrc.set_property("location", self.songs.pop(0))
self.convert.link(self.sink)
self.pipeline.set_state(gst.STATE_PLAYING)
return True
player = AudioPlayer()
loop = gobject.MainLoop()
gobject.threads_init()
context = loop.get_context()
while 1:
value = sys.stdin.readline()
if value == "next\n":
player.next()
context.iteration(True)
In next you are setting the wrong thing to NULL:
self.filesrc.set_state(gst.STATE_NULL)
should be
self.pipeline.set_state(gst.STATE_NULL)
That is the crux of your problem, you aren't stopping the pipeline but also you do not need to unlink and relink self.convert either but that is a side issue.

Categories

Resources