Wait for song played outside of python to finish - python

I am trying to wait for a song to finish to play the next song.
I am running python 3.4 on windows but am trying to be able to use it on Linux (raspberry pi).
I have used the command subprocess.call([PLAYER, SONG]) to open the mp3 file. It plays in vlc and then stops. I know that I have not incorporated anything for the program to tell python when its finished.
That's where you guys come in. I want to find a command that will wait until the song has finished and when the song is finished, the rest of the code will process.
I would like the command to be able to used on a Linux operating system and I am trying not to have to install any modules.
If modules are definitely needed, I will install them.

You may use VLC python bindings to get the different information about the VLC player.
There are different methods that can provide your different information. You may achieve your solution by using the get_state(self) method, it provides the state information of the player. So, when the song is completed the VLC state would be stopped.
Sample code:
import vlc
def setup_player(filename):
vlc_instance = vlc.Instance()
media = vlc_instance.media_new(filename)
player = vlc_instance.media_player_new()
player.set_media(media)
player.play()# Start the player
print player.get_state()# Print player's state
player.stop()# Stop the player
print player.get_state()# Print player's state
setup_player('filename')#Put media file name/location here
I hope it was helpful.

Related

python-vlc: Exit the player programatically

I'm trying to play a video using VLC, and close the window after the video is finished. However, I can't close the player window. I tried releasing instances of the player and media, but it doesn't work. And I couldn't find anything else in the API documentation.
Note that I don't want to terminate the whole application after the player finished, so sys.exit is not an option.
The following code is what I'm doing.
import vlc
VIDEO_PATH="/path/to/video.mp4"
def get_end_callback(mediaplayer):
def end_callback(event):
print("End of playing reached")
mediaplayer.stop()
mediaplayer.get_media().release()
mediaplayer.release()
mediaplayer.get_instance().release()
return end_callback
def play():
vlc_instance = vlc.Instance(["--no-xlib"])
media_player = vlc.MediaPlayer(vlc_instance, VIDEO_PATH)
media_player.play()
event_manager = media_player.event_manager()
event_manager.event_attach(vlc.EventType.MediaPlayerEndReached, get_end_callback(media_player))
play()
input("press Enter to exit")
I'm testing it with python=3.9, python-vlc=3.0.12118, vlc=3.0.9.2, on Ubuntu=20.04. I also tried another machine with older OS and older VLC.
So LibVLC will spawn a window to draw on, if you don't provide one. You don't want that, as you won't be able to manage it easily.
Before calling media_player.play(), you want to call media_player.set_hwnd(window.handle) (for Windows) / media_player.set_xwindow(window.xid) (for Linux) with a window handle.
Creating and managing and deleting this window is up to you and it does not have to be your main window of your app.
Here you can find more complete yet minimal samples with Qt and GTK frameworks https://github.com/oaubert/python-vlc/tree/master/examples

Send MIDI data via port on MacOS to Digital Piano

I would like to send midi data from my computer (running MacOS) via a port to my digital piano.
I want to be able to play a midi file, play certain notes for certain durations and potentially change instruments.
I have literally no idea on how to achieve this and cannot find any resources online.
Please provide code with your solution as it would help greatly.
I am using USB-to-Host, to send the data --> not sure if this means anything.
Not sure this qualifies as a decent stack overflow question. There's lots of resources on the internet about MIDI.
The search 'Python MIDI' brings up this repo python-midi.
If you read the README it seems it can do what you wish.
Manually with Garageband:
Connect the digital piano to the computer(MacOS) and turn both on.
Open the midi file with Garageband, which is usually available on MacOS devices.
Then go to Gargageband->Preferences->'Audio/Midi'->'Output Device' dropdown
If the Digital Piano is recognized by the computer, it should be listed in the dropdown. Select it.
Click the 'play' icon on Garageband. The midi file should play with output comming from the digital piano.
Programatically with Mido:
Connect the digital piano to the computer(MacOS) and turn both on.
Install the mido python package
pip install mido
Get the list of midi ports that mido recognizes:
python -c "import mido; print(mido.get_output_names())"
The output should be something like:
['Digital Keyboard', 'IAC Driver Bus 1']
In this example 'Digital Keyboard' is your keyboard.
Your actual keyboard probably has a different name.
NOTE: The 'IAC Driver Bus 1' is a standard MacOS midi output port.
Update the following play-midi.py script by changing 'Digital Keyboard' to the name of your keyboard which mido displayed in #3. Update the *.mid file to the name of your *.mid file.
import mido
# This will list the available ports
print(mido.get_output_names())
# Open the midi link to your keyboard
outport = mido.open_output('Digital Keyboard')
# Open the mid file to be played
mid = mido.MidiFile('my_midi_file.mid', clip=True)
# Play the file out to your keyboard
for msg in mid.play():
outport.send(msg)
Run the script. The sound should play out of your keyboard.
Mido Reference resources:
https://github.com/mido/mido
https://mido.readthedocs.io/en/latest/midi_files.html

