class EmbeddedPlayerPanel(wx.Panel): """ The Embedded Player consists of a VLCWindow and the media controls such as Play/Pause buttons and Volume Control. """ VIDEO_SIZE = (320, 240) def __init__(self, parent, utility, vlcwrap, bg): wx.Panel.__init__(self, parent, -1) self.utility = utility self.guiutility = utility.guiUtility self.parent = parent self.SetBackgroundColour(DEFAULT_BACKGROUND) self.volume = 0.48 self.oldvolume = 0.48 self.estduration = None self.fullscreenwindow = None self.download = None self.update = True self.timeoffset = None vSizer = wx.BoxSizer(wx.VERTICAL) self.vlcwrap = vlcwrap if vlcwrap: self.vlcwin = VLCWindow(self, vlcwrap) self.vlcwin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE) vSizer.Add(self.vlcwin, 1, wx.EXPAND, 0) self.logowin = LogoWindow(self) self.logowin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE) vSizer.Add(self.logowin, 1, wx.EXPAND, 0) self.ctrlpanel = FancyPanel(self, border=wx.TOP) self.ctrlpanel.SetMinSize((-1, 30)) self.ctrlpanel.SetBorderColour(SEPARATOR_GREY) self.ctrlpanel.SetBackgroundColour(GRADIENT_LGREY, GRADIENT_DGREY) self.ctrlsizer = wx.BoxSizer(wx.HORIZONTAL) self.slider = VideoSlider(self.ctrlpanel) self.slider.Enable(False) self.timeposition = TransparentText(self.ctrlpanel, -1, "--:-- / --:--") self.bmp_muted = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_muted.png")) self.bmp_unmuted = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_unmuted.png")) self.mute = ActionButton(self.ctrlpanel, -1, self.bmp_unmuted) self.mute.Bind(wx.EVT_LEFT_UP, self.MuteClicked) self.bmp_pause = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_pause.png")) self.bmp_play = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_play.png")) self.ppbtn = ActionButton(self.ctrlpanel, -1, self.bmp_play) self.ppbtn.Bind(wx.EVT_LEFT_UP, self.PlayPause) self.ppbtn.Enable(False) self.sbtn = ActionButton(self.ctrlpanel, -1, wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_stop.png"))) self.sbtn.Bind(wx.EVT_LEFT_UP, self.OnStop) self.sbtn.Enable(False) self.volctrl = VideoVolume(self.ctrlpanel, -1) self.volctrl.SetVolumeHandler(self.OnVolumeChanged) self.volctrl.SetValue(self.volume) self.volctrl.SetMinSize((30, 17)) self.fsbtn = ActionButton(self.ctrlpanel, -1, wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_fullscreen.png"))) self.fsbtn.Bind(wx.EVT_LEFT_UP, self.FullScreen) self.fsbtn.Enable(False) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlsizer.Add(self.ppbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlsizer.Add(self.sbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlsizer.Add(self.slider, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5) self.ctrlsizer.Add(self.timeposition, 0, wx.ALIGN_CENTER_VERTICAL) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlsizer.Add(self.mute, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1) self.ctrlsizer.AddSpacer((5, -1)) self.ctrlsizer.Add(self.volctrl, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlsizer.Add(self.fsbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlpanel.SetSizer(self.ctrlsizer) vSizer.Add(self.ctrlpanel, 0, wx.ALIGN_BOTTOM | wx.EXPAND) self.SetSizer(vSizer) self.playtimer = None self.timer = None if self.vlcwrap: self.SetMinSize((EmbeddedPlayerPanel.VIDEO_SIZE[0], -1)) self.vlcwin.Show(True) self.logowin.Show(False) self.ctrlsizer.ShowItems(True) self.guiutility.frame.Layout() def OnVolumeChanged(self, volume): if self.mute.GetBitmapLabel() == self.bmp_muted: # unmute self.mute.SetBitmapLabel(self.bmp_unmuted, recreate=True) self.volume = volume self.oldvolume = self.volume self.SetVolume(self.volume) def MuteClicked(self, event): if self.mute.GetBitmapLabel() == self.bmp_muted: self.volume = self.oldvolume else: self.volume = 0 self.volctrl.SetValue(self.volume) self.SetVolume(self.volume) self.mute.SetBitmapLabel(self.bmp_unmuted if self.mute.GetBitmapLabel() == self.bmp_muted else self.bmp_muted, recreate=True) @warnWxThread def Load(self, url, streaminfo=None): if DEBUG: print >> sys.stderr, "embedplay: Load:", url, streaminfo, currentThread().getName() if streaminfo is not None: self.estduration = streaminfo.get('estduration', None) self.download = VideoPlayer.getInstance().get_vod_download() # 19/02/10 Boudewijn: no self.slider when self.vlcwrap is None # 26/05/09 Boudewijn: when using the external player we do not have a vlcwrap if self.vlcwrap: self.slider.Enable(True) # Arno, 2009-02-17: If we don't do this VLC gets the wrong playlist somehow self.vlcwrap.stop() self.vlcwrap.playlist_clear() self.vlcwrap.load(url, streaminfo=streaminfo) # Enable update of progress slider wx.CallAfter(self.slider.SetValue, 0) if self.timer is None: self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.UpdateSlider) self.timer.Start(500) self.fsbtn.Enable(True) self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True) self.ppbtn.Enable(True) self.sbtn.Enable(True) def StartPlay(self): """ Start playing the new item after VLC has stopped playing the old one """ if DEBUG: print >> sys.stderr, "embedplay: PlayWhenStopped" self.playtimer = DelayTimer(self) @warnWxThread def Play(self, evt=None): if DEBUG: print >> sys.stderr, "embedplay: Play pressed" # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: if self.GetState() != MEDIASTATE_PLAYING: self.HideLoading() self.vlcwrap.start() self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True) self.ppbtn.Enable(True) elif DEBUG: print >> sys.stderr, "embedplay: Play pressed, already playing" @warnWxThread def Pause(self, evt=None, gui_vod_event=False): if DEBUG: print >> sys.stderr, "embedplay: Pause pressed" # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: if self.GetState() == MEDIASTATE_PLAYING: self.vlcwrap.pause() self.ppbtn.SetBitmapLabel(self.bmp_play, recreate=True) if gui_vod_event: self.ppbtn.Enable(False) self.ShowLoading() elif DEBUG: print >> sys.stderr, "embedplay: Pause pressed, not playing" @warnWxThread def Resume(self, evt=None): if DEBUG: print >> sys.stderr, "embedplay: Resume pressed" if self.vlcwrap: if self.GetState() != MEDIASTATE_PLAYING: self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True) self.ppbtn.Enable(True) self.HideLoading() self.vlcwrap.resume() @warnWxThread def PlayPause(self, evt=None): if DEBUG: print >> sys.stderr, "embedplay: PlayPause pressed" # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: if self.GetState() in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED]: # Ensures that the related download also starts self.guiutility.library_manager.startLastVODTorrent() else: self.vlcwrap.resume() self.ppbtn.SetBitmapLabel(self.bmp_play if self.ppbtn.GetBitmapLabel() == self.bmp_pause else self.bmp_pause, recreate=True) self.ppbtn.Enable(True) @warnWxThread def Seek(self, evt=None): if DEBUG: print >> sys.stderr, "embedplay: Seek" # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True) self.ppbtn.Enable(not bool(self.download)) position = self.slider.GetValue() self.update = False try: if self.download: self.download.pause_vod() self.download.vod_seekpos = None self.ShowLoading() self.vlcwrap.set_media_position_relative(position, self.GetState() in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED]) length = self.vlcwrap.get_stream_information_length() length = length / 1000 if length > 0 else (self.estduration or (self.download and self.download.get_vod_duration())) time_position = length * position self.timeoffset = time_position - (self.vlcwrap.get_media_position() / 1000) self.update = True except: print_exc() if DEBUG: print >> sys.stderr, 'embedplay: Could not seek' def FullScreen(self, evt=None): # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap and self.fsbtn.IsEnabled(): self._ToggleFullScreen() def OnFullScreenKey(self, event): if event.GetUnicodeKey() == wx.WXK_ESCAPE: self._ToggleFullScreen() elif event.GetUnicodeKey() == wx.WXK_SPACE: self._TogglePause() def _TogglePause(self): if self.GetState() == MEDIASTATE_PLAYING: self.vlcwrap.pause() else: self.vlcwrap.resume() @warnWxThread def _ToggleFullScreen(self): if isinstance(self.parent, wx.Frame): # are we shown in popup frame if self.ctrlsizer.IsShown(0): # we are not in fullscreen -> ctrlsizer is showing self.parent.ShowFullScreen(True) self.ctrlsizer.ShowItems(False) self.Layout() # Niels: 07-03-2012, only evt_close seems to work :( quitId = wx.NewId() pauseId = wx.NewId() self.parent.Bind(wx.EVT_MENU, lambda event: self._ToggleFullScreen(), id=quitId) self.parent.Bind(wx.EVT_MENU, lambda event: self._TogglePause(), id=pauseId) self.parent.Bind(wx.EVT_CLOSE, lambda event: self._ToggleFullScreen()) self.parent.Bind(wx.EVT_LEFT_DCLICK, lambda event: self._ToggleFullScreen()) accelerators = [(wx.ACCEL_NORMAL, wx.WXK_ESCAPE, quitId), (wx.ACCEL_CTRL, wx.WXK_SPACE, pauseId)] self.parent.SetAcceleratorTable(wx.AcceleratorTable(accelerators)) else: self.parent.ShowFullScreen(False) self.ctrlsizer.ShowItems(True) self.Layout() self.parent.SetAcceleratorTable(wx.NullAcceleratorTable) self.parent.Unbind(wx.EVT_CLOSE) else: # saving media player state cur_time = self.vlcwrap.get_media_position() cur_state = self.vlcwrap.get_our_state() self.vlcwrap.stop() if not self.fullscreenwindow: # create a new top level frame where to attach the vlc widget and # render the fullscreen video self.fullscreenwindow = wx.Frame(None, title="FullscreenVLC") self.fullscreenwindow.SetBackgroundColour("BLACK") eventPanel = wx.Panel(self.fullscreenwindow) eventPanel.SetBackgroundColour(wx.BLACK) eventPanel.Bind(wx.EVT_KEY_DOWN, lambda event: self.OnFullScreenKey(event)) self.fullscreenwindow.Bind(wx.EVT_CLOSE, lambda event: self._ToggleFullScreen()) self.fullscreenwindow.ShowFullScreen(True) eventPanel.SetFocus() self.vlcwrap.set_window(self.fullscreenwindow) else: self.TellLVCWrapWindow4Playback() self.fullscreenwindow.Destroy() self.fullscreenwindow = None # restoring state if cur_state == MEDIASTATE_PLAYING: self.vlcwrap.start(cur_time) elif cur_state == MEDIASTATE_PAUSED: self.vlcwrap.start(cur_time) def doPause(cur_time): self.vlcwrap.pause() self.vlcwrap.set_media_position(cur_time) wx.CallLater(500, doPause, cur_time) def Save(self, evt=None): # save media content in different directory if self.save_button.isToggled(): self.save_callback() def SetVolume(self, volume, evt=None): if DEBUG: print >> sys.stderr, "embedplay: SetVolume:", self.volume # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: self.vlcwrap.sound_set_volume(volume) def OnStop(self, event=None): if self.vlcwrap and self.sbtn.IsEnabled(): self.Stop() self.ppbtn.Enable(True) # Ensures that the related download also stops. self.guiutility.library_manager.stopLastVODTorrent() @forceWxThread def Stop(self): if DEBUG: print >> sys.stderr, "embedplay: Stop" # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: self.vlcwrap.stop() self.timeposition.SetLabel('--:-- / --:--') self.slider.SetValue(0) self.fsbtn.Enable(False) self.sbtn.Enable(False) self.ppbtn.SetBitmapLabel(self.bmp_play, recreate=True) self.slider.Enable(False) self.HideLoading() if self.timer is not None: self.timer.Stop() def GetState(self): """ Returns the state of VLC as summarized by Fabian: MEDIASTATE_PLAYING, MEDIASTATE_PAUSED, MEDIASTATE_ENDED, MEDIASTATE_STOPPED """ # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: status = self.vlcwrap.get_our_state() if DEBUG: print >> sys.stderr, "embedplay: GetState", status return status # catchall return MEDIASTATE_STOPPED def Reset(self): self.Stop() self.slider.SetPieces([]) @forceWxThread def UpdateStatus(self, progress, progress_consec, pieces_complete): self.logowin.loading.SetValue(progress) if self.vlcwrap: self.slider.SetPieces(pieces_complete) @warnWxThread def UpdateSlider(self, evt): # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap and self.update: if self.GetState() not in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED]: length = self.vlcwrap.get_stream_information_length() length = length / 1000 if length > 0 else (self.estduration or (self.download and self.download.get_vod_duration())) cur = self.vlcwrap.get_media_position() / 1000 if length and self.timeoffset: cur += self.timeoffset if cur >= 0 and length: self.slider.SetValue(float(cur) / length) cur_str = self.FormatTime(float(cur)) if cur >= 0 else '--:--' length_str = self.FormatTime(length) if length else '--:--' self.timeposition.SetLabel('%s / %s' % (cur_str, length_str)) self.ctrlsizer.Layout() elif self.GetState() == MEDIASTATE_ENDED: self.OnStop(None) def FormatTime(self, s): longformat = time.strftime('%d:%H:%M:%S', time.gmtime(s)) if longformat.startswith('01:'): longformat = longformat[3:] while longformat.startswith('00:') and len(longformat) > len('00:00'): longformat = longformat[3:] return longformat def TellLVCWrapWindow4Playback(self): if self.vlcwrap: self.vlcwin.tell_vclwrap_window_for_playback() def ShowLoading(self): if self.vlcwrap: self.logowin.loading.SetValue(0.0) self.logowin.show_loading() self.logowin.Show(True) self.vlcwin.Show(False) self.Layout() def HideLoading(self): if self.vlcwrap: self.logowin.hide_loading() self.logowin.Show(False) self.vlcwin.Show(True) self.Layout()
class EmbeddedPlayerPanel(wx.Panel): """ The Embedded Player consists of a VLCWindow and the media controls such as Play/Pause buttons and Volume Control. """ VIDEO_SIZE = (320, 240) def __init__(self, parent, utility, vlcwrap, bg_color): wx.Panel.__init__(self, parent, -1) self._logger = logging.getLogger(self.__class__.__name__) self._gui_image_manager = GuiImageManager.getInstance() self.utility = utility self.guiutility = utility.guiUtility self.videoplayer = self.guiutility.videoplayer self.parent = parent self.SetBackgroundColour(bg_color) self.fullscreenwindow = None self.download = None self.download_hash = None self.update = True self.timeoffset = None self.oldvolume = 0 vSizer = wx.BoxSizer(wx.VERTICAL) self.vlcwrap = vlcwrap if vlcwrap: self.vlcwin = VLCWindow(self, vlcwrap) self.vlcwin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE) vSizer.Add(self.vlcwin, 1, wx.EXPAND, 0) self.logowin = LogoWindow(self) self.logowin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE) vSizer.Add(self.logowin, 1, wx.EXPAND, 0) self.ctrlpanel = FancyPanel(self, border=wx.TOP) self.ctrlpanel.SetMinSize((-1, 30)) self.ctrlpanel.SetBorderColour(SEPARATOR_GREY) self.ctrlpanel.SetBackgroundColour(GRADIENT_LGREY, GRADIENT_DGREY) self.ctrlsizer = wx.BoxSizer(wx.HORIZONTAL) self.slider = VideoSlider(self.ctrlpanel) self.slider.Enable(False) self.timeposition = TransparentText(self.ctrlpanel, -1, "--:-- / --:--") self.bmp_muted = self._gui_image_manager.getImage( u"video_muted.png") self.bmp_unmuted = self._gui_image_manager.getImage( u"video_unmuted.png") self.mute = ActionButton(self.ctrlpanel, -1, self.bmp_unmuted) self.mute.Bind(wx.EVT_LEFT_UP, self.MuteClicked) self.bmp_pause = self._gui_image_manager.getImage( u"video_pause.png") self.bmp_play = self._gui_image_manager.getImage(u"video_play.png") self.ppbtn = ActionButton(self.ctrlpanel, -1, self.bmp_play) self.ppbtn.Bind(wx.EVT_LEFT_UP, self.PlayPause) self.ppbtn.Enable(False) self.sbtn = ActionButton( self.ctrlpanel, -1, self._gui_image_manager.getImage(u"video_stop.png")) self.sbtn.Bind(wx.EVT_LEFT_UP, self.OnStop) self.sbtn.Enable(False) self.volctrl = VideoVolume(self.ctrlpanel, -1) self.volctrl.SetVolumeHandler(self.OnVolumeChanged) self.volctrl.SetMinSize((30, 17)) self.volctrl.Enable(False) self.fsbtn = ActionButton( self.ctrlpanel, -1, self._gui_image_manager.getImage(u"video_fullscreen.png")) self.fsbtn.Bind(wx.EVT_LEFT_UP, self.FullScreen) self.fsbtn.Enable(False) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlsizer.Add(self.ppbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlsizer.Add(self.sbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlsizer.Add(self.slider, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5) self.ctrlsizer.Add(self.timeposition, 0, wx.ALIGN_CENTER_VERTICAL) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlsizer.Add(self.mute, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1) self.ctrlsizer.AddSpacer((5, -1)) self.ctrlsizer.Add(self.volctrl, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlsizer.Add(self.fsbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1) self.ctrlsizer.AddSpacer((10, -1)) self.ctrlpanel.SetSizer(self.ctrlsizer) vSizer.Add(self.ctrlpanel, 0, wx.ALIGN_BOTTOM | wx.EXPAND) self.notifier = self.guiutility.utility.session.notifier self.SetSizer(vSizer) self.playtimer = None self.timer = None if self.vlcwrap: self.SetMinSize((EmbeddedPlayerPanel.VIDEO_SIZE[0], -1)) self.vlcwin.Show(True) self.logowin.Show(False) self.ctrlsizer.ShowItems(True) self.guiutility.frame.Layout() self.guiutility.library_manager.add_download_state_callback( self.OnStatesCallback) self.guiutility.utility.session.add_observer( self.OnVideoBuffering, NTFY_TORRENTS, [NTFY_VIDEO_BUFFERING]) self.videoplayer.set_internalplayer_callback(self.LoadAndStartPlay) def OnVideoBuffering(self, subject, changeType, torrent_tuple): if not self: return download_hash, _, is_buffering = torrent_tuple if self.download and self.download.get_def().get_infohash( ) == download_hash: @forceWxThread def do_gui(): if is_buffering: self.Pause(gui_vod_event=True) else: self.Resume() do_gui() def OnStatesCallback(self, dslist, magnetlist): if not self or not self.download: return for ds in dslist: if ds.get_download() == self.download and self.download.get_mode( ) == DLMODE_VOD: if ds.get_status() == DLSTATUS_HASHCHECKING: progress = ds.get_progress() label = 'Checking\n%d%%' % (progress * 100) elif ds.get_status() == DLSTATUS_STOPPED_ON_ERROR: progress = 0 label = 'Loading\nfailed' else: progress = ds.get_vod_prebuffering_progress() label = 'Loading\n%d%%' % (progress * 100) pieces_complete = ds.get_pieces_complete( ) if ds.get_progress() < 1.0 else [True] self.UpdateStatus(label, progress, pieces_complete) def OnVolumeChanged(self, volume): if self.mute.GetBitmapLabel() == self.bmp_muted: # unmute self.mute.SetBitmapLabel(self.bmp_unmuted, recreate=True) self.volume = volume self.oldvolume = self.volume self.SetVolume(self.volume) def MuteClicked(self, event): if self.mute.GetBitmapLabel() == self.bmp_muted: self.volume = self.oldvolume else: self.volume = 0 self.volctrl.SetValue(self.volume) self.SetVolume(self.volume) self.mute.SetBitmapLabel( self.bmp_unmuted if self.mute.GetBitmapLabel() == self.bmp_muted else self.bmp_muted, recreate=True) @forceWxThread def LoadAndStartPlay(self, url, download): self.Load(url, download) self.StartPlay() @warnWxThread def Load(self, url, download): self._logger.debug("embedplay: Load: %s %s", url, currentThread().getName()) self.download = download self.download_hash = download.get_def().get_infohash() # 19/02/10 Boudewijn: no self.slider when self.vlcwrap is None # 26/05/09 Boudewijn: when using the external player we do not have a vlcwrap if self.vlcwrap: self.slider.Enable(False) # Arno, 2009-02-17: If we don't do this VLC gets the wrong playlist somehow self.vlcwrap.stop() self.vlcwrap.load(url) # Enable update of progress slider wx.CallAfter(self.slider.SetValue, 0) if self.timer is None: self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.UpdateSlider) self.timer.Start(500) self.volume = self.vlcwrap.sound_get_volume() self.oldvolume = self.vlcwrap.sound_get_volume() self.volctrl.SetValue(self.volume) self.volctrl.Enable(True) self.fsbtn.Enable(True) self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True) self.ppbtn.Enable(True) self.sbtn.Enable(True) def StartPlay(self): """ Start playing the new item after VLC has stopped playing the old one """ self._logger.debug("embedplay: PlayWhenStopped") self.playtimer = DelayTimer(self) @warnWxThread def Play(self, evt=None): self._logger.debug("embedplay: Play pressed") # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: if self.GetState() != MEDIASTATE_PLAYING: self.vlcwrap.start() self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True) self.ppbtn.Enable(True) else: self._logger.debug("embedplay: Play pressed, already playing") @warnWxThread def Pause(self, evt=None, gui_vod_event=False): self._logger.debug("embedplay: Pause pressed") if self.vlcwrap: if self.GetState() == MEDIASTATE_PLAYING: self.vlcwrap.pause() self.ppbtn.SetBitmapLabel(self.bmp_play, recreate=True) if gui_vod_event: self.ppbtn.Enable(False) self.ShowLoading() @warnWxThread def Resume(self, evt=None): self._logger.debug("embedplay: Resume pressed") if self.vlcwrap: if self.GetState() != MEDIASTATE_PLAYING: self.vlcwrap.resume() self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True) self.ppbtn.Enable(True) self.slider.Enable(True) self.HideLoading() @warnWxThread def PlayPause(self, evt=None): self._logger.debug("embedplay: PlayPause pressed") # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: if self.GetState() in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED]: # Ensures that the related download also starts self.guiutility.library_manager.startLastVODTorrent() else: self.vlcwrap.resume() self.ppbtn.SetBitmapLabel( self.bmp_play if self.ppbtn.GetBitmapLabel() == self.bmp_pause else self.bmp_pause, recreate=True) self.ppbtn.Enable(True) @warnWxThread def Seek(self, evt=None): self._logger.debug("embedplay: Seek") # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True) self.ppbtn.Enable(self.download.get_progress() == 1.0) position = self.slider.GetValue() self.update = False try: self.Pause(gui_vod_event=True) self.videoplayer.seek(position) self.vlcwrap.set_media_position_relative( position, self.GetState() in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED]) length = self.vlcwrap.get_stream_information_length() length = length / 1000 if length > 0 else self.videoplayer.get_vod_duration( self.download_hash) time_position = length * position self.timeoffset = time_position - ( self.vlcwrap.get_media_position() / 1000) self.update = True except: print_exc() self._logger.debug('embedplay: Could not seek') def FullScreen(self, evt=None): # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap and self.fsbtn.IsEnabled(): self._ToggleFullScreen() def OnFullScreenKey(self, event): if event.GetUnicodeKey() == wx.WXK_ESCAPE: self._ToggleFullScreen() elif event.GetUnicodeKey() == wx.WXK_SPACE: self._TogglePause() def _TogglePause(self): if self.GetState() == MEDIASTATE_PLAYING: self.vlcwrap.pause() else: self.vlcwrap.resume() @warnWxThread def _ToggleFullScreen(self): # saving media player state cur_time = self.vlcwrap.get_media_position() cur_state = self.vlcwrap.get_our_state() self.vlcwrap.stop() if not self.fullscreenwindow: # create a new top level frame where to attach the vlc widget and # render the fullscreen video self.fullscreenwindow = wx.Frame(None, title="FullscreenVLC") self.fullscreenwindow.SetBackgroundColour("BLACK") eventPanel = wx.Panel(self.fullscreenwindow) eventPanel.SetBackgroundColour(wx.BLACK) eventPanel.Bind(wx.EVT_KEY_DOWN, lambda event: self.OnFullScreenKey(event)) self.fullscreenwindow.Bind(wx.EVT_CLOSE, lambda event: self._ToggleFullScreen()) self.fullscreenwindow.Show() self.fullscreenwindow.ShowFullScreen(True) eventPanel.SetFocus() self.vlcwrap.set_window(self.fullscreenwindow) else: self.vlcwrap.set_window(self.vlcwin) self.fullscreenwindow.Destroy() self.fullscreenwindow = None # restoring state if cur_state == MEDIASTATE_PLAYING: self.vlcwrap.start(cur_time) elif cur_state == MEDIASTATE_PAUSED: self.vlcwrap.start(cur_time) def doPause(cur_time): self.vlcwrap.pause() self.vlcwrap.set_media_position(cur_time) wx.CallLater(500, doPause, cur_time) def SetVolume(self, volume, evt=None): self._logger.debug("embedplay: SetVolume: %s", self.volume) # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: self.vlcwrap.sound_set_volume(volume) def OnStop(self, event=None): if self.vlcwrap and self.sbtn.IsEnabled(): self.Stop() self.ppbtn.Enable(True) # Ensures that the related download also stops. self.guiutility.library_manager.stopLastVODTorrent() @forceWxThread def Stop(self): self._logger.debug("embedplay: Stop") # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: self.vlcwrap.stop() self.timeposition.SetLabel('--:-- / --:--') self.slider.SetValue(0) self.timeoffset = None self.fsbtn.Enable(False) self.sbtn.Enable(False) self.ppbtn.SetBitmapLabel(self.bmp_play, recreate=True) self.slider.Enable(False) self.HideLoading() if self.timer is not None: self.timer.Stop() def GetState(self): """ Returns the state of VLC as summarized by Fabian: MEDIASTATE_PLAYING, MEDIASTATE_PAUSED, MEDIASTATE_ENDED, MEDIASTATE_STOPPED """ # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap: status = self.vlcwrap.get_our_state() self._logger.debug("embedplay: GetState %s", status) return status # catchall return MEDIASTATE_STOPPED def Reset(self): self.Stop() self.slider.SetPieces([]) @forceWxThread def UpdateStatus(self, label, progress, pieces_complete): self.logowin.loading.SetValue(progress) self.logowin.loading.SetLabel(label) if self.vlcwrap: self.slider.SetPieces(pieces_complete) @warnWxThread def UpdateSlider(self, evt): # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap if self.vlcwrap and self.update: if self.GetState() not in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED]: length = self.vlcwrap.get_stream_information_length() length = length / 1000 if length > 0 else self.videoplayer.get_vod_duration( self.download_hash) cur = self.vlcwrap.get_media_position() / 1000 if length and self.timeoffset: cur += self.timeoffset if cur >= 0 and length: self.slider.SetValue(float(cur) / length) cur_str = self.FormatTime(float(cur)) if cur >= 0 else '--:--' length_str = self.FormatTime(length) if length else '--:--' self.timeposition.SetLabel('%s / %s' % (cur_str, length_str)) self.ctrlsizer.Layout() elif self.GetState() == MEDIASTATE_ENDED: download, fileindex = (self.videoplayer.get_vod_download(), self.videoplayer.get_vod_fileindex()) self.OnStop(None) if download: self.notifier.notify( NTFY_TORRENTS, NTFY_VIDEO_ENDED, (download.get_def().get_infohash(), fileindex)) if self.fullscreenwindow: self._ToggleFullScreen() def FormatTime(self, s): longformat = time.strftime('%d:%H:%M:%S', time.gmtime(s)) if longformat.startswith('01:'): longformat = longformat[3:] while longformat.startswith('00:') and len(longformat) > len('00:00'): longformat = longformat[3:] return longformat def ShowLoading(self): if self.vlcwrap: self.logowin.loading.SetValue(0.0) self.logowin.show_loading() self.logowin.Show(True) self.vlcwin.Show(False) self.Layout() def HideLoading(self): if self.vlcwrap: self.logowin.hide_loading() self.logowin.Show(False) self.vlcwin.Show(True) self.Layout() def RecreateVLCWindow(self): if self.vlcwrap: vlcwin = VLCWindow(self, self.vlcwrap) vlcwin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE) vlcwin.Show(self.vlcwin.IsShown()) self.GetSizer().Replace(self.vlcwin, vlcwin) self.vlcwin.Destroy() self.vlcwin = vlcwin