So now we have a functional player. It though lacks a vital feature. There is no tracking over loop. That means every time a user listens to a track, the player stops after playing that track. It does not jump to the next track in our playlist.
Let's provide some radio buttons to let the user choose the looping structure. By the end of this iteration, we will add the following to our player:
In essence, our player should provide choice amongst:
The corresponding code for creating radio buttons in the GUI
class is as follows (see Code 5.05 main-gui.py):
#radio buttons added to create_bottom_frame self.loopv = IntVar() self.loopv.set(3) for txt, val in self.loopchoices: Radiobutton(bottomframe, text=txt, variable=self.loopv, value=val).grid(row=5, column=4+val, pady=3)
Let's look at the player end logic first when a song ends. We need a way to call a method once a song has completed playing. Luckily, the pyglet player allows for an on_eos
(on end of song) callback.
We first modify our existing play_media
method in the player
class to include this callback.(See Code 5.05 player.py)
self.myplayer.push_handlers(on_eos=self.what_next)
This callback is executed on end of a given song. We add the callback to a method named what_next
.
This what_next
method essentially looks for the selected choice on looping and accordingly takes some action. The code for what_next
is as follows:
def what_next(self): if self.stopped: self.stopped = False return None if self.parent.loopv.get() == 1: # No Loop return None if self.parent.loopv.get() == 2: # Loop current self.parent.launch_play() if self.parent.loopv.get() == 3: # Loop All self.fetch_next_track()
The description of the code is listed as follows:
on_eos
callback is also called just in case a track is stopped in the middle. That means that if a stop action occurs, we don't want to do anything next. We, therefore, break out of the method by calling a blank return.self.parent.selectedloopchoice
.1
(No Loop), it does not play the next song, but breaks out of the method with a return statement.2
(loop over the current song), it again calls the launch_play
method without changing the current track.3
(Loop All), it calls another method named fetch_next_track
.The code of fetch_next_track
to fetch the next track is as follows:
def fetch_next_track(self): try: next_trackindx = self.parent.alltracks.index(self.parent.currentTrack) +1 self.parent.currentTrack = self.parent.alltracks[next_trackindx] self.parent.launch_play() except:pass # end of list – do nothing
The description of the code is listed as follows:
launch_play()
to play the next track.This completes the coding of looping in our player.
This iteration relied on the fact that pyglet allows an on_oes
(on end of song) callback. At the end of a track, we use this callback to check the looping choice specified by the user.
If the user does not want to loop through the playlist, we pass a blank return statement. If the user wants to loop over the current song, we call the launch_play
method without incrementing the current track. If the user wants to loop through the entire list, we call a method named fetch_next_track
, which increments the index of song by one, and then calls the launch_play
method to play the next song.
In this iteration, we also saw a sample usage of radio buttons.
Our player is now equipped to loop over a playlist based on preferences provided by the user.
3.129.194.106