def __init__(self, video_dir, gapless=True): self.previous = None self.current = None self.next = None self.video_dir = video_dir self.track_list = os.listdir(self.video_dir) self.list = PlayList(caller=self, maxsize=len(self.track_list))
def init_ui(self): self.main_menu = MainMenu(self) self.setting_dialog = SettingDialog(self) self.title_widget = TitleWidget(self) self.btn_mainmenu = self.title_widget.btn_mainmenu self.btn_min = self.title_widget.btn_min self.btn_max = self.title_widget.btn_max self.btn_close = self.title_widget.btn_close self.controlbar = ControlBar() self.controlbar.setFixedHeight(48) self.btn_open = self.controlbar.btn_open self.btn_play = self.controlbar.btn_play self.btn_pause = self.controlbar.btn_pause self.btn_stop = self.controlbar.btn_stop self.btn_fullscreen = self.controlbar.btn_fullscreen self.btn_playlist = self.controlbar.btn_playlist self.lab_time = self.controlbar.lab_time self.seekslider = self.controlbar.seekslider self.volumeslider = self.controlbar.volumeslider self.video.setMinimumSize(650, 350) #self.playlist = PlayList(_('PlayList')) self.playlist = PlayList() self.playlist.setFixedSize(150, 850) # playlist is hidden by default #self.playlist.hide() title_layout = QtGui.QHBoxLayout() title_layout.addWidget(self.title_widget) center_layout = QtGui.QHBoxLayout() center_layout.addWidget(self.video) center_layout.setSpacing(0) center_layout.addWidget(self.playlist) bottom_layout = QtGui.QHBoxLayout() bottom_layout.addWidget(self.controlbar) main_layout = QtGui.QGridLayout(self) main_layout.addLayout(title_layout, 0, 0) main_layout.addLayout(center_layout, 1, 0) main_layout.setSpacing(0) main_layout.addLayout(bottom_layout, 2, 0, 1, 2) # Fill the window with all contents, no gap in border. main_layout.setContentsMargins(0, 0, 0, 0) self.setLayout(main_layout)
def createPlaylistDock(self): from playlist import PlayList self.next_id = 0 self.playlist = PlayList(self, None) self.playlistdock = QW.QDockWidget() self.playlistdock.setWindowTitle("Playlist") self.playlistdock.setFeatures(QW.QDockWidget.DockWidgetFloatable| QW.QDockWidget.DockWidgetMovable) self.playlistsplit = QW.QSplitter() self.playlistsplit.setOrientation(Q.Qt.Vertical) self.playlistsplit.addWidget(self.playlist) # tv = self.dockprops = Q.QTreeView() # self.playlistsplit.addWidget(tv) self.playlistdock.setWidget(self.playlistsplit)
def test_change_input(self): p = PlayList() p.load_data(StringIO(INPUT)) # below schema in change: # 1. option type is not valid # 2. miss filed 'song_ids' change = """ [ { "type": "invalid_option" } ] """ with self.assertRaises(PlayListException): p.apply_changes(StringIO(change)) change = """ [ { "type": "add_song_to_playlist", "playlist_id": "2" } ] """ with self.assertRaises(PlayListException): p.apply_changes(StringIO(change))
class TestPlayList(unittest.TestCase): """TestPlayList class""" def setUp(self): """Setup method that will run before each test""" self.first_song = Song(title='Fields of Gold', artist='Sting', album='Greatest Hits', length='3:54') self.second_song = Song(title='Desert Rose', artist='Sting', album='Greatest Hits', length='4:12') self.third_song = Song(title='Youth of the nation', artist='POD', album='Greatest Hits', length='3:25') self.playlist = PlayList(name='Best PlayList Ever', repeat=True) self.playlist.add_song(self.first_song) self.playlist.add_songs([self.second_song, self.third_song]) def test_artists(self): """Test generating the proper histogram""" expected_histogram = { 'Sting':2, 'POD':1 } self.assertEqual(expected_histogram, self.playlist.artists()) def test_next_song_repeat(self): """Test whether a playlist in a repeat mode will repeat the song""" songs = [self.playlist.next_song() for x in range(4)] self.assertEqual(self.first_song, songs[len(songs)-1]) def test_next_song_shuffle(self): """Test whether a playlist in a shuffle mode will shuffle its content""" self.playlist.shuffle=True self.playlist.repeat=False songs = [self.playlist.next_song() for x in range(3)] self.assertEqual(3, len(songs)) self.assertTrue(self.playlist.next_song() in songs)
def setUp(self): """Setup method that will run before each test""" self.first_song = Song(title='Fields of Gold', artist='Sting', album='Greatest Hits', length='3:54') self.second_song = Song(title='Desert Rose', artist='Sting', album='Greatest Hits', length='4:12') self.third_song = Song(title='Youth of the nation', artist='POD', album='Greatest Hits', length='3:25') self.playlist = PlayList(name='Best PlayList Ever', repeat=True) self.playlist.add_song(self.first_song) self.playlist.add_songs([self.second_song, self.third_song])
def __init__(self, **kwargs): """ Initialize the screens and the screen manager """ self._store = JsonStore("zenplayer.json") self.playlist = PlayList(self._store) self.sm = ScreenManager() self.playing = PlayingScreen(self, name="main") self.sm.add_widget(self.playing) self.sm.current = "main" if platform not in ['ios', 'android']: self.kb_listener = ZenKeyboardListener(self) Sound.add_state_callback(self.playing.on_sound_state) Sound.add_state_callback(self._on_sound_state) super(Controller, self).__init__(**kwargs) if self._store.exists('state'): state = self._store.get("state") if "volume" in state.keys(): self.volume = state["volume"]
def test_input_valiate(self): p = PlayList() ## playlist's user_id is invalid input = """ { "users" : [{"id" : "1", "name" : "Albin Jaye"} ], "playlists" : [{"id" : "1", "user_id" : "2", "song_ids" : ["1"] } ], "songs": [{"id" : "1", "artist": "Camila Cabello", "title": "Never Be the Same"} ] } """ with self.assertRaises(PlayListException): p.load_data(StringIO(input)) # playlist's song_id is invalid input = """ { "users" : [{"id" : "1", "name" : "Albin Jaye"} ], "playlists" : [{"id" : "1", "user_id" : "1", "song_ids" : ["2"] } ], "songs": [{"id" : "1", "artist": "Camila Cabello", "title": "Never Be the Same"} ] } """ with self.assertRaises(PlayListException): p.load_data(StringIO(input))
def test_normal_case(self): p = PlayList() p.load_data(StringIO(INPUT)) p.apply_changes(StringIO(CHANGE)) output = StringIO() p.gen_output(output) obj = json.loads(output.getvalue()) self.assertEqual(len(obj['users']), 1) self.assertEqual(obj['users'][0]['id'], '1') self.assertEqual(len(obj['playlists']), 2) self.assertEqual(obj['playlists'][0]['id'], '2') self.assertEqual(obj['playlists'][0]['song_ids'], ['1', '2']) self.assertEqual(obj['playlists'][1]['id'], '3') self.assertEqual(obj['playlists'][1]['song_ids'], ['1', '2'])
def test_not_allow_duplicate_song_in_playlist(self): change = """ [ { "type": "add_song_to_playlist", "playlist_id": "1", "song_ids" : ["1"] } ] """ p = PlayList() p.load_data(StringIO(INPUT)) p.apply_changes(StringIO(change)) output = StringIO() p.gen_output(output) obj = json.loads(output.getvalue()) self.assertEqual(len(obj['playlists'][0]['song_ids']), 2)
def test_operate_on_not_exists_song(self): change = """ [ { "type": "add_song_to_playlist", "playlist_id": "1", "song_ids" : ["100"] } ] """ p = PlayList() p.load_data(StringIO(INPUT)) with self.assertRaises(PlayListException): p.apply_changes(StringIO(change))
from playlist import PlayList my_playlist = PlayList() my_playlist.append("Country Roads") my_playlist.append("Heart on Ice") my_playlist.append("Rap God") my_playlist.append("Chicken in the CornBread") my_playlist.print_songs() my_playlist.prepend("Apple Bottom Jeans") my_playlist.print_songs() my_playlist.delete_from_head() my_playlist.print_songs() my_playlist.delete_from_tail() my_playlist.print_songs() print(my_playlist.find('Rap God')) print(my_playlist.find("Chicken in the CornBread")) my_playlist.delete("Heart on Ice") my_playlist.print_songs() my_playlist.reverse() my_playlist.print_songs() my_playlist.append("Country Roads") my_playlist.append("Heart on Ice") my_playlist.append("Rap God") my_playlist.append("Chicken in the CornBread") my_playlist.print_songs() my_playlist.reverse() my_playlist.print_songs()
class Controller(EventDispatcher): """ Controls the playing of audio and coordinates the updating of the playlist and screen displays """ volume = NumericProperty(1.0) advance = True # This flag indicates whether to advance to the next track # once the currently playing one had ended sm = None # THe ScreenManager pos = 0 def __init__(self, **kwargs): """ Initialize the screens and the screen manager """ self._store = JsonStore( join(self._get_settings_folder(), "zenplayer.json")) self.playlist = PlayList(self._store) self.sm = ScreenManager() self.playing = PlayingScreen(self, name="main") self.sm.add_widget(self.playing) self.sm.current = "main" if platform not in ['ios', 'android']: self.kb_listener = ZenKeyboardListener(self.on_key_down, self.playing) Sound.add_state_callback(self.playing.on_sound_state) Sound.add_state_callback(self._on_sound_state) super(Controller, self).__init__(**kwargs) if self._store.exists('state'): state = self._store.get("state") if "volume" in state.keys(): self.volume = state["volume"] @staticmethod def _get_settings_folder(): """ Return the folder when the setting file is stored. """ path = expanduser("~/.zencode") if not exists(path): mkdir(path) return path def _on_sound_state(self, state): """ The sound state has changed. If the track played to the end, move to the next track.""" if state == "finished" and self.advance: self.play_next() def get_current_art(self): return self.playlist.get_current_art() def get_current_info(self): return self.playlist.get_current_info() def get_current_file(self): return self.playlist.get_current_file() @staticmethod def get_pos_length(): return Sound.get_pos_length() def on_key_down(self, keyboard, keycode, text, modifiers): """ React to the keypress event """ key_name = keycode[1] if key_name == "up" or text == "+": self.volume += 0.025 elif key_name == "down" or text == "-": self.volume -= 0.025 elif key_name == "x": self.play_pause() elif key_name == "z": self.play_previous() elif key_name == "v": self.stop() elif key_name == "b": self.play_next() elif key_name == "a": self.show_filebrowser() elif key_name == "p": self.show_playlist() elif key_name == "s": self.show_main() return True def on_volume(self, widget, value): """ Set the volume of the currently playing sound """ if 0.0 > value: self.volume = 0.0 elif value > 1.0: self.volume = 1.0 else: Sound.set_volume(value) self.playing.volume_slider.value = value def play_index(self, index): """ Play the track with the specified playlist index """ Sound.stop() self.playlist.current = index self.play_pause() def play_pause(self): """ Play or pause the currently playing track """ self.advance = True if Sound.state == "playing": self.pos, x = Sound.get_pos_length() Sound.stop() else: audio_file = self.get_current_file() if audio_file: Sound.play(audio_file, self.volume) if self.pos > 0: def set_pos(dt): Sound.seek(self.pos) self.pos = 0 Clock.schedule_once(set_pos, 0.1) def play_next(self): """ Play the next track in the playlist. """ Sound.stop() self.playlist.move_next() self.play_pause() def play_previous(self): """ Play the previous track in the playlist. """ Sound.stop() self.playlist.move_previous() self.play_pause() @staticmethod def set_position(value): """ Set the playing position to the specified value. """ Sound.set_position(value) def save(self): """ Save the state of the the playlist and volume. """ self.playlist.save(self._store) self._store.put("state", volume=self.volume) if "filebrowser" in self.sm.screen_names: self.sm.get_screen("filebrowser").save(self._store) def show_filebrowser(self): """ Switch to the file browser screen """ if "filebrowser" not in self.sm.screen_names: self.sm.add_widget( ZenFileBrowser(self, self.playlist, self._store, name="filebrowser")) self.sm.current = "filebrowser" def show_playlist(self): """ Switch to the playlist screen """ if "playlist" not in self.sm.screen_names: self.sm.add_widget( PlayListScreen(self.sm, self, self.playlist, name="playlist")) self.sm.current = "playlist" def show_main(self): """ Switch to the main playing screen""" self.sm.current = "main" def stop(self): """ Stop any playing audio """ self.advance = False Sound.stop()
def __init__(self, handle): activity.Activity.__init__(self, handle) self.player = None self._alert = None self._playlist_jobject = None self.set_title(_('Jukebox Activity')) self.max_participants = 1 self._toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_toolbar = activity_button.page self._toolbar_box.toolbar.insert(activity_button, 0) self.title_entry = activity_toolbar.title self._view_toolbar = ViewToolbar() self._view_toolbar.connect('go-fullscreen', self.__go_fullscreen_cb) self._view_toolbar.connect('toggle-playlist', self.__toggle_playlist_cb) view_toolbar_button = ToolbarButton( page=self._view_toolbar, icon_name='toolbar-view') self._view_toolbar.show() self._toolbar_box.toolbar.insert(view_toolbar_button, -1) view_toolbar_button.show() self._control_toolbar = Gtk.Toolbar() self._control_toolbar_button = ToolbarButton( page=self._control_toolbar, icon_name='media-playback-start') self._control_toolbar.show() self._toolbar_box.toolbar.insert(self._control_toolbar_button, -1) self._control_toolbar_button.hide() self.set_toolbar_box(self._toolbar_box) self._toolbar_box.show_all() self.connect('key_press_event', self.__key_press_event_cb) self.connect('playlist-finished', self.__playlist_finished_cb) # We want to be notified when the activity gets the focus or # loses it. When it is not active, we don't need to keep # reproducing the video self.connect('notify::active', self.__notify_active_cb) self._video_canvas = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) self._playlist_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.playlist_widget = PlayList() self.playlist_widget.connect('play-index', self.__play_index_cb) self.playlist_widget.connect('missing-tracks', self.__missing_tracks_cb) self.playlist_widget.set_size_request( Gdk.Screen.width() * PLAYLIST_WIDTH_PROP, 0) self.playlist_widget.show() self._playlist_box.pack_start(self.playlist_widget, expand=True, fill=True, padding=0) self._playlist_toolbar = Gtk.Toolbar() move_up = ToolButton("go-up") move_up.set_tooltip(_("Move up")) move_up.connect("clicked", self._move_up_cb) self._playlist_toolbar.insert(move_up, 0) move_down = ToolButton("go-down") move_down.set_tooltip(_("Move down")) move_down.connect("clicked", self._move_down_cb) self._playlist_toolbar.insert(move_down, 1) self._playlist_box.pack_end(self._playlist_toolbar, False, False, 0) self._video_canvas.pack_start(self._playlist_box, False, False, 0) # Create the player just once logging.debug('Instantiating GstPlayer') self.player = GstPlayer() self.player.connect('eos', self.__player_eos_cb) self.player.connect('error', self.__player_error_cb) self.player.connect('play', self.__player_play_cb) self.control = Controls(self, self._toolbar_box.toolbar, self._control_toolbar) self._separator = Gtk.SeparatorToolItem() self._separator.props.draw = False self._separator.set_expand(True) self._separator.show() self._toolbar_box.toolbar.insert(self._separator, -1) self._stop = StopButton(self) self._toolbar_box.toolbar.insert(self._stop, -1) self._empty_widget = Gtk.Label(label="") self._empty_widget.show() self.videowidget = VideoWidget() self.set_canvas(self._video_canvas) self._init_view_area() self.show_all() # need hide the playlist by default self._playlist_box.hide() self._configure_cb() self.player.init_view_area(self.videowidget) self._volume_monitor = Gio.VolumeMonitor.get() self._volume_monitor.connect('mount-added', self.__mount_added_cb) self._volume_monitor.connect('mount-removed', self.__mount_removed_cb) if handle.object_id is None: # The activity was launched from scratch. We need to show # the Empty Widget self.playlist_widget.hide() emptypanel.show(self, 'activity-jukebox', _('No media'), _('Choose media files'), self.control.show_picker_cb) self.control.check_if_next_prev() Gdk.Screen.get_default().connect('size-changed', self._configure_cb)
import xml.dom import xml.etree.cElementTree as ET import json import random from os import walk from os.path import join import sys import vlc import vidlist from playlist import PlayList # read settings # setup xml playlist = PlayList() # fill xml with contents x = vlc.Instance() def handle(index, tpath, trackLength): media = x.media_new(tpath) media.parse() duration = media.get_duration()-1 if duration < 0: print("error: duration is 0 for file " + str(tpath)) print("media state: " + str(media.get_state())) else: playlist.addTrack(index, tpath, duration, trackLength, 0, duration) def handleSegment(index, tpath, trackLength, segstart, segstop):
class GracePlay(QtGui.QWidget): ''' The main window of the GracePlay.''' def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.init_media() self.init_ui() self.setWindowIcon(QtGui.QIcon("icons/72px-video.png")) # Set transparent window #self.setWindowOpacity(1) self.setMinimumSize(800, 450) # set Frameless window self.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.show() def init_media(self): self.media = Phonon.MediaObject(self) self.video = Video(self) self.audio = Phonon.AudioOutput(self) def init_ui(self): self.main_menu = MainMenu(self) self.setting_dialog = SettingDialog(self) self.title_widget = TitleWidget(self) self.btn_mainmenu = self.title_widget.btn_mainmenu self.btn_min = self.title_widget.btn_min self.btn_max = self.title_widget.btn_max self.btn_close = self.title_widget.btn_close self.controlbar = ControlBar() self.controlbar.setFixedHeight(48) self.btn_open = self.controlbar.btn_open self.btn_play = self.controlbar.btn_play self.btn_pause = self.controlbar.btn_pause self.btn_stop = self.controlbar.btn_stop self.btn_fullscreen = self.controlbar.btn_fullscreen self.btn_playlist = self.controlbar.btn_playlist self.lab_time = self.controlbar.lab_time self.seekslider = self.controlbar.seekslider self.volumeslider = self.controlbar.volumeslider self.video.setMinimumSize(650, 350) #self.playlist = PlayList(_('PlayList')) self.playlist = PlayList() self.playlist.setFixedSize(150, 850) # playlist is hidden by default #self.playlist.hide() title_layout = QtGui.QHBoxLayout() title_layout.addWidget(self.title_widget) center_layout = QtGui.QHBoxLayout() center_layout.addWidget(self.video) center_layout.setSpacing(0) center_layout.addWidget(self.playlist) bottom_layout = QtGui.QHBoxLayout() bottom_layout.addWidget(self.controlbar) main_layout = QtGui.QGridLayout(self) main_layout.addLayout(title_layout, 0, 0) main_layout.addLayout(center_layout, 1, 0) main_layout.setSpacing(0) main_layout.addLayout(bottom_layout, 2, 0, 1, 2) # Fill the window with all contents, no gap in border. main_layout.setContentsMargins(0, 0, 0, 0) self.setLayout(main_layout) # Set the drag property of the window -- For press event def mousePressEvent(self, event): if event.button() == QtCore.Qt.LeftButton: self.dragPosition = event.globalPos() - self.frameGeometry().topLeft() event.accept() # Set the drag property of the window move -- For drag move event def mouseMoveEvent(self, event): if event.buttons() == QtCore.Qt.LeftButton: self.move(event.globalPos() - self.dragPosition) event.accept()
def quit_window(widget): mp.quit() gtk.main_quit() def end_media_player(mp): print '播放结束了' mp.player.uri = play_list.get_next_file() mp.play() print "fdjsklfjds" # set_flags(screen) # screen_frame.set(0.0, 0.0, 1.0, 1.0) def rect_error_msg(mp, msg): print "error_msg:", msg play_list = PlayList() play_list.set_state(ORDER_PLAY) play_list.append("http://f.youku.com/player/getFlvPath/sid/00_00/st/flv/fileid/030002010050D29B0C1EB704E9D2A70A597BC9-661F-04B6-2574-7696D26555A6?K=25078da9c15b9aeb261cbce1") play_list.append("file:///home/long/Desktop/test.rmvb") #################################### win = gtk.Window(gtk.WINDOW_TOPLEVEL) win.set_size_request(300, 300) vbox = gtk.VBox() screen_frame = gtk.Alignment() screen_frame.connect("expose-event", draw_screen) screen_frame.set(0, 0, 1, 1) screen = gtk.DrawingArea() screen_frame.add(screen) screen.set_has_window(True) screen.set_can_focus(True)
class TopWindow(Q.QMainWindow): crossfadeChanged = Q.pyqtSignal(int) shutdown = Q.pyqtSignal() cascadeSubWindows = Q.pyqtSignal() childChanged = Q.pyqtSignal(object) def createPlaylistDock(self): from playlist import PlayList self.next_id = 0 self.playlist = PlayList(self, None) self.playlistdock = QW.QDockWidget() self.playlistdock.setWindowTitle("Playlist") self.playlistdock.setFeatures(QW.QDockWidget.DockWidgetFloatable| QW.QDockWidget.DockWidgetMovable) self.playlistsplit = QW.QSplitter() self.playlistsplit.setOrientation(Q.Qt.Vertical) self.playlistsplit.addWidget(self.playlist) # tv = self.dockprops = Q.QTreeView() # self.playlistsplit.addWidget(tv) self.playlistdock.setWidget(self.playlistsplit) # self.playlist.playerChanged.connect(self.setDockModel) # from playlist import PlayList # self.playlist = PlayList(self, None) # self.propertydock = Q.QDockWidget() # self.propertydock.setWindowTitle("Properties") # self.propertydock.setFeatures(Q.QDockWidget.DockWidgetFloatable| Q.QDockWidget.DockWidgetMovable) # self.propertyview = Q.QTableView(self.propertydock) # self.propertymodel= None ## self.propertyview.setModel(self.propertymodel) # def set_propertymodel(player): # if player and player._property_model: # self.propertyview.setModel(player._property_model) # self.playlist.playerChanged.connect(set_propertymodel) # self.propertydock.setWidget(self.propertyview) # self.propertydock.show() # self.playlistdock.setWidget(self.playlist) # def setDockModel(self, player): # if player: # self.dockprops.setModel(player._property_model) # else: # self.dockprops.setModel(None) def onCrossfadeChanged(self, cross): pass # self.players[0].m.volume = (100.- cross)/2 # print( self.players[0].m.volume) # self.players[1].m.volume = (100 + cross )/2 # print( self.players[1].m.volume) # print(cross) def getPlayerAt(self, where = -1): player = None if where >= 0: for p in self.players: if p.index == where: return p if player is None: player = self.makeWidgetFor() self.playlist.updateActions() return player def openFile(self, where = -1 ): prev = self.playlist.player player = self.getPlayerAt(where) self.playlist.player = player self.playlist.openFile() self.playlist.player = prev def openUrl(self, where = -1 ): prev = self.playlist.player player = self.getPlayerAt(where) self.playlist.player = player self.playlist.openUrl() self.playlist.player = prev @property def players(self): return self.findChildren(AVPlayer) def childEvent(self,evt): self.childChanged.emit(evt) def __init__(self,*args,**kwargs): super().__init__() self.setAttribute(Q.Qt.WA_DeleteOnClose) # self.players = list() # self.players = [Player() for _ in range(max(1,n))] mdiArea = Q.QMdiArea(self) self.mdiArea = mdiArea self.setCentralWidget(mdiArea) self.createPlaylistDock() self.addDockWidget(Q.Qt.LeftDockWidgetArea,self.playlistdock) # self.addDockWidget(Q.Qt.BottomDockWidgetArea,self.propertydock) self.playlistdock.fileMenu = self.menuBar().addMenu("&File") fileMenu = self.playlistdock.fileMenu fileMenu.addAction("&Open...",lambda:self.openFile(-1),"Ctrl+O") fileMenu.addAction("Open &Url...",lambda:self.openUrl(-1),"Ctrl_U") fileMenu.addAction("E&xit",self.close,"Ctrl+Q") self.childChanged.connect(self.playlist.updateActions) cf_bar = self.addToolBar("Crossfade") cf_bar.setFloatable(True) cf_bar.setMovable(True) cf = self.crossfade = Q.QSlider(Q.Qt.Horizontal) cf.setRange(-100,100) cf.setEnabled(True) cf.valueChanged.connect(self.crossfadeChanged) self.crossfadeChanged.connect(self.onCrossfadeChanged) cf_bar.addWidget(cf) cf_bar = self.addToolBar(Q.Qt.BottomToolBarArea,cf_bar) winMenu = self.winMenu = self.menuBar().addMenu("&Window") winMenu.addAction("Cl&ose",mdiArea.closeActiveSubWindow) winMenu.addAction("Close&All",mdiArea.closeAllSubWindows) winMenu.addAction("&Tile",mdiArea.tileSubWindows) cascadeAction = winMenu.addAction("&Cascade",self.cascadeSubWindows) cascadeAction.triggered.connect(mdiArea.cascadeSubWindows) winMenu.addAction("Ne&xt",mdiArea.activateNextSubWindow,Q.QKeySequence.NextChild) winMenu.addAction("&Prev",mdiArea.activatePreviousSubWindow,Q.QKeySequence.PreviousChild) mdiArea.subWindowActivated.connect(lambda *x: self.playlist.setPlayer(mdiArea.activeSubWindow())) self.destroyed.connect(self.shutdown,Q.Qt.DirectConnection) self._timer = Q.QTimer() self._timer.setInterval(int(1000/30)) # self._timer.setTimerType(Q.Qt.PreciseTimer) self._timer.timeout.connect(self.update) self._timer.start() frate = kwargs.pop('forcerate',None) if frate: try: self.forcedFrameRate = float(frate) except: pass self._options,media = AVPlayer.get_options(*args) p = self.getPlayerAt(-1) self.playlist.setPlayer(p) if media: self.playlist.updateActions() list(map(self.playlist.onRequestFile,media)) @property def forcedFrameRate(self): return 10000 / self._timer.interval() @forcedFrameRate.setter def forcedFrameRate(self, val): self._timer.setInterval(int(1000/val)) def makeWidgetFor(self,*args, **kwargs): tw = Q.QTabWidget(parent=self) cw = CtrlPlayer(*args, parent=None, **kwargs) tw.addTab(cw,"video") cw.childwidget.resize(self.size()) player = cw.childwidget # player._property_model = AVTreePropertyModel(player=player,parent=player) tv = Q.QTreeView() tv.setModel(player._property_model) tw.addTab(tv,"properties") self._timer.timeout.connect(cw.update) player.index = self.next_id player._playlist = self.playlist self.next_id += 1 # self.cascadeSubWindows.connect(cw.idealConfig) # self.crossfadeChanged.connect(cw.onCrossfadeChanged) self.mdiArea.addSubWindow(tw) tw.adjustSize() tw.parent().adjustSize() tw.parent().update() tw.destroyed.connect(tw.parent().close,Q.Qt.DirectConnection) tw.setVisible(True) return player
class JukeboxActivity(activity.Activity): __gsignals__ = { 'playlist-finished': (GObject.SignalFlags.RUN_FIRST, None, []), } def __init__(self, handle): activity.Activity.__init__(self, handle) self.player = None self._alert = None self._playlist_jobject = None self.set_title(_('Jukebox Activity')) self.max_participants = 1 toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_toolbar = activity_button.page toolbar_box.toolbar.insert(activity_button, 0) self.title_entry = activity_toolbar.title self._view_toolbar = ViewToolbar() self._view_toolbar.connect('go-fullscreen', self.__go_fullscreen_cb) self._view_toolbar.connect('toggle-playlist', self.__toggle_playlist_cb) view_toolbar_button = ToolbarButton(page=self._view_toolbar, icon_name='toolbar-view') self._view_toolbar.show() toolbar_box.toolbar.insert(view_toolbar_button, -1) view_toolbar_button.show() self._control_toolbar = Gtk.Toolbar() self._control_toolbar_button = ToolbarButton( page=self._control_toolbar, icon_name='media-playback-start') self._control_toolbar.show() toolbar_box.toolbar.insert(self._control_toolbar_button, -1) self._control_toolbar_button.hide() self.set_toolbar_box(toolbar_box) toolbar_box.show_all() self.connect('key_press_event', self.__key_press_event_cb) self.connect('playlist-finished', self.__playlist_finished_cb) # We want to be notified when the activity gets the focus or # loses it. When it is not active, we don't need to keep # reproducing the video self.connect('notify::active', self.__notify_active_cb) self._video_canvas = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) self._playlist_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.playlist_widget = PlayList() self.playlist_widget.connect('play-index', self.__play_index_cb) self.playlist_widget.connect('missing-tracks', self.__missing_tracks_cb) self.playlist_widget.set_size_request( Gdk.Screen.width() * PLAYLIST_WIDTH_PROP, 0) self.playlist_widget.show() self._playlist_box.pack_start(self.playlist_widget, expand=True, fill=True, padding=0) self._playlist_toolbar = Gtk.Toolbar() move_up = ToolButton("go-up") move_up.set_tooltip(_("Move up")) move_up.connect("clicked", self._move_up_cb) self._playlist_toolbar.insert(move_up, 0) move_down = ToolButton("go-down") move_down.set_tooltip(_("Move down")) move_down.connect("clicked", self._move_down_cb) self._playlist_toolbar.insert(move_down, 1) self._playlist_box.pack_end(self._playlist_toolbar, False, False, 0) self._video_canvas.pack_start(self._playlist_box, False, False, 0) # Create the player just once logging.debug('Instantiating GstPlayer') self.player = GstPlayer() self.player.connect('eos', self.__player_eos_cb) self.player.connect('error', self.__player_error_cb) self.player.connect('play', self.__player_play_cb) self.control = Controls(self, toolbar_box.toolbar, self._control_toolbar) self._separator = Gtk.SeparatorToolItem() self._separator.props.draw = False self._separator.set_expand(True) self._separator.show() toolbar_box.toolbar.insert(self._separator, -1) self._stop = StopButton(self) toolbar_box.toolbar.insert(self._stop, -1) self._empty_widget = Gtk.Label(label="") self._empty_widget.show() self.videowidget = VideoWidget() self.set_canvas(self._video_canvas) self._init_view_area() self.show_all() # need hide the playlist by default self._playlist_box.hide() self._configure_cb() self.player.init_view_area(self.videowidget) self._volume_monitor = Gio.VolumeMonitor.get() self._volume_monitor.connect('mount-added', self.__mount_added_cb) self._volume_monitor.connect('mount-removed', self.__mount_removed_cb) if handle.object_id is None: # The activity was launched from scratch. We need to show # the Empty Widget self.playlist_widget.hide() emptypanel.show(self, 'activity-jukebox', _('No media'), _('Choose media files'), self.control.show_picker_cb) self.control.check_if_next_prev() Gdk.Screen.get_default().connect('size-changed', self._configure_cb) def _move_up_cb(self, button): self.playlist_widget.move_up() def _move_down_cb(self, button): self.playlist_widget.move_down() def _configure_cb(self, event=None): toolbar = self.get_toolbar_box().toolbar toolbar.remove(self._stop) toolbar.remove(self._separator) if Gdk.Screen.width() < Gdk.Screen.height(): self._control_toolbar_button.show() self._control_toolbar_button.set_expanded(True) self.control.update_layout(landscape=False) toolbar.insert(self._separator, -1) else: self._control_toolbar_button.set_expanded(False) self._control_toolbar_button.hide() self.control.update_layout(landscape=True) toolbar.insert(self._stop, -1) def __notify_active_cb(self, widget, event): """Sugar notify us that the activity is becoming active or inactive. When we are inactive, we stop the player if it is reproducing a video. """ logging.debug('JukeboxActivity notify::active signal received') if self.player.player.props.current_uri is not None and \ self.player.playing_video(): if not self.player.is_playing() and self.props.active: self.player.play() if self.player.is_playing() and not self.props.active: self.player.pause() def _init_view_area(self): """ Use a notebook with two pages, one empty an another with the videowidget """ self.view_area = Gtk.Notebook() self.view_area.set_show_tabs(False) self.view_area.append_page(self._empty_widget, None) self.view_area.append_page(self.videowidget, None) self._video_canvas.pack_end(self.view_area, expand=True, fill=True, padding=0) def _switch_canvas(self, show_video): """Show or hide the video visualization in the canvas. When hidden, the canvas is filled with an empty widget to ensure redrawing. """ if show_video: self.view_area.set_current_page(1) else: self.view_area.set_current_page(0) self._video_canvas.queue_draw() def __key_press_event_cb(self, widget, event): keyname = Gdk.keyval_name(event.keyval) logging.info("Keyname Press: %s, time: %s", keyname, event.time) if self.title_entry.has_focus(): return False if keyname == "space": self.control._button_clicked_cb(None) return True def __playlist_finished_cb(self, widget): self._switch_canvas(show_video=False) self._view_toolbar._show_playlist.set_active(True) self.unfullscreen() # Select the first stream to be played when Play button will # be pressed self.playlist_widget.set_current_playing(0) self.control.check_if_next_prev() def songchange(self, direction): current_playing = self.playlist_widget.get_current_playing() if direction == 'prev' and current_playing > 0: self.play_index(current_playing - 1) elif direction == 'next' and \ current_playing < len(self.playlist_widget._items) - 1: self.play_index(current_playing + 1) else: self.emit('playlist-finished') def play_index(self, index): # README: this line is no more necessary because of the # .playing_video() method # self._switch_canvas(show_video=True) self.playlist_widget.set_current_playing(index) path = self.playlist_widget._items[index]['path'] if self.playlist_widget.check_available_media(path): if self.playlist_widget.is_from_journal(path): path = self.playlist_widget.get_path_from_journal(path) self.control.check_if_next_prev() self.player.set_uri(path) self.player.play() else: self.songchange('next') def __play_index_cb(self, widget, index, path): # README: this line is no more necessary because of the # .playing_video() method # self._switch_canvas(show_video=True) self.playlist_widget.set_current_playing(index) if self.playlist_widget.is_from_journal(path): path = self.playlist_widget.get_path_from_journal(path) self.control.check_if_next_prev() self.player.set_uri(path) self.player.play() def __player_eos_cb(self, widget): self.songchange('next') def _show_error_alert(self, title, msg=None): self._alert = ErrorAlert() self._alert.props.title = title if msg is not None: self._alert.props.msg = msg self.add_alert(self._alert) self._alert.connect('response', self._alert_cancel_cb) self._alert.show() def __mount_added_cb(self, volume_monitor, device): logging.debug('Mountpoint added. Checking...') self.remove_alert(self._alert) self.playlist_widget.update() def __mount_removed_cb(self, volume_monitor, device): logging.debug('Mountpoint removed. Checking...') self.remove_alert(self._alert) self.playlist_widget.update() def __missing_tracks_cb(self, widget, tracks): self._show_missing_tracks_alert(tracks) def _show_missing_tracks_alert(self, tracks): self._alert = Alert() title = _('%s tracks not found.') % len(tracks) self._alert.props.title = title icon = Icon(icon_name='dialog-cancel') self._alert.add_button(Gtk.ResponseType.CANCEL, _('Dismiss'), icon) icon.show() icon = Icon(icon_name='dialog-ok') self._alert.add_button(Gtk.ResponseType.APPLY, _('Details'), icon) icon.show() self.add_alert(self._alert) self._alert.connect('response', self.__missing_tracks_alert_response_cb, tracks) def __missing_tracks_alert_response_cb(self, alert, response_id, tracks): if response_id == Gtk.ResponseType.APPLY: vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox.props.valign = Gtk.Align.CENTER label = Gtk.Label(label='') label.set_markup(_('<b>Missing tracks</b>')) vbox.pack_start(label, False, False, 15) for track in tracks: label = Gtk.Label(label=track['path']) vbox.add(label) _missing_tracks = Gtk.ScrolledWindow() _missing_tracks.add_with_viewport(vbox) _missing_tracks.show_all() self.view_area.append_page(_missing_tracks, None) self.view_area.set_current_page(2) self.remove_alert(alert) def _alert_cancel_cb(self, alert, response_id): self.remove_alert(alert) def __player_play_cb(self, widget): # Do not show the visualization widget if we are playing just # an audio stream def callback(): if self.player.playing_video(): self._switch_canvas(True) else: self._switch_canvas(False) return False # HACK: we need a timeout here because gstreamer returns # n-video = 0 if we call it immediately GObject.timeout_add(1000, callback) def __player_error_cb(self, widget, message, detail): self.player.stop() self.control.set_disabled() logging.error('ERROR MESSAGE: %s', message) logging.error('ERROR DETAIL: %s', detail) file_path = self.playlist_widget._items[ self.playlist_widget.get_current_playing()]['path'] mimetype = mime.get_for_file(file_path) title = _('Error') msg = _('This "%s" file can\'t be played') % mimetype self._switch_canvas(False) self._show_error_alert(title, msg) def can_close(self): # We need to put the Gst.State in NULL so gstreamer can # cleanup the pipeline self.player.stop() return True def read_file(self, file_path): """Load a file from the datastore on activity start.""" logging.debug('JukeBoxAtivity.read_file: %s', file_path) title = self.metadata['title'] self.playlist_widget.load_file(file_path, title) self._view_toolbar._show_playlist.set_active(True) def write_file(self, file_path): def write_playlist_to_file(file_path): """Open the file at file_path and write the playlist. It is saved in audio/x-mpegurl format. """ list_file = open(file_path, 'w') for uri in self.playlist_widget._items: list_file.write('#EXTINF:%s\n' % uri['title']) list_file.write('%s\n' % uri['path']) list_file.close() if not self.metadata['mime_type']: self.metadata['mime_type'] = 'audio/x-mpegurl' if self.metadata['mime_type'] == 'audio/x-mpegurl': write_playlist_to_file(file_path) else: if self._playlist_jobject is None: self._playlist_jobject = \ self.playlist_widget.create_playlist_jobject() # Add the playlist to the playlist jobject description. # This is only done if the activity was not started from a # playlist or from scratch: description = '' for uri in self.playlist_widget._items: description += '%s\n' % uri['title'] self._playlist_jobject.metadata['description'] = description write_playlist_to_file(self._playlist_jobject.file_path) datastore.write(self._playlist_jobject) def __go_fullscreen_cb(self, toolbar): self.fullscreen() def __toggle_playlist_cb(self, toolbar): if self._view_toolbar._show_playlist.get_active(): self._playlist_box.show_all() else: self._playlist_box.hide() self._video_canvas.queue_draw()
def __init__(self, handle): activity.Activity.__init__(self, handle) self.player = None self._alert = None self._playlist_jobject = None self.set_title(_('Jukebox Activity')) self.max_participants = 1 toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_toolbar = activity_button.page toolbar_box.toolbar.insert(activity_button, 0) self.title_entry = activity_toolbar.title self._view_toolbar = ViewToolbar() self._view_toolbar.connect('go-fullscreen', self.__go_fullscreen_cb) self._view_toolbar.connect('toggle-playlist', self.__toggle_playlist_cb) view_toolbar_button = ToolbarButton(page=self._view_toolbar, icon_name='toolbar-view') self._view_toolbar.show() toolbar_box.toolbar.insert(view_toolbar_button, -1) view_toolbar_button.show() self._control_toolbar = Gtk.Toolbar() self._control_toolbar_button = ToolbarButton( page=self._control_toolbar, icon_name='media-playback-start') self._control_toolbar.show() toolbar_box.toolbar.insert(self._control_toolbar_button, -1) self._control_toolbar_button.hide() self.set_toolbar_box(toolbar_box) toolbar_box.show_all() self.connect('key_press_event', self.__key_press_event_cb) self.connect('playlist-finished', self.__playlist_finished_cb) # We want to be notified when the activity gets the focus or # loses it. When it is not active, we don't need to keep # reproducing the video self.connect('notify::active', self.__notify_active_cb) self._video_canvas = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) self._playlist_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.playlist_widget = PlayList() self.playlist_widget.connect('play-index', self.__play_index_cb) self.playlist_widget.connect('missing-tracks', self.__missing_tracks_cb) self.playlist_widget.set_size_request( Gdk.Screen.width() * PLAYLIST_WIDTH_PROP, 0) self.playlist_widget.show() self._playlist_box.pack_start(self.playlist_widget, expand=True, fill=True, padding=0) self._playlist_toolbar = Gtk.Toolbar() move_up = ToolButton("go-up") move_up.set_tooltip(_("Move up")) move_up.connect("clicked", self._move_up_cb) self._playlist_toolbar.insert(move_up, 0) move_down = ToolButton("go-down") move_down.set_tooltip(_("Move down")) move_down.connect("clicked", self._move_down_cb) self._playlist_toolbar.insert(move_down, 1) self._playlist_box.pack_end(self._playlist_toolbar, False, False, 0) self._video_canvas.pack_start(self._playlist_box, False, False, 0) # Create the player just once logging.debug('Instantiating GstPlayer') self.player = GstPlayer() self.player.connect('eos', self.__player_eos_cb) self.player.connect('error', self.__player_error_cb) self.player.connect('play', self.__player_play_cb) self.control = Controls(self, toolbar_box.toolbar, self._control_toolbar) self._separator = Gtk.SeparatorToolItem() self._separator.props.draw = False self._separator.set_expand(True) self._separator.show() toolbar_box.toolbar.insert(self._separator, -1) self._stop = StopButton(self) toolbar_box.toolbar.insert(self._stop, -1) self._empty_widget = Gtk.Label(label="") self._empty_widget.show() self.videowidget = VideoWidget() self.set_canvas(self._video_canvas) self._init_view_area() self.show_all() # need hide the playlist by default self._playlist_box.hide() self._configure_cb() self.player.init_view_area(self.videowidget) self._volume_monitor = Gio.VolumeMonitor.get() self._volume_monitor.connect('mount-added', self.__mount_added_cb) self._volume_monitor.connect('mount-removed', self.__mount_removed_cb) if handle.object_id is None: # The activity was launched from scratch. We need to show # the Empty Widget self.playlist_widget.hide() emptypanel.show(self, 'activity-jukebox', _('No media'), _('Choose media files'), self.control.show_picker_cb) self.control.check_if_next_prev() Gdk.Screen.get_default().connect('size-changed', self._configure_cb)
class GracePlay(QtGui.QWidget): ''' The main window of the GracePlay.''' def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.init_media() self.init_ui() self.setWindowIcon(QtGui.QIcon("icons/72px-video.png")) # Set transparent window #self.setWindowOpacity(1) self.setMinimumSize(800, 450) # set Frameless window self.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.show() def init_media(self): self.media = Phonon.MediaObject(self) self.video = Video(self) self.audio = Phonon.AudioOutput(self) def init_ui(self): self.main_menu = MainMenu(self) self.setting_dialog = SettingDialog(self) self.title_widget = TitleWidget(self) self.btn_mainmenu = self.title_widget.btn_mainmenu self.btn_min = self.title_widget.btn_min self.btn_max = self.title_widget.btn_max self.btn_close = self.title_widget.btn_close self.controlbar = ControlBar() self.controlbar.setFixedHeight(48) self.btn_open = self.controlbar.btn_open self.btn_play = self.controlbar.btn_play self.btn_pause = self.controlbar.btn_pause self.btn_stop = self.controlbar.btn_stop self.btn_fullscreen = self.controlbar.btn_fullscreen self.btn_playlist = self.controlbar.btn_playlist self.lab_time = self.controlbar.lab_time self.seekslider = self.controlbar.seekslider self.volumeslider = self.controlbar.volumeslider self.video.setMinimumSize(650, 350) #self.playlist = PlayList(_('PlayList')) self.playlist = PlayList() self.playlist.setFixedSize(150, 850) # playlist is hidden by default #self.playlist.hide() title_layout = QtGui.QHBoxLayout() title_layout.addWidget(self.title_widget) center_layout = QtGui.QHBoxLayout() center_layout.addWidget(self.video) center_layout.setSpacing(0) center_layout.addWidget(self.playlist) bottom_layout = QtGui.QHBoxLayout() bottom_layout.addWidget(self.controlbar) main_layout = QtGui.QGridLayout(self) main_layout.addLayout(title_layout, 0, 0) main_layout.addLayout(center_layout, 1, 0) main_layout.setSpacing(0) main_layout.addLayout(bottom_layout, 2, 0, 1, 2) # Fill the window with all contents, no gap in border. main_layout.setContentsMargins(0, 0, 0, 0) self.setLayout(main_layout) # Set the drag property of the window -- For press event def mousePressEvent(self, event): if event.button() == QtCore.Qt.LeftButton: self.dragPosition = event.globalPos() - self.frameGeometry( ).topLeft() event.accept() # Set the drag property of the window move -- For drag move event def mouseMoveEvent(self, event): if event.buttons() == QtCore.Qt.LeftButton: self.move(event.globalPos() - self.dragPosition) event.accept()
# i=0 # while i <len(lista): # print(lista[i]) # i=i+1 # def mostrar(s="Hello", n=2): # for i in range (0, n): # print(s) # # mostrar('Michael', 4) from cancion import Cancion from playlist import PlayList l = PlayList() while True: print('1 Agregar Cancion') print('2 Mostrar Cnaciones') print('0 Salir') op = input() if op == '1': cancion = Cancion() cancion.artista = input("Artista") cancion.album = input("Album") cancion.titulo = input("Titulo") cancion.duracion = int(input("Duaracion")) l.agregar(cancion) elif op == '2':
class JukeboxActivity(activity.Activity): __gsignals__ = { 'playlist-finished': (GObject.SignalFlags.RUN_FIRST, None, []), } def __init__(self, handle): activity.Activity.__init__(self, handle) self.player = None self._alert = None self._playlist_jobject = None self.set_title(_('Jukebox Activity')) self.max_participants = 1 self._toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_toolbar = activity_button.page self._toolbar_box.toolbar.insert(activity_button, 0) self.title_entry = activity_toolbar.title self._view_toolbar = ViewToolbar() self._view_toolbar.connect('go-fullscreen', self.__go_fullscreen_cb) self._view_toolbar.connect('toggle-playlist', self.__toggle_playlist_cb) view_toolbar_button = ToolbarButton( page=self._view_toolbar, icon_name='toolbar-view') self._view_toolbar.show() self._toolbar_box.toolbar.insert(view_toolbar_button, -1) view_toolbar_button.show() self._control_toolbar = Gtk.Toolbar() self._control_toolbar_button = ToolbarButton( page=self._control_toolbar, icon_name='media-playback-start') self._control_toolbar.show() self._toolbar_box.toolbar.insert(self._control_toolbar_button, -1) self._control_toolbar_button.hide() self.set_toolbar_box(self._toolbar_box) self._toolbar_box.show_all() self.connect('key_press_event', self.__key_press_event_cb) self.connect('playlist-finished', self.__playlist_finished_cb) # We want to be notified when the activity gets the focus or # loses it. When it is not active, we don't need to keep # reproducing the video self.connect('notify::active', self.__notify_active_cb) self._video_canvas = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) self._playlist_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.playlist_widget = PlayList() self.playlist_widget.connect('play-index', self.__play_index_cb) self.playlist_widget.connect('missing-tracks', self.__missing_tracks_cb) self.playlist_widget.set_size_request( Gdk.Screen.width() * PLAYLIST_WIDTH_PROP, 0) self.playlist_widget.show() self._playlist_box.pack_start(self.playlist_widget, expand=True, fill=True, padding=0) self._playlist_toolbar = Gtk.Toolbar() move_up = ToolButton("go-up") move_up.set_tooltip(_("Move up")) move_up.connect("clicked", self._move_up_cb) self._playlist_toolbar.insert(move_up, 0) move_down = ToolButton("go-down") move_down.set_tooltip(_("Move down")) move_down.connect("clicked", self._move_down_cb) self._playlist_toolbar.insert(move_down, 1) self._playlist_box.pack_end(self._playlist_toolbar, False, False, 0) self._video_canvas.pack_start(self._playlist_box, False, False, 0) # Create the player just once logging.debug('Instantiating GstPlayer') self.player = GstPlayer() self.player.connect('eos', self.__player_eos_cb) self.player.connect('error', self.__player_error_cb) self.player.connect('play', self.__player_play_cb) self.control = Controls(self, self._toolbar_box.toolbar, self._control_toolbar) self._separator = Gtk.SeparatorToolItem() self._separator.props.draw = False self._separator.set_expand(True) self._separator.show() self._toolbar_box.toolbar.insert(self._separator, -1) self._stop = StopButton(self) self._toolbar_box.toolbar.insert(self._stop, -1) self._empty_widget = Gtk.Label(label="") self._empty_widget.show() self.videowidget = VideoWidget() self.set_canvas(self._video_canvas) self._init_view_area() self.show_all() # need hide the playlist by default self._playlist_box.hide() self._configure_cb() self.player.init_view_area(self.videowidget) self._volume_monitor = Gio.VolumeMonitor.get() self._volume_monitor.connect('mount-added', self.__mount_added_cb) self._volume_monitor.connect('mount-removed', self.__mount_removed_cb) if handle.object_id is None: # The activity was launched from scratch. We need to show # the Empty Widget self.playlist_widget.hide() emptypanel.show(self, 'activity-jukebox', _('No media'), _('Choose media files'), self.control.show_picker_cb) self.control.check_if_next_prev() Gdk.Screen.get_default().connect('size-changed', self._configure_cb) def _move_up_cb(self, button): self.playlist_widget.move_up() def _move_down_cb(self, button): self.playlist_widget.move_down() def _configure_cb(self, event=None): self._toolbar_box.toolbar.remove(self._stop) self._toolbar_box.toolbar.remove(self._separator) if Gdk.Screen.width() < Gdk.Screen.height(): self._control_toolbar_button.show() self._control_toolbar_button.set_expanded(True) self.control.update_layout(landscape=False) self._toolbar_box.toolbar.insert(self._separator, -1) else: self._control_toolbar_button.set_expanded(False) self._control_toolbar_button.hide() self.control.update_layout(landscape=True) self._toolbar_box.toolbar.insert(self._stop, -1) def __notify_active_cb(self, widget, event): """Sugar notify us that the activity is becoming active or inactive. When we are inactive, we stop the player if it is reproducing a video. """ logging.debug('JukeboxActivity notify::active signal received') if self.player.player.props.current_uri is not None and \ self.player.playing_video(): if not self.player.is_playing() and self.props.active: self.player.play() if self.player.is_playing() and not self.props.active: self.player.pause() def _init_view_area(self): """ Use a notebook with two pages, one empty an another with the videowidget """ self.view_area = Gtk.Notebook() self.view_area.set_show_tabs(False) self.view_area.append_page(self._empty_widget, None) self.view_area.append_page(self.videowidget, None) self._video_canvas.pack_end(self.view_area, expand=True, fill=True, padding=0) def _switch_canvas(self, show_video): """Show or hide the video visualization in the canvas. When hidden, the canvas is filled with an empty widget to ensure redrawing. """ if show_video: self.view_area.set_current_page(1) else: self.view_area.set_current_page(0) self._video_canvas.queue_draw() def __key_press_event_cb(self, widget, event): keyname = Gdk.keyval_name(event.keyval) logging.info("Keyname Press: %s, time: %s", keyname, event.time) if self.title_entry.has_focus(): return False if keyname == "space": self.control._button_clicked_cb(None) return True def __playlist_finished_cb(self, widget): self._switch_canvas(show_video=False) self._view_toolbar._show_playlist.set_active(True) self.unfullscreen() # Select the first stream to be played when Play button will # be pressed self.playlist_widget.set_current_playing(0) self.control.check_if_next_prev() def songchange(self, direction): current_playing = self.playlist_widget.get_current_playing() if direction == 'prev' and current_playing > 0: self.play_index(current_playing - 1) elif direction == 'next' and \ current_playing < len(self.playlist_widget._items) - 1: self.play_index(current_playing + 1) else: self.emit('playlist-finished') def play_index(self, index): # README: this line is no more necessary because of the # .playing_video() method # self._switch_canvas(show_video=True) self.playlist_widget.set_current_playing(index) path = self.playlist_widget._items[index]['path'] if self.playlist_widget.check_available_media(path): if self.playlist_widget.is_from_journal(path): path = self.playlist_widget.get_path_from_journal(path) self.control.check_if_next_prev() self.player.set_uri(path) self.player.play() else: self.songchange('next') def __play_index_cb(self, widget, index, path): # README: this line is no more necessary because of the # .playing_video() method # self._switch_canvas(show_video=True) self.playlist_widget.set_current_playing(index) if self.playlist_widget.is_from_journal(path): path = self.playlist_widget.get_path_from_journal(path) self.control.check_if_next_prev() self.player.set_uri(path) self.player.play() def __player_eos_cb(self, widget): self.songchange('next') def _show_error_alert(self, title, msg=None): self._alert = ErrorAlert() self._alert.props.title = title if msg is not None: self._alert.props.msg = msg self.add_alert(self._alert) self._alert.connect('response', self._alert_cancel_cb) self._alert.show() def __mount_added_cb(self, volume_monitor, device): logging.debug('Mountpoint added. Checking...') self.remove_alert(self._alert) self.playlist_widget.update() def __mount_removed_cb(self, volume_monitor, device): logging.debug('Mountpoint removed. Checking...') self.remove_alert(self._alert) self.playlist_widget.update() def __missing_tracks_cb(self, widget, tracks): self._show_missing_tracks_alert(tracks) def _show_missing_tracks_alert(self, tracks): self._alert = Alert() title = _('%s tracks not found.') % len(tracks) self._alert.props.title = title icon = Icon(icon_name='dialog-cancel') self._alert.add_button(Gtk.ResponseType.CANCEL, _('Dismiss'), icon) icon.show() icon = Icon(icon_name='dialog-ok') self._alert.add_button(Gtk.ResponseType.APPLY, _('Details'), icon) icon.show() self.add_alert(self._alert) self._alert.connect( 'response', self.__missing_tracks_alert_response_cb, tracks) def __missing_tracks_alert_response_cb(self, alert, response_id, tracks): if response_id == Gtk.ResponseType.APPLY: vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox.props.valign = Gtk.Align.CENTER label = Gtk.Label(label='') label.set_markup(_('<b>Missing tracks</b>')) vbox.pack_start(label, False, False, 15) for track in tracks: label = Gtk.Label(label=track['path']) vbox.add(label) _missing_tracks = Gtk.ScrolledWindow() _missing_tracks.add_with_viewport(vbox) _missing_tracks.show_all() self.view_area.append_page(_missing_tracks, None) self.view_area.set_current_page(2) self.remove_alert(alert) def _alert_cancel_cb(self, alert, response_id): self.remove_alert(alert) def __player_play_cb(self, widget): # Do not show the visualization widget if we are playing just # an audio stream def callback(): if self.player.playing_video(): self._switch_canvas(True) else: self._switch_canvas(False) return False # HACK: we need a timeout here because gstreamer returns # n-video = 0 if we call it immediately GObject.timeout_add(1000, callback) def __player_error_cb(self, widget, message, detail): self.player.stop() self.control.set_disabled() logging.error('ERROR MESSAGE: %s', message) logging.error('ERROR DETAIL: %s', detail) file_path = self.playlist_widget._items[ self.playlist_widget.get_current_playing()]['path'] mimetype = mime.get_for_file(file_path) title = _('Error') msg = _('This "%s" file can\'t be played') % mimetype self._switch_canvas(False) self._show_error_alert(title, msg) def can_close(self): # We need to put the Gst.State in NULL so gstreamer can # cleanup the pipeline self.player.stop() return True def read_file(self, file_path): """Load a file from the datastore on activity start.""" logging.debug('JukeBoxAtivity.read_file: %s', file_path) title = self.metadata['title'] self.playlist_widget.load_file(file_path, title) self._view_toolbar._show_playlist.set_active(True) def write_file(self, file_path): def write_playlist_to_file(file_path): """Open the file at file_path and write the playlist. It is saved in audio/x-mpegurl format. """ list_file = open(file_path, 'w') for uri in self.playlist_widget._items: list_file.write('#EXTINF:%s\n' % uri['title']) list_file.write('%s\n' % uri['path']) list_file.close() if not self.metadata['mime_type']: self.metadata['mime_type'] = 'audio/x-mpegurl' if self.metadata['mime_type'] == 'audio/x-mpegurl': write_playlist_to_file(file_path) else: if self._playlist_jobject is None: self._playlist_jobject = \ self.playlist_widget.create_playlist_jobject() # Add the playlist to the playlist jobject description. # This is only done if the activity was not started from a # playlist or from scratch: description = '' for uri in self.playlist_widget._items: description += '%s\n' % uri['title'] self._playlist_jobject.metadata['description'] = description write_playlist_to_file(self._playlist_jobject.file_path) datastore.write(self._playlist_jobject) def __go_fullscreen_cb(self, toolbar): self.fullscreen() def __toggle_playlist_cb(self, toolbar): if self._view_toolbar._show_playlist.get_active(): self._playlist_box.show_all() else: self._playlist_box.hide() self._video_canvas.queue_draw()
def __init__(self, directory): """Constructor""" self.directory = directory self.extension = ".mp3" self.playlist = PlayList()
class Player(): def __init__(self, video_dir, gapless=True): self.previous = None self.current = None self.next = None self.video_dir = video_dir self.track_list = os.listdir(self.video_dir) self.list = PlayList(caller=self, maxsize=len(self.track_list)) def initial_load(self): if len(self.track_list) == 0: self.display_logo() elif len(self.track_list) == 1: self.current = OmxDriver('widget', '') self.play_loop(self.current) else: self.list.populate(self.track_list) self.current = OmxDriver('widget', '') self.next = OmxDriver('widget', '') self.current.load( self.get_video_path(self.video_dir, self.list.get())) self.next.load_and_pause( self.get_video_path(self.video_dir, self.list.get())) self.continuous_play() def continuous_play(self): try: while True: self.current.pause_at_end() self.next.unpause() self.previous = self.current self.previous.terminate('play finished') self.current = self.next # self.next = self.previous self.next = OmxDriver('widget', '') try: next_track = self.list.get() except Empty: logging.info('empty queue, re-populating') self.list.populate(self.track_list) next_track = self.list.get() self.next.load_and_pause( self.get_video_path(self.video_dir, next_track)) #dbug info # print('continuous play loop finished') # import psutil # pid = os.getpid() # ps = psutil.Process(pid) # print('memory used = ' + str(ps.memory_info())) # import gc # print('object used' + str(gc.get_count())) except KeyboardInterrupt: try: self.previous.terminate() self.current.terminate() self.next.terminate() except: pass finally: exit(1) def continuous_play_single_loop(self): try: self.current.pause_at_end() self.next.unpause() self.previous = self.current self.previous.terminate('play finished') self.current = self.next # self.next = self.previous self.next = OmxDriver('widget', '') try: next_track = self.list.get() except Empty: logging.info('empty queue, re-populating') self.list.populate(self.track_list) next_track = self.list.get() self.next.load_and_pause( self.get_video_path(self.video_dir, next_track)) except KeyboardInterrupt: try: self.previous.terminate() self.current.terminate() self.next.terminate() except: pass finally: exit(1) def get_video_path(self, video_dir, video_name): return video_dir + '/' + video_name def play_loop(self, driver): self.list.populate(self.track_list) self.current = OmxDriver('widget', '') try: self.current.load( self.get_video_path(self.video_dir, self.list.get()), ' --loop ') except KeyboardInterrupt: self.current.terminate('keyboard interruption') def display_logo(self): raise NotImplementedError
class Controller(EventDispatcher): """ Controls the playing of audio and coordinates the updating of the playlist and screen displays """ volume = NumericProperty(1.0) advance = True # This flag indicates whether to advance to the next track # once the currently playing one had ended sm = None # THe ScreenManager pos = 0 def __init__(self, **kwargs): """ Initialize the screens and the screen manager """ self._store = JsonStore(join(self._get_settings_folder(), "zenplayer.json")) self.playlist = PlayList(self._store) self.sm = ScreenManager() self.playing = PlayingScreen(self, name="main") self.sm.add_widget(self.playing) self.sm.current = "main" if platform not in ['ios', 'android']: self.kb_listener = ZenKeyboardListener(self.on_key_down, self.playing) Sound.add_state_callback(self.playing.on_sound_state) Sound.add_state_callback(self._on_sound_state) super(Controller, self).__init__(**kwargs) if self._store.exists('state'): state = self._store.get("state") if "volume" in state.keys(): self.volume = state["volume"] @staticmethod def _get_settings_folder(): """ Return the folder when the setting file is stored. """ path = expanduser("~/.zencode") if not exists(path): mkdir(path) return path def _on_sound_state(self, state): """ The sound state has changed. If the track played to the end, move to the next track.""" if state == "finished" and self.advance: self.play_next() def get_current_art(self): return self.playlist.get_current_art() def get_current_info(self): return self.playlist.get_current_info() def get_current_file(self): return self.playlist.get_current_file() @staticmethod def get_pos_length(): return Sound.get_pos_length() def on_key_down(self, keyboard, keycode, text, modifiers): """ React to the keypress event """ key_name = keycode[1] if key_name == "up" or text == "+": self.volume += 0.025 elif key_name == "down" or text == "-": self.volume -= 0.025 elif key_name == "x": self.play_pause() elif key_name == "z": self.play_previous() elif key_name == "v": self.stop() elif key_name == "b": self.play_next() elif key_name == "a": self.show_filebrowser() elif key_name == "p": self.show_playlist() elif key_name == "s": self.show_main() return True def on_volume(self, widget, value): """ Set the volume of the currently playing sound """ if 0.0 > value: self.volume = 0.0 elif value > 1.0: self.volume = 1.0 else: Sound.set_volume(value) self.playing.volume_slider.value = value def play_index(self, index): """ Play the track with the specified playlist index """ Sound.stop() self.playlist.current = index self.play_pause() def play_pause(self): """ Play or pause the currently playing track """ self.advance = True if Sound.state == "playing": self.pos, x = Sound.get_pos_length() Sound.stop() else: audio_file = self.get_current_file() if audio_file: Sound.play(audio_file, self.volume) if self.pos > 0: def set_pos(dt): Sound.seek(self.pos) self.pos = 0 Clock.schedule_once(set_pos, 0.1) def play_next(self): """ Play the next track in the playlist. """ Sound.stop() self.playlist.move_next() self.play_pause() def play_previous(self): """ Play the previous track in the playlist. """ Sound.stop() self.playlist.move_previous() self.play_pause() @staticmethod def set_position(value): """ Set the playing position to the specified value. """ Sound.set_position(value) def save(self): """ Save the state of the the playlist and volume. """ self.playlist.save(self._store) self._store.put("state", volume=self.volume) if "filebrowser" in self.sm.screen_names: self.sm.get_screen("filebrowser").save(self._store) def show_filebrowser(self): """ Switch to the file browser screen """ if "filebrowser" not in self.sm.screen_names: self.sm.add_widget(ZenFileBrowser(self, self.playlist, self._store, name="filebrowser")) self.sm.current = "filebrowser" def show_playlist(self): """ Switch to the playlist screen """ if "playlist" not in self.sm.screen_names: self.sm.add_widget(PlayListScreen(self.sm, self, self.playlist, name="playlist")) self.sm.current = "playlist" def show_main(self): """ Switch to the main playing screen""" self.sm.current = "main" def stop(self): """ Stop any playing audio """ self.advance = False Sound.stop()
class MusicCrawler(): """MusicCrawler class""" def __init__(self, directory): """Constructor""" self.directory = directory self.extension = ".mp3" self.playlist = PlayList() def generate_playlist(self): """ Generates the playlist from directory with .mp3 files """ mp3s = self.find_all_extension_files(self.directory, self.extension) for mp3 in mp3s: dest = self.join_mp3_and_path(self.directory, mp3) data = mutagen.File(dest) tags = self._extract_mp3_targs(data) s = Song(tags["title"], tags["artist"], tags["album"], tags["length"], dest) self.playlist.add_song(s) def join_mp3_and_path(self, dir, mp3): """ Joins a directory and mp3 object into 1 path :return: a new path created object """ return os.path.join(dir, mp3) def _extract_mp3_targs(self, mp3_object): """ Extract mp3 tags from an mp3 file. The extracted tags are represented as a key-value pairs. :param mp3_object: mp3 from which the tags will be extracted :return: dictionary """ tags = {} try: tags["artist"] = mp3_object["TPE1"].text[0] except: tags["artist"] = "Unknown Artist" try: tags["album"] = mp3_object["TALB"].text[0] except: tags["album"] = "Unknown Album" try: tags["title"] = mp3_object["TIT2"].text[0] except: tags["title"] = "Unknown Title" try: m, s = divmod(mp3_object.info.length, 60) h, m = divmod(m, 60) tags["length"] = "%d:%02d:%02d" % (h, m, s) except: tags["length"] = "Unknown Length" return tags def find_all_extension_files(self, directory, extension): """ Finds all mp3 files in a directory :param directory: directory where to look for :extension: the type of the extension :return: list """ return [x for x in os.listdir(directory) if x.endswith(extension)]