From f790f7d0b566dde616eb751e6c436560e41b23f2 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sat, 25 Aug 2018 15:30:12 +0300 Subject: [PATCH] new prototype of the streams player --- app/tools/vlc.py | 138 +++++++++------ app/ui/main_app_window.py | 91 ++++++---- app/ui/main_window.glade | 350 ++++++++++++++++++++++++++------------ 3 files changed, 383 insertions(+), 196 deletions(-) diff --git a/app/tools/vlc.py b/app/tools/vlc.py index 2d3b454b..09e7262a 100644 --- a/app/tools/vlc.py +++ b/app/tools/vlc.py @@ -53,10 +53,10 @@ import logging logger = logging.getLogger(__name__) -__version__ = "3.0.0102" -__libvlc_version__ = "3.0.0" -__generator_version__ = "1.2" -build_date = "Mon Feb 19 18:13:20 2018 3.0.0" +__version__ = "3.0.3104" +__libvlc_version__ = "3.0.3" +__generator_version__ = "1.4" +build_date = "Fri Jul 13 15:18:27 2018 3.0.3" # The libvlc doc states that filenames are expected to be in UTF8, do # not rely on sys.getfilesystemencoding() which will be confused, @@ -1112,7 +1112,7 @@ class Callback(ctypes.c_void_p): class LogCb(ctypes.c_void_p): """Callback prototype for LibVLC log message handler. @param data: data pointer as given to L{libvlc_log_set}(). - @param level: message level (@ref libvlc_log_level). + @param level: message level (@ref L{LogLevel}). @param ctx: message context (meta-information about the message). @param fmt: printf() format string (as defined by ISO C11). @param args: variable argument list for the format @note Log message handlers B{must} be thread-safe. @warning The message context pointer, the format string parameters and the variable arguments are only valid until the callback returns. @@ -1318,7 +1318,7 @@ class CallbackDecorators(object): LogCb = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, Log_ptr, ctypes.c_char_p, ctypes.c_void_p) LogCb.__doc__ = '''Callback prototype for LibVLC log message handler. @param data: data pointer as given to L{libvlc_log_set}(). - @param level: message level (@ref libvlc_log_level). + @param level: message level (@ref L{LogLevel}). @param ctx: message context (meta-information about the message). @param fmt: printf() format string (as defined by ISO C11). @param args: variable argument list for the format @note Log message handlers B{must} be thread-safe. @warning The message context pointer, the format string parameters and the variable arguments are only valid until the callback returns. @@ -1745,7 +1745,7 @@ AudioOutputDevice._fields_ = [ # recursive struct class TitleDescription(_Cstruct): - _fields = [ + _fields_ = [ ('duration', ctypes.c_longlong), ('name', ctypes.c_char_p), ('menu', ctypes.c_bool), @@ -1753,7 +1753,7 @@ class TitleDescription(_Cstruct): class ChapterDescription(_Cstruct): - _fields = [ + _fields_ = [ ('time_offset', ctypes.c_longlong), ('duration', ctypes.c_longlong), ('name', ctypes.c_char_p), @@ -1761,7 +1761,7 @@ class ChapterDescription(_Cstruct): class VideoViewpoint(_Cstruct): - _fields = [ + _fields_ = [ ('yaw', ctypes.c_float), ('pitch', ctypes.c_float), ('roll', ctypes.c_float), @@ -1769,11 +1769,22 @@ class VideoViewpoint(_Cstruct): ] +class MediaDiscovererDescription(_Cstruct): + _fields_ = [ + ('name', ctypes.c_char_p), + ('longname', ctypes.c_char_p), + ('cat', MediaDiscovererCategory), + ] + + def __str__(self): + return '%s %s (%d) - %s' % (self.__class__.__name__, self.name, self.cat, self.longname) + + # This struct depends on the MediaSlaveType enum that is defined only # in > 2.2 if 'MediaSlaveType' in locals(): class MediaSlave(_Cstruct): - _fields = [ + _fields_ = [ ('psz_uri', ctypes.c_char_p), ('i_type', MediaSlaveType), ('i_priority', ctypes.c_uint) @@ -1781,7 +1792,7 @@ if 'MediaSlaveType' in locals(): class RDDescription(_Cstruct): - _fields = [ + _fields_ = [ ('name', ctypes.c_char_p), ('longname', ctypes.c_char_p) ] @@ -2612,7 +2623,7 @@ class Media(_Ctype): return libvlc_media_add_option_flag(self, str_to_bytes(psz_options), i_flags) def retain(self): - '''Retain a reference to a media descriptor object (libvlc_media_t). Use + '''Retain a reference to a media descriptor object (L{Media}). Use L{release}() to decrement the reference count of a media descriptor object. ''' @@ -2667,7 +2678,7 @@ class Media(_Ctype): '''Get current state of media descriptor object. Possible media states are libvlc_NothingSpecial=0, libvlc_Opening, libvlc_Playing, libvlc_Paused, libvlc_Stopped, libvlc_Ended, libvlc_Error. - See libvlc_state_t. + See L{State}. @return: state of media descriptor object. ''' return libvlc_media_get_state(self) @@ -2708,7 +2719,7 @@ class Media(_Ctype): To track when this is over you can listen to libvlc_MediaParsedChanged event. However if this functions returns an error, you will not receive any events. - It uses a flag to specify parse options (see libvlc_media_parse_flag_t). All + It uses a flag to specify parse options (see L{MediaParseFlag}). All these flags can be combined. By default, media is parsed if it's a local file. @note: Parsing can be aborted with L{parse_stop}(). @@ -2716,7 +2727,7 @@ class Media(_Ctype): See L{get_meta} See L{tracks_get} See L{get_parsed_status} - See libvlc_media_parse_flag_t. + See L{MediaParseFlag}. @param parse_flag: parse options: @param timeout: maximum time allowed to preparse the media. If -1, the default "preparse-timeout" option will be used as a timeout. If 0, it will wait indefinitely. If > 0, the timeout will be used (in milliseconds). @return: -1 in case of error, 0 otherwise. @@ -2736,8 +2747,8 @@ class Media(_Ctype): def get_parsed_status(self): '''Get Parsed status for media descriptor object. See libvlc_MediaParsedChanged - See libvlc_media_parsed_status_t. - @return: a value of the libvlc_media_parsed_status_t enum. + See L{MediaParsedStatus}. + @return: a value of the L{MediaParsedStatus} enum. @version: LibVLC 3.0.0 or later. ''' return libvlc_media_get_parsed_status(self) @@ -2760,7 +2771,7 @@ class Media(_Ctype): def get_type(self): '''Get the media type of the media descriptor object. @return: media type. - @version: LibVLC 3.0.0 and later. See libvlc_media_type_t. + @version: LibVLC 3.0.0 and later. See L{MediaType}. ''' return libvlc_media_get_type(self) @@ -3179,7 +3190,7 @@ class MediaListPlayer(_Ctype): def get_state(self): '''Get current libvlc_state of media list player. - @return: libvlc_state_t for media list player. + @return: L{State} for media list player. ''' return libvlc_media_list_player_get_state(self) @@ -3306,8 +3317,14 @@ class MediaPlayer(_Ctype): ''' titleDescription_pp = ctypes.POINTER(TitleDescription)() n = libvlc_media_player_get_full_title_descriptions(self, ctypes.byref(titleDescription_pp)) - info = ctypes.cast(ctypes.titleDescription_pp, ctypes.POINTER(ctypes.POINTER(TitleDescription) * n)) - return info + info = ctypes.cast(titleDescription_pp, ctypes.POINTER(ctypes.POINTER(TitleDescription) * n)) + try: + contents = info.contents + except ValueError: + # Media not parsed, no info. + return None + descr = (contents[i].contents for i in range(len(contents))) + return descr def get_full_chapter_descriptions(self, i_chapters_of_title): '''Get the full description of available chapters. @@ -3317,8 +3334,14 @@ class MediaPlayer(_Ctype): ''' chapterDescription_pp = ctypes.POINTER(ChapterDescription)() n = libvlc_media_player_get_full_chapter_descriptions(self, ctypes.byref(chapterDescription_pp)) - info = ctypes.cast(ctypes.chapterDescription_pp, ctypes.POINTER(ctypes.POINTER(ChapterDescription) * n)) - return info + info = ctypes.cast(chapterDescription_pp, ctypes.POINTER(ctypes.POINTER(ChapterDescription) * n)) + try: + contents = info.contents + except ValueError: + # Media not parsed, no info. + return None + descr = (contents[i].contents for i in range(len(contents))) + return descr def video_get_size(self, num=0): """Get the video size in pixels as 2-tuple (width, height). @@ -3788,7 +3811,7 @@ class MediaPlayer(_Ctype): def get_state(self): '''Get current movie state. - @return: the current state of the media player (playing, paused, ...) See libvlc_state_t. + @return: the current state of the media player (playing, paused, ...) See L{State}. ''' return libvlc_media_player_get_state(self) @@ -3997,7 +4020,7 @@ class MediaPlayer(_Ctype): def video_set_teletext(self, i_page): '''Set new teletext page to retrieve. This function can also be used to send a teletext key. - @param i_page: teletex page number requested. This value can be 0 to disable teletext, a number in the range ]0;1000[ to show the requested page, or a \ref libvlc_teletext_key_t. 100 is the default teletext page. + @param i_page: teletex page number requested. This value can be 0 to disable teletext, a number in the range ]0;1000[ to show the requested page, or a \ref L{TeletextKey}. 100 is the default teletext page. ''' return libvlc_video_set_teletext(self, i_page) @@ -4068,7 +4091,7 @@ class MediaPlayer(_Ctype): def video_get_logo_int(self, option): '''Get integer logo option. - @param option: logo option to get, values of libvlc_video_logo_option_t. + @param option: logo option to get, values of L{VideoLogoOption}. ''' return libvlc_video_get_logo_int(self, option) @@ -4077,7 +4100,7 @@ class MediaPlayer(_Ctype): are ignored. Passing libvlc_logo_enable as option value has the side effect of starting (arg !0) or stopping (arg 0) the logo filter. - @param option: logo option to set, values of libvlc_video_logo_option_t. + @param option: logo option to set, values of L{VideoLogoOption}. @param value: logo option value. ''' return libvlc_video_set_logo_int(self, option, value) @@ -4085,14 +4108,14 @@ class MediaPlayer(_Ctype): def video_set_logo_string(self, option, psz_value): '''Set logo option as string. Options that take a different type value are ignored. - @param option: logo option to set, values of libvlc_video_logo_option_t. + @param option: logo option to set, values of L{VideoLogoOption}. @param psz_value: logo option value. ''' return libvlc_video_set_logo_string(self, option, str_to_bytes(psz_value)) def video_get_adjust_int(self, option): '''Get integer adjust option. - @param option: adjust option to get, values of libvlc_video_adjust_option_t. + @param option: adjust option to get, values of L{VideoAdjustOption}. @version: LibVLC 1.1.1 and later. ''' return libvlc_video_get_adjust_int(self, option) @@ -4102,7 +4125,7 @@ class MediaPlayer(_Ctype): are ignored. Passing libvlc_adjust_enable as option value has the side effect of starting (arg !0) or stopping (arg 0) the adjust filter. - @param option: adust option to set, values of libvlc_video_adjust_option_t. + @param option: adust option to set, values of L{VideoAdjustOption}. @param value: adjust option value. @version: LibVLC 1.1.1 and later. ''' @@ -4110,7 +4133,7 @@ class MediaPlayer(_Ctype): def video_get_adjust_float(self, option): '''Get float adjust option. - @param option: adjust option to get, values of libvlc_video_adjust_option_t. + @param option: adjust option to get, values of L{VideoAdjustOption}. @version: LibVLC 1.1.1 and later. ''' return libvlc_video_get_adjust_float(self, option) @@ -4118,7 +4141,7 @@ class MediaPlayer(_Ctype): def video_set_adjust_float(self, option, value): '''Set adjust option as float. Options that take a different type value are ignored. - @param option: adust option to set, values of libvlc_video_adjust_option_t. + @param option: adust option to set, values of L{VideoAdjustOption}. @param value: adjust option value. @version: LibVLC 1.1.1 and later. ''' @@ -4242,13 +4265,13 @@ class MediaPlayer(_Ctype): def audio_get_channel(self): '''Get current audio channel. - @return: the audio channel See libvlc_audio_output_channel_t. + @return: the audio channel See L{AudioOutputChannel}. ''' return libvlc_audio_get_channel(self) def audio_set_channel(self, channel): '''Set current audio channel. - @param channel: the audio channel, See libvlc_audio_output_channel_t. + @param channel: the audio channel, See L{AudioOutputChannel}. @return: 0 on success, -1 on error. ''' return libvlc_audio_set_channel(self, channel) @@ -5340,7 +5363,7 @@ def libvlc_media_add_option_flag(p_md, psz_options, i_flags): def libvlc_media_retain(p_md): - '''Retain a reference to a media descriptor object (libvlc_media_t). Use + '''Retain a reference to a media descriptor object (L{Media}). Use L{libvlc_media_release}() to decrement the reference count of a media descriptor object. @param p_md: the media descriptor. @@ -5430,7 +5453,7 @@ def libvlc_media_get_state(p_md): '''Get current state of media descriptor object. Possible media states are libvlc_NothingSpecial=0, libvlc_Opening, libvlc_Playing, libvlc_Paused, libvlc_Stopped, libvlc_Ended, libvlc_Error. - See libvlc_state_t. + See L{State}. @param p_md: a media descriptor object. @return: state of media descriptor object. ''' @@ -5495,7 +5518,7 @@ def libvlc_media_parse_with_options(p_md, parse_flag, timeout): To track when this is over you can listen to libvlc_MediaParsedChanged event. However if this functions returns an error, you will not receive any events. - It uses a flag to specify parse options (see libvlc_media_parse_flag_t). All + It uses a flag to specify parse options (see L{MediaParseFlag}). All these flags can be combined. By default, media is parsed if it's a local file. @note: Parsing can be aborted with L{libvlc_media_parse_stop}(). @@ -5503,7 +5526,7 @@ def libvlc_media_parse_with_options(p_md, parse_flag, timeout): See L{libvlc_media_get_meta} See L{libvlc_media_tracks_get} See L{libvlc_media_get_parsed_status} - See libvlc_media_parse_flag_t. + See L{MediaParseFlag}. @param p_md: media descriptor object. @param parse_flag: parse options: @param timeout: maximum time allowed to preparse the media. If -1, the default "preparse-timeout" option will be used as a timeout. If 0, it will wait indefinitely. If > 0, the timeout will be used (in milliseconds). @@ -5533,9 +5556,9 @@ def libvlc_media_parse_stop(p_md): def libvlc_media_get_parsed_status(p_md): '''Get Parsed status for media descriptor object. See libvlc_MediaParsedChanged - See libvlc_media_parsed_status_t. + See L{MediaParsedStatus}. @param p_md: media descriptor object. - @return: a value of the libvlc_media_parsed_status_t enum. + @return: a value of the L{MediaParsedStatus} enum. @version: LibVLC 3.0.0 or later. ''' f = _Cfunctions.get('libvlc_media_get_parsed_status', None) or \ @@ -5614,7 +5637,7 @@ def libvlc_media_get_type(p_md): '''Get the media type of the media descriptor object. @param p_md: media descriptor object. @return: media type. - @version: LibVLC 3.0.0 and later. See libvlc_media_type_t. + @version: LibVLC 3.0.0 and later. See L{MediaType}. ''' f = _Cfunctions.get('libvlc_media_get_type', None) or \ _Cfunction('libvlc_media_get_type', ((1,),), None, @@ -7045,7 +7068,7 @@ def libvlc_media_player_set_rate(p_mi, rate): def libvlc_media_player_get_state(p_mi): '''Get current movie state. @param p_mi: the Media Player. - @return: the current state of the media player (playing, paused, ...) See libvlc_state_t. + @return: the current state of the media player (playing, paused, ...) See L{State}. ''' f = _Cfunctions.get('libvlc_media_player_get_state', None) or \ _Cfunction('libvlc_media_player_get_state', ((1,),), None, @@ -7324,7 +7347,7 @@ def libvlc_video_new_viewpoint(): ''' f = _Cfunctions.get('libvlc_video_new_viewpoint', None) or \ _Cfunction('libvlc_video_new_viewpoint', (), None, - VideoViewpoint) + ctypes.POINTER(VideoViewpoint)) return f() @@ -7339,7 +7362,7 @@ def libvlc_video_update_viewpoint(p_mi, p_viewpoint, b_absolute): ''' f = _Cfunctions.get('libvlc_video_update_viewpoint', None) or \ _Cfunction('libvlc_video_update_viewpoint', ((1,), (1,), (1,),), None, - ctypes.c_int, MediaPlayer, VideoViewpoint, ctypes.c_bool) + ctypes.c_int, MediaPlayer, ctypes.POINTER(VideoViewpoint), ctypes.c_bool) return f(p_mi, p_viewpoint, b_absolute) @@ -7507,7 +7530,7 @@ def libvlc_video_set_teletext(p_mi, i_page): '''Set new teletext page to retrieve. This function can also be used to send a teletext key. @param p_mi: the media player. - @param i_page: teletex page number requested. This value can be 0 to disable teletext, a number in the range ]0;1000[ to show the requested page, or a \ref libvlc_teletext_key_t. 100 is the default teletext page. + @param i_page: teletex page number requested. This value can be 0 to disable teletext, a number in the range ]0;1000[ to show the requested page, or a \ref L{TeletextKey}. 100 is the default teletext page. ''' f = _Cfunctions.get('libvlc_video_set_teletext', None) or \ _Cfunction('libvlc_video_set_teletext', ((1,), (1,),), None, @@ -7639,7 +7662,7 @@ def libvlc_video_set_marquee_string(p_mi, option, psz_text): def libvlc_video_get_logo_int(p_mi, option): '''Get integer logo option. @param p_mi: libvlc media player instance. - @param option: logo option to get, values of libvlc_video_logo_option_t. + @param option: logo option to get, values of L{VideoLogoOption}. ''' f = _Cfunctions.get('libvlc_video_get_logo_int', None) or \ _Cfunction('libvlc_video_get_logo_int', ((1,), (1,),), None, @@ -7653,7 +7676,7 @@ def libvlc_video_set_logo_int(p_mi, option, value): Passing libvlc_logo_enable as option value has the side effect of starting (arg !0) or stopping (arg 0) the logo filter. @param p_mi: libvlc media player instance. - @param option: logo option to set, values of libvlc_video_logo_option_t. + @param option: logo option to set, values of L{VideoLogoOption}. @param value: logo option value. ''' f = _Cfunctions.get('libvlc_video_set_logo_int', None) or \ @@ -7666,7 +7689,7 @@ def libvlc_video_set_logo_string(p_mi, option, psz_value): '''Set logo option as string. Options that take a different type value are ignored. @param p_mi: libvlc media player instance. - @param option: logo option to set, values of libvlc_video_logo_option_t. + @param option: logo option to set, values of L{VideoLogoOption}. @param psz_value: logo option value. ''' f = _Cfunctions.get('libvlc_video_set_logo_string', None) or \ @@ -7678,7 +7701,7 @@ def libvlc_video_set_logo_string(p_mi, option, psz_value): def libvlc_video_get_adjust_int(p_mi, option): '''Get integer adjust option. @param p_mi: libvlc media player instance. - @param option: adjust option to get, values of libvlc_video_adjust_option_t. + @param option: adjust option to get, values of L{VideoAdjustOption}. @version: LibVLC 1.1.1 and later. ''' f = _Cfunctions.get('libvlc_video_get_adjust_int', None) or \ @@ -7693,7 +7716,7 @@ def libvlc_video_set_adjust_int(p_mi, option, value): Passing libvlc_adjust_enable as option value has the side effect of starting (arg !0) or stopping (arg 0) the adjust filter. @param p_mi: libvlc media player instance. - @param option: adust option to set, values of libvlc_video_adjust_option_t. + @param option: adust option to set, values of L{VideoAdjustOption}. @param value: adjust option value. @version: LibVLC 1.1.1 and later. ''' @@ -7706,7 +7729,7 @@ def libvlc_video_set_adjust_int(p_mi, option, value): def libvlc_video_get_adjust_float(p_mi, option): '''Get float adjust option. @param p_mi: libvlc media player instance. - @param option: adjust option to get, values of libvlc_video_adjust_option_t. + @param option: adjust option to get, values of L{VideoAdjustOption}. @version: LibVLC 1.1.1 and later. ''' f = _Cfunctions.get('libvlc_video_get_adjust_float', None) or \ @@ -7719,7 +7742,7 @@ def libvlc_video_set_adjust_float(p_mi, option, value): '''Set adjust option as float. Options that take a different type value are ignored. @param p_mi: libvlc media player instance. - @param option: adust option to set, values of libvlc_video_adjust_option_t. + @param option: adust option to set, values of L{VideoAdjustOption}. @param value: adjust option value. @version: LibVLC 1.1.1 and later. ''' @@ -7972,7 +7995,7 @@ def libvlc_audio_set_track(p_mi, i_track): def libvlc_audio_get_channel(p_mi): '''Get current audio channel. @param p_mi: media player. - @return: the audio channel See libvlc_audio_output_channel_t. + @return: the audio channel See L{AudioOutputChannel}. ''' f = _Cfunctions.get('libvlc_audio_get_channel', None) or \ _Cfunction('libvlc_audio_get_channel', ((1,),), None, @@ -7983,7 +8006,7 @@ def libvlc_audio_get_channel(p_mi): def libvlc_audio_set_channel(p_mi, channel): '''Set current audio channel. @param p_mi: media player. - @param channel: the audio channel, See libvlc_audio_output_channel_t. + @param channel: the audio channel, See L{AudioOutputChannel}. @return: 0 on success, -1 on error. ''' f = _Cfunctions.get('libvlc_audio_set_channel', None) or \ @@ -8348,7 +8371,7 @@ def libvlc_media_list_player_is_playing(p_mlp): def libvlc_media_list_player_get_state(p_mlp): '''Get current libvlc_state of media list player. @param p_mlp: media list player instance. - @return: libvlc_state_t for media list player. + @return: L{State} for media list player. ''' f = _Cfunctions.get('libvlc_media_list_player_get_state', None) or \ _Cfunction('libvlc_media_list_player_get_state', ((1,),), None, @@ -8522,7 +8545,10 @@ def _dot2int(v): ''' t = [int(i) for i in v.split('.')] if len(t) == 3: - t.append(0) + if t[2] < 100: + t.append(0) + else: # 100 is arbitrary + t[2:4] = divmod(t[2], 100) elif len(t) != 4: raise ValueError('"i.i.i[.i]": %r' % (v,)) if min(t) < 0 or max(t) > 255: diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index b0e86559..7e1b8bb1 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -115,6 +115,11 @@ class MainAppWindow: "on_iptv": self.on_iptv, "on_iptv_list_configuration": self.on_iptv_list_configuration, "on_play_stream": self.on_play_stream, + "on_player_play": self.on_player_play, + "on_player_stop": self.on_player_stop, + "on_player_close": self.on_player_close, + "on_player_size_allocate": self.on_player_size_allocate, + "on_drawing_area_realize": self.on_drawing_area_realize, "on_remove_all_unavailable": self.on_remove_all_unavailable, "on_new_bouquet": self.on_new_bouquet, "on_bouquets_edit": self.on_bouquets_edit, @@ -159,6 +164,11 @@ class MainAppWindow: self._bouquets_model = builder.get_object("bouquets_tree_store") self._status_bar = builder.get_object("status_bar") self._main_window_box = builder.get_object("main_window_box") + self._player_drawing_area = builder.get_object("player_drawing_area") + self._player_box = builder.get_object("player_box") + # enabling events for the drawing area + self._player_drawing_area.set_events(Gdk.ModifierType.BUTTON1_MASK) + self._drawing_area_xid = None self._header_bar = builder.get_object("header_bar") self._bq_name_label = builder.get_object("bq_name_label") self._ip_label = builder.get_object("ip_label") @@ -214,9 +224,7 @@ class MainAppWindow: def on_close_app(self, *args): """ Called before app quit """ write_config(self._options) # storing current config - if self._player: - self._player.stop() - self._player.release() + self.on_player_close() Gtk.main_quit() def on_resize(self, window): @@ -957,28 +965,6 @@ class MainAppWindow: if event.get_event_type() == Gdk.EventType.DOUBLE_BUTTON_PRESS: self.on_play_stream() - def on_play_stream(self, item=None): - path, column = self._fav_view.get_cursor() - if path: - row = self._fav_model[path][:] - if row[5] == BqServiceType.IPTV.value: - url = get_iptv_url(row, Profile(self._profile)) - if not url: - return - - self.on_player_stop(None) - - if not self._player: - try: - self._player = Player.get_vlc_instance().media_player_new() - except (NameError, AttributeError): - show_dialog(DialogType.ERROR, self._main_window, "No VLC is found. Check that it is installed!") - - if self._player: - self._player.set_mrl(url) - self._is_played = True - self._player.play() - @run_idle def on_iptv_list_configuration(self, item): profile = Profile(self._profile) @@ -1018,19 +1004,56 @@ class MainAppWindow: if response: self.remove_favs(fav_bqt, response, self._fav_model) - def on_player_stop(self, item): + # ***************** Player *********************# + @run_idle + def on_play_stream(self, item=None): + self._player_box.set_visible(True) + self.on_player_play() + + @run_task + def on_player_play(self, item=None): + self.on_player_stop(None) + path, column = self._fav_view.get_cursor() + if path: + row = self._fav_model[path][:] + if row[5] == BqServiceType.IPTV.value: + url = get_iptv_url(row, Profile(self._profile)) + if not url: + return + + if not self._player: + try: + self._player = Player.get_vlc_instance().media_player_new() + except (NameError, AttributeError): + show_dialog(DialogType.ERROR, self._main_window, "No VLC is found. Check that it is installed!") + else: + if self._player: + self._player.set_mrl(url) + self._is_played = True + self._player.play() + self._player.set_xwindow(self._drawing_area_xid) + + def on_player_stop(self, item=None): if self._player: self._player.stop() self._is_played = False - def on_player_press(self, area, event): - if event.button == Gdk.BUTTON_PRIMARY: - if event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS: - self._full_screen = not self._full_screen - self._main_window.fullscreen() if self._full_screen else self._main_window.unfullscreen() - elif event.type == Gdk.EventType.BUTTON_PRESS: - if self._player: - self._player.stop() if self._player.is_playing() else self._player.play() + @run_idle + def on_player_close(self, item=None): + if self._player: + self._player.stop() + self._is_played = False + self._player.release() + GLib.idle_add(self._player_box.set_visible, False, property=GLib.PRIORITY_LOW) + + def on_player_size_allocate(self, area, rectangle=None): + area.hide() + GLib.idle_add(area.show, priority=GLib.PRIORITY_LOW) + + def on_drawing_area_realize(self, widget): + self._drawing_area_xid = widget.get_window().get_xid() + + # ***************** Player end *********************# def on_locate_in_services(self, view): locate_in_services(view, self._services_view, self._main_window) diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index dba2d7a1..0e77c025 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -1678,134 +1678,272 @@ Author: Dmitriy Yefremov - + True True - 2 - in + vertical + True - + + False + vertical + + + True + False + 2 + 2 + 0 + 0 + in + + + 24 + True + False + + + + + + + + + + True + True + 0 + + + + + True + False + + + True + False + Play + gtk-media-play + + + + False + True + + + + + True + False + Stop + True + gtk-media-stop + + + + False + True + + + + + True + False + + + True + False + + + + + True + False + False + Fullscreen + True + gtk-fullscreen + + + False + True + + + + + True + False + + + False + False + + + + + True + False + Close + Close + True + gtk-close + + + + False + True + + + + + False + False + end + 1 + + + + + True + True + + + + True True - fav_list_store - 2 - True - both - True - - - - - - - - - multiple - - + 2 + in - - True - 25 - Num - - - 0.20000000298023224 - 5 - 5 + + True + True + fav_list_store + 2 + True + both + True + + + + + + + + + multiple - - 0 - - - - - - - True - 2 - 50 - Service - True - - - - 8 - - - - 1 - - - - - end - 25 + + True + 25 + Num + + + 0.20000000298023224 + 5 + 5 + + + 0 + + - - 2 - - - - 3 - - - - - - 4 - - - - - - - True - 25 - Type - True - - - 0.50999999046325684 + + True + 2 + 50 + Service + True + + + + 8 + + + + + + 1 + + + + + end + 25 + + + 2 + + + + + + 3 + + + + + + 4 + + - - 5 - - - - - - 25 - Pos - True - - 0.50999999046325684 + + True + 25 + Type + True + + + 0.50999999046325684 + + + 5 + + - - 6 - - - - - - False - fav_id - - - 7 - + + 25 + Pos + True + + + 0.50999999046325684 + + + 6 + + + + + + + False + fav_id + + + + 7 + + + + + True + True +