The most notable difference here is clearly the volume slider, but under the hood I've rewritten just about the whole thing. Here is the current piamp code:
#--------------------------------------------------------------------- # piamp.py # # A Python Media Player # # By: Josh Archer #--------------------------------------------------------------------- import os import pyglet import Tkinter, tkFileDialog dir = pyglet.resource.get_settings_path('Piamp') if not os.path.exists(dir): os.makedirs(dir) configFileName = os.path.join(dir, 'settings.cfg') pyglet.resource.path = ['resources'] pyglet.resource.reindex() batch = pyglet.graphics.Batch() class Piamp(pyglet.window.Window): def __init__(self): super(Piamp, self).__init__() self.set_size(800, 480) #self.set_fullscreen(True) configFile = open(configFileName, 'wt') self.load_graphics() self.canPlay = True self.canMute = True self.mainMenuVisible = True self.frameCount = 0 self.selectedFile = "null" self.mediaType = 'Audio' self.currentVolume = 0.5 self.refresh_player() def load_graphics(self): #Background: self.img_background = pyglet.resource.image('background.png') self.img_background.anchor_x = self.img_background.width/2 self.img_background.anchor_y = self.img_background.height/2 #Main Menu Buttons: self.img_movies = pyglet.resource.image('movies.png') self.img_movies.anchor_x = self.img_movies.width/2 self.img_movies.anchor_y = self.img_movies.height/2 self.img_music = pyglet.resource.image('music.png') self.img_music.anchor_x = self.img_music.width/2 self.img_music.anchor_y = self.img_music.height/2 self.img_shutdown = pyglet.resource.image('shutdown.png') self.img_shutdown.anchor_x = self.img_shutdown.width/2 self.img_shutdown.anchor_y = self.img_shutdown.height/2 self.img_reboot = pyglet.resource.image('reboot.png') self.img_reboot.anchor_x = self.img_reboot.width/2 self.img_reboot.anchor_y = self.img_reboot.height/2 self.img_eq = pyglet.resource.image('equalizer.png') self.img_eq.anchor_x = self.img_eq.width/2 self.img_eq.anchor_y = self.img_eq.height/2 #Player Control Buttons: self.img_mute = pyglet.resource.image('mute.png') self.img_mute.anchor_x = self.img_mute.width/2 self.img_mute.anchor_y = self.img_mute.height/2 self.img_unmute = pyglet.resource.image('unmute.png') self.img_unmute.anchor_x = self.img_unmute.width/2 self.img_unmute.anchor_y = self.img_unmute.height/2 self.img_prev = pyglet.resource.image('previous.png') self.img_prev.anchor_x = self.img_prev.width/2 self.img_prev.anchor_y = self.img_prev.height/2 self.img_rewind = pyglet.resource.image('rewind.png') self.img_rewind.anchor_x = self.img_rewind.width/2 self.img_rewind.anchor_y = self.img_rewind.height/2 self.img_play = pyglet.resource.image('play.png') self.img_play.anchor_x = self.img_play.width/2 self.img_play.anchor_y = self.img_play.height/2 self.img_pause = pyglet.resource.image('pause.png') self.img_pause.anchor_x = self.img_pause.width/2 self.img_pause.anchor_y = self.img_pause.height/2 self.img_ff = pyglet.resource.image('ff.png') self.img_ff.anchor_x = self.img_ff.width/2 self.img_ff.anchor_y = self.img_ff.height/2 self.img_next = pyglet.resource.image('next.png') self.img_next.anchor_x = self.img_next.width/2 self.img_next.anchor_y = self.img_next.height/2 #Volume Control Graphics self.img_volume = pyglet.resource.image('volume.png') self.img_volume.anchor_y = self.img_volume.height/2 self.img_volume_fill = pyglet.resource.image('volume_fill.png') #self.img_volume_fill.anchor_y = self.img_volume_fill.height/2 #self.maxFill = self.img_volume_fill.width def update_sprites(self): #print("Entering update_sprites function...") self.backgroundSprite = pyglet.sprite.Sprite(self.img_background, x=400, y=240, batch=batch) if(self.mainMenuVisible == True): self.mainMenuSprites = [pyglet.sprite.Sprite(self.img_movies, x=280, y=315, batch=batch), pyglet.sprite.Sprite(self.img_music, x=525, y=315, batch=batch), pyglet.sprite.Sprite(self.img_shutdown, x=60, y=425, batch=batch), pyglet.sprite.Sprite(self.img_reboot, x=60, y=305, batch=batch), pyglet.sprite.Sprite(self.img_eq, x=60, y=185, batch=batch)] if(self.canPlay == True and self.canMute == True): self.controlSprites = [pyglet.sprite.Sprite(self.img_mute, x=50, y=108, batch=batch), pyglet.sprite.Sprite(self.img_prev, x=50, y=35, batch=batch), pyglet.sprite.Sprite(self.img_rewind, x=146, y=35, batch=batch), pyglet.sprite.Sprite(self.img_play, x=242, y=35, batch=batch), pyglet.sprite.Sprite(self.img_ff, x=338, y=35, batch=batch), pyglet.sprite.Sprite(self.img_next, x=434, y=35, batch=batch)] if(self.canPlay == False and self.canMute == True): self.controlSprites = [pyglet.sprite.Sprite(self.img_mute, x=50, y=108, batch=batch), pyglet.sprite.Sprite(self.img_prev, x=50, y=35, batch=batch), pyglet.sprite.Sprite(self.img_rewind, x=146, y=35, batch=batch), pyglet.sprite.Sprite(self.img_pause, x=242, y=35, batch=batch), pyglet.sprite.Sprite(self.img_ff, x=338, y=35, batch=batch), pyglet.sprite.Sprite(self.img_next, x=434, y=35, batch=batch)] if(self.canPlay == False and self.canMute == False): self.controlSprites = [pyglet.sprite.Sprite(self.img_unmute, x=50, y=108, batch=batch), pyglet.sprite.Sprite(self.img_prev, x=50, y=35, batch=batch), pyglet.sprite.Sprite(self.img_rewind, x=146, y=35, batch=batch), pyglet.sprite.Sprite(self.img_pause, x=242, y=35, batch=batch), pyglet.sprite.Sprite(self.img_ff, x=338, y=35, batch=batch), pyglet.sprite.Sprite(self.img_next, x=434, y=35, batch=batch)] if(self.canPlay == True and self.canMute == False): self.controlSprites = [pyglet.sprite.Sprite(self.img_unmute, x=50, y=108, batch=batch), pyglet.sprite.Sprite(self.img_prev, x=50, y=35, batch=batch), pyglet.sprite.Sprite(self.img_rewind, x=146, y=35, batch=batch), pyglet.sprite.Sprite(self.img_play, x=242, y=35, batch=batch), pyglet.sprite.Sprite(self.img_ff, x=338, y=35, batch=batch), pyglet.sprite.Sprite(self.img_next, x=434, y=35, batch=batch)] self.volumeSprites = [pyglet.sprite.Sprite(self.img_volume, x=498, y=35, batch=batch), pyglet.sprite.Sprite(self.currentFill, x=498, y=3, batch=batch)] def update_volume_fill(self): self.currentFill = self.img_volume_fill.get_region(x=0, y=0, width=int(self.img_volume_fill.width * self.currentVolume), height=64) def update_volume(self): self.player.volume = self.currentVolume def on_draw(self): self.clear() if(self.frameCount%10 == 0): #print("Resetting frame count") self.frameCount = 0 self.update_volume_fill() self.update_volume() self.update_sprites() batch.draw() self.frameCount += 1 def open_file(self): self.root = Tkinter.Tk() self.root.withdraw() if(self.mediaType == 'Audio'): f = tkFileDialog.askopenfilename(parent = self.root, title = 'Please select an audio file:', filetypes = [('MP3 Files', '.mp3'), ('WAV Files', '.wav'), ('All Files', '.*')], initialdir = 'F:\\Media\\Music\\') if(f): file = f self.root.destroy() return file else: self.root.destroy() return None else: f = tkFileDialog.askopenfilename(parent = self.root, title = 'Please select a video file:', filetypes = [('AVI Files', '.avi'), ('MPEG Files', '.mpeg'), ('MKV Files', '.mkv'), ('All Files', '.*')], initialdir = 'F:\\Media\\Video\\') if(f): file = f self.root.destroy() return file else: self.root.destroy() return None def refresh_player(self): self.player = pyglet.media.Player() @self.player.event('on_eos') def auto_next(): self.next() self.player.volume = self.currentVolume def previous(self): #Go back to the previous file in the current directory self.player.canPlay = True self.player.pause() if(self.player.source != 'null'): #Find the index of the first / from the end of our source filepath sourceIndex = self.selectedFile.rfind('/') #Now we can get the name of the directory (including path) directory = self.selectedFile[:sourceIndex + 1] previousFile = 'null' if(self.mediaType == 'Audio'): for file in os.listdir(directory): if file.endswith('.MP3') or file.endswith('.mp3'): print('Previous Button: Checking ' + file) if(self.selectedFile == (directory + file)): print('Previous Button: Match!') #Found the current file, now we need to check if there is a file before this in the directory, and play that file if there is if(previousFile != 'null'): print('Previous Button: Previous file is ' + previousFile) self.refresh_player() media = pyglet.media.load(directory + previousFile) self.player.queue(media) self.selectedFile = directory + previousFile self.player.play() self.player.canPlay = False else: print('Previous Button: Current file first in directory!') return else: #Assign the current file to previousFile so that we can refer back to it if the next file is the current source previousFile = file if file.endswith('.WAV') or file.endswith('.wav') or file.endswith('.Wav') or file.endswith('.WAv') or file.endswith('.waV') or file.endswith('.wAV'): print('Previous Button: Checking ' + file) if(self.selectedFile == (directory + file)): print('Previous Button: Match!') #Found the current file, now we need to check if there is a file before this in the directory, and play that file if there is if(previousFile != 'null'): print('Previous Button: Previous file is ' + previousFile) self.refresh_player() media = pyglet.media.load(directory + previousFile) self.player.queue(media) self.selectedFile = directory + previousFile self.player.play() self.player.canPlay = False else: print('Previous Button: Current file first in directory!') return else: #Assign the current file to previousFile so that we can refer back to it if the next file is the current source previousFile = file else: print('Previous Button: Source is null!') def next(self): #Go to the next file in the current directory self.player.canPlay = True self.player.pause() if(self.player.source != 'null'): #Find the index of the first / from the end of our source filepath sourceIndex = self.selectedFile.rfind('/') #Now we can get the name of the directory (including path) directory = self.selectedFile[:sourceIndex + 1] foundCurrent = False isLastFile = True if(self.mediaType == 'Audio'): for file in os.listdir(directory): if file.endswith('.MP3') or file.endswith('.mp3') or file.endswith('.mP3') or file.endswith('.Mp3'): if(foundCurrent): print('Next Button: Next file is ' + file) self.refresh_player() media = pyglet.media.load(directory + file) self.player.queue(media) self.selectedFile = (directory + file) self.player.play() self.player.canPlay = False #Use this to tell program we successfully loaded the next file isLastFile = False return if(self.selectedFile == (directory + file)): #Found the current file, so change foundCurrent to True foundCurrent = True if file.endswith('.WAV') or file.endswith('.wav') or file.endswith('.Wav') or file.endswith('.WAv') or file.endswith('.waV') or file.endswith('.wAV'): if(foundCurrent): print('Next Button: Next file is ' + file) self.refresh_player() media = pyglet.media.load(directory + file) self.player.queue(media) self.selectedFile = (directory + file) self.player.play() self.player.canPlay = False #Use this to tell program we successfully loaded the next file isLastFile = False return if(self.selectedFile == (directory + file)): #Found the current file, so change foundCurrent to True foundCurrent = True if(isLastFile): print('Next Button: Current file is last in the directory!') def check_for_button(self, x, y): #Check all button coordinates against x and y, return True if a button was hit or False if not if( (525 - (self.img_music.width / 2)) < x < (525 + (self.img_music.width / 2)) and ( (315 - (self.img_music.height / 2)) < y < (315 + (self.img_music.height / 2)) ) ): #coordinate lies inside the music button if(self.player.playing): self.player.canPlay = True self.player.pause() wasPlaying = True else: wasPlaying = False self.mediaType = 'Audio' filename = self.open_file() if(filename): self.selectedFile = filename print('Opening ' + self.selectedFile + ' ...') #Drop the current queue so we can build a new one by overwriting our player with a fresh one self.refresh_player() media = pyglet.media.load(filename) self.player.queue(media) #Start playback from the selected file self.canPlay = False self.player.play() else: print('Dialog cancelled') if(wasPlaying): self.player.play() if( (280 - (self.img_movies.width / 2)) < x < (280 + (self.img_movies.width / 2)) and ( (315 - (self.img_movies.height /2)) < y < (315 + (self.img_movies.height /2)) ) ): #coordinate lies inside the movies button if(self.player.playing): self.player.canPlay = True self.player.pause() wasPlaying = True else: wasPlaying = False self.mediaType = 'Video' filename = self.open_file() if(filename): self.selectedFile = filename print('Opening ' + self.selectedFile + ' ...') #Drop the current queue so we can build a new one by overwriting our player with a fresh one self.refresh_player() media = pyglet.media.load(filename) self.player.queue(media) #Start playback from the selected file self.canPlay = False self.player.play() else: print('Dialog cancelled') if(wasPlaying): self.player.play() if( (242 - (self.img_play.width / 2)) < x < (242 + (self.img_play.width / 2)) and ( (35 - (self.img_play.height / 2)) < y < (35 + (self.img_play.height / 2)) ) ): #coordinate lies inside the play/pause button if(self.canPlay): print('Play Button: Playing ' + self.selectedFile) self.player.play() self.canPlay = False else: print('Pause Button: Pausing ' + self.selectedFile) self.player.pause() self.canPlay = True if( (434 - (self.img_next.width / 2)) < x < (434 + (self.img_next.width / 2)) and ( (35 - (self.img_next.height / 2)) < y < (35 + (self.img_next.height / 2)) ) ): #coordinate lies inside the next button print('Clicked next button...') self.next() if( (50 - (self.img_prev.width / 2)) < x < (50 + (self.img_prev.width / 2)) and ( (35 - (self.img_prev.height / 2)) < y < (35 + (self.img_prev.height / 2)) ) ): #coordinate lies inside the previous button print('Clicked previous button...') self.previous() if( (50 - (self.img_mute.width / 2)) < x < (50 + (self.img_mute.width / 2)) and ( (108 - (self.img_mute.height / 2)) < y < (108 + (self.img_mute.height / 2)) ) ): #coordinate lies inside the mute/unmute button if(self.canMute): print('Mute Button: Audio Muted!') self.player.volume = 0 self.canMute = False else: print('Mute Button: Audio Unmuted!') self.player.volume = self.currentVolume self.canMute = True if( (146 - (self.img_rewind.width / 2)) < x < (146 + (self.img_rewind.width / 2)) and ( (35 - (self.img_rewind.height / 2)) < y < (35 + (self.img_rewind.height / 2)) ) ): #coordinate lies inside the rewind button if(self.player.playing or self.canPlay): print('Rewind Button: Seeking backwards 10 seconds.') newPosition = self.player.time - 10.0 if(newPosition < 0.0): print('Rewind Button: New time is negative, set to 0 instead.') newPosition = 0.0 self.player.seek(newPosition) if(self.canPlay): pass else: self.player.play() if( (338 - (self.img_ff.width / 2)) < x < (338 + (self.img_ff.width / 2)) and ( (35 - (self.img_ff.height / 2)) < y < (35 + (self.img_ff.height / 2)) ) ): #coordinate lies inside the fast forward button if(self.player.playing or self.canPlay): print('FF Button: Seeking forwards 10 seconds.') newPosition = self.player.time + 10.0 #Note: We don't need to check if the time is past the end of the track because the Player() class will automatically clamp this to the end of the source self.player.seek(newPosition) if(self.canPlay): pass else: self.player.play() self.volumeSprites = [pyglet.sprite.Sprite(self.img_volume, x=498, y=35, batch=batch), pyglet.sprite.Sprite(self.img_volume_fill, x=498, y=35, batch=batch)] if( (498 < x < (498 + self.img_volume.width)) and ( (35 - (self.img_volume.height / 2)) < y < (35 + (self.img_volume.height / 2)) ) ): #coordinate lies inside the volume control #First, we need to convert the image's width to a percentage scale ratio = 100.0 / self.img_volume.width / 100.0 #To make more sense of this, here is an example: #100 / 256 = 0.390625 #If our touch/mouse location was 128 (right in the middle of the image), we want to set our volume to 50%, or 0.5 #Since 128 * 0.390625 = 50, we still need to divide that by 100 to get the percentage (or 0 to 1 decimal) that we want to use. #Therefore, instead of 100 / 256 = 0.390625, we need a ratio of 100 / 256 / 100 = 0.00390625 #Now we need to find our x position in relation to the image, instead of the screen like it currently is local_x = x - 498 #Let's use our new conversion factor to set the volume appropriately self.currentVolume = local_x * ratio def on_mouse_press(self, x, y, button, modifiers): self.check_for_button(x, y) if __name__ == '__main__': window = Piamp() #window.set_mouse_visible(False) pyglet.app.run()
I've decided to utilize Tkinter and tkFileDialog for the file opening window, which looks like this:
This dialog will look different depending on the operating system that runs it. Tkinter works on a variety of operating systems, so it was an easy choice for this functionality.
To give you an idea on the state of the player:
Working:
- Volume Slider
- Previous Button
- Rewind
- Play/Pause
- Fast Forward
- Next Button
- Mute/Unmute
- Music Button (Open audio file)
- Movies Button (Open video file)
Not Yet Implemented:
- Show current selected file in text box
- Shutdown button
- Reboot button
- Equalizer button
- Video Playback - Currently player only plays audio for video files
In case you want to play around with the player (or the code) yourself, here is a zip file of the entire project:
Stay tuned - I'll be finishing up as much as possible tomorrow, and then I'm transferring all of this to the Pi and getting it installed in the car!
No comments:
Post a Comment