playing python game background-music without delaying the actual game

I am making a hangman python game to get to know the python syntax but as the code plays the background music .wav file, the code delays until the end of the music instead of running simultaneously.
I have tried using the os.system command (from the os library) and also subprocess.popen() in order to open the music in a new script window using a different script file but nothing worked.
import os
def music(): #this is the in-game function that is supposed to run the music
os.system("musicforhangmaninit.py")
import winsound #this is the command that plays the .wav file music created earlier by this script
winsound.PlaySound('hangmanadditionals.wav', winsound.SND_FILENAME)
no error messages appeared but I think that I got the os.system() function wrong because it seems to do nothing at all, the subprocess.popen() played the music but still delayed the game. (the goal output was the music playing simultaneously with the game I made)
P.s. : I prefer a solution that works on all the operating systems or at least Linux and windows

Automating windows media player

Any ideas about controling windows media player in Python? I found the following code on the net which runs fine but no audio is played. am using win7 64 bit machine
# this program will play MP3, WMA, MID, WAV files via the WindowsMediaPlayer
from win32com.client import Dispatch
mp = Dispatch("WMPlayer.OCX")
#tune = mp.newMedia("./SleepAway.mp3")
tune = mp.newMedia("./plays.wav")
mp.currentPlaylist.appendItem(tune)
mp.controls.play()
raw_input("Press Enter to stop playing")
mp.controls.stop()
As I have mentioned in comments, I have had an identical problem. I tried a ridiculous number of different approaches. None of them really worked, so I was stuck using os.startfile to open windows media player to play my sound files. However, just today I had an idea which has led to an alternative solution. It is a bit hack-ish, but it works. Technically I still open windows media player with this approach, but I do so using subprocess, and thus I can use the greater control over the process allowed by that to supress the window. This makes it seem like it plays without a secondary application. Why I had to do something so bizarre to get a simple result I have no idea, but it is the only thing that worked. Here is my code for it if you want.
import subprocess
import threading
def windowsmedia(filename):
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
a = subprocess.call('C:\\Program Files (x86)\\Windows Media Player\\wmplayer.exe /play /close "C:/Users/Student/Documents/notes/file.mp3"',startupinfo=startupinfo)
def startmp3(filename):
mythread = threading.Thread(target=windowsmedia,args=[filename])
mythread.start()
time.sleep(15) #You might want to extend this... I just give it 15 seconds to complete before killing the process. It shouldn't be too hard to read the exact length from the file and wait that, or add an interrupt, but that was somewhat unnecessary for my purposes.
pkill("wmplayer") #This is a function of my own but it basically just kills the process. It shouldn't be too hard to reproduce.
Again it is truly regrettable that I had to do something so weird for just playing a sound but as far as you have described it this is the same issue and I hope this helps.
Thought, it might help others who are still facing this issue.
All you had to do is to call PlayItem() API after Play().
from win32com.client import Dispatch
from time import sleep
mp = Dispatch("WMPlayer.OCX")
tune = mp.newMedia("./plays.wav")
mp.currentPlaylist.appendItem(tune)
mp.controls.play()
sleep(1)
mp.controls.playItem(tune)
raw_input("Press Enter to stop playing")
mp.controls.stop()
It helps me to use Windows Media COM. When I tried it, I need to make 2 small modification to make it working in Python Flask.
CoInitialize to make it single thread i.e. pythoncom.CoInitialize() and pythoncom.CoUninitialize()
PumpWaitMessage to keep MediaPlayer working i.e while mp.PlayState != 1: pythoncom.PumpWaitingMessages()

Quit VLC if already running

I am having a weird problem with VLC in Python. Using the following things.
import vlc
self.Instance = vlc.Instance()
self.List = self.Instance.media_list_new()
self.Player_d = self.Instance.media_list_player_new()
I am using self.List.add_media(address of video) to populate the media list.
Then self.Player_d.set_media_list(self.List)
and self.Player_d.play()
The problem is that VLC starts in a weird (YUV something) window, without any controls. Then freezes after playing the list. I have to use Task Manager to shut it down.
Can anybody point out the problem? I want to play the VLC with all controls.
Secondly, is there anyway of checking if VLC is already running, if running, then to quit and start a new instance of VLC.
Any help would be appreciated.
I don't see anything about wxPython in your question, but if you're using it with the vlc module, then that could be your problem. I'm guessing they don't play nicely together. You probably need to run all the vlc stuff in a separate thread rather than in wx's main loop.

Categories

Resources