Skip to content

Commit

Permalink
Overhaul support of alternative players
Browse files Browse the repository at this point in the history
- Follow up to ec68426
  • Loading branch information
MoojMidge committed Apr 15, 2024
1 parent b61c998 commit 0d4afbe
Show file tree
Hide file tree
Showing 14 changed files with 183 additions and 90 deletions.
10 changes: 9 additions & 1 deletion resources/language/resource.language.en_gb/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,7 @@ msgid "Are you sure?"
msgstr ""

msgctxt "#30704"
msgid "Use YouTube website urls"
msgid "Use YouTube website urls with default player"
msgstr ""

msgctxt "#30705"
Expand Down Expand Up @@ -1520,3 +1520,11 @@ msgstr ""
msgctxt "#30803"
msgid "Bookmark %s"
msgstr ""

msgctxt "#30804"
msgid "Use YouTube website urls with external player"
msgstr ""

msgctxt "#30805"
msgid "Use adaptive streaming formats with external player"
msgstr ""
3 changes: 3 additions & 0 deletions resources/lib/youtube_plugin/kodion/compatibility/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
'urlencode',
'urljoin',
'urlsplit',
'urlunsplit',
'xbmc',
'xbmcaddon',
'xbmcgui',
Expand All @@ -40,6 +41,7 @@
urlencode,
urljoin,
urlsplit,
urlunsplit,
)

import xbmc
Expand Down Expand Up @@ -68,6 +70,7 @@
parse_qsl,
urljoin,
urlsplit,
urlunsplit,
)
from xml.sax.saxutils import unescape

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@
IP = '/youtube/client_ip'
MPD = '/youtube/manifest/dash/'
PING = '/youtube/ping'
REDIRECT = '/youtube/redirect'
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@

CLIENT_SELECTION = 'youtube.client.selection' # (int)
SUPPORT_ALTERNATIVE_PLAYER = 'kodion.support.alternative_player' # (bool)
ALTERNATIVE_PLAYER_WEB_URLS = 'kodion.alternative_player.web.urls' # (bool)
DEFAULT_PLAYER_WEB_URLS = 'kodion.default_player.web_urls' # (bool)
ALTERNATIVE_PLAYER_WEB_URLS = 'kodion.alternative_player.web_urls' # (bool)
ALTERNATIVE_PLAYER_ADAPTIVE = 'kodion.alternative_player.adaptive' # (bool)

USE_ISA = 'kodion.video.quality.isa' # (bool)
LIVE_STREAMS = 'kodion.live_stream.selection' # (int)
Expand Down
17 changes: 4 additions & 13 deletions resources/lib/youtube_plugin/kodion/items/xbmc/xbmc_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,19 +330,10 @@ def video_playback_item(context, video_item, show_fanart=None):
settings = context.get_settings()
headers = video_item.get_headers()
license_key = video_item.get_license_key()
is_external = False
is_external = context.get_ui().get_property(SWITCH_PLAYER_FLAG)
is_strm = context.get_param('strm')
mime_type = None

if context.get_ui().get_property(SWITCH_PLAYER_FLAG):
is_external = True
if (settings.alternative_player_web_urls()
and not video_item.get_license_key()):
is_external = True
uri = 'https://www.youtube.com/watch?v={video_id}'.format(
video_id=video_item.video_id
)

if is_strm:
kwargs = {
'path': uri,
Expand All @@ -360,7 +351,7 @@ def video_playback_item(context, video_item, show_fanart=None):
'isPlayable': str(video_item.playable).lower(),
}

if (not is_external and video_item.use_isa_video()
if (video_item.use_isa_video()
and context.addon_enabled('inputstream.adaptive')):
if video_item.use_mpd_video():
manifest_type = 'mpd'
Expand Down Expand Up @@ -396,9 +387,9 @@ def video_playback_item(context, video_item, show_fanart=None):

list_item = xbmcgui.ListItem(**kwargs)

if mime_type:
if mime_type or is_external:
list_item.setContentLookup(False)
list_item.setMimeType(mime_type)
list_item.setMimeType(mime_type or '*/*')

if is_strm:
list_item.setProperties(props)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,6 @@ def cleanup_threads(self, only_ended=True):

def onPlayBackStarted(self):
if self._ui.get_property(SWITCH_PLAYER_FLAG):
self._context.execute('Action(FullScreen)')
self._context.execute('Action(SwitchPlayer)')
self._context.execute('Action(Stop)')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class ServiceMonitor(xbmc.Monitor):

def __init__(self):
settings = self._settings
self._use_httpd = settings.use_isa() or settings.api_config_page()
self._use_httpd = (settings.use_isa()
or settings.api_config_page()
or settings.support_alternative_player())
address, port = get_connect_address()
self._old_httpd_address = self._httpd_address = address
self._old_httpd_port = self._httpd_port = port
Expand Down
51 changes: 35 additions & 16 deletions resources/lib/youtube_plugin/kodion/network/http_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from ..constants import ADDON_ID, TEMP_PATH, paths
from ..logger import log_debug, log_error
from ..settings import XbmcPluginSettings
from ..utils import validate_ip_address
from ..utils import validate_ip_address, wait


_addon = xbmcaddon.Addon(ADDON_ID)
Expand Down Expand Up @@ -103,7 +103,7 @@ def do_GET(self):
self.end_headers()
self.wfile.write(client_json.encode('utf-8'))

elif self.path.startswith(paths.MPD):
elif stripped_path.startswith(paths.MPD):
filepath = os.path.join(self.BASE_PATH, self.path[len(paths.MPD):])
file_chunk = True
try:
Expand Down Expand Up @@ -134,8 +134,8 @@ def do_GET(self):
for chunk in self.get_chunks(html):
self.wfile.write(chunk)

elif api_config_enabled and self.path.startswith(paths.API_SUBMIT):
xbmc.executebuiltin('Dialog.Close(addonsettings, true)')
elif api_config_enabled and stripped_path.startswith(paths.API_SUBMIT):
xbmc.executebuiltin('Dialog.Close(addonsettings,true)')

query = urlsplit(self.path).query
params = parse_qs(query)
Expand Down Expand Up @@ -192,6 +192,16 @@ def do_GET(self):
elif stripped_path == paths.PING:
self.send_error(204)

elif stripped_path.startswith(paths.REDIRECT):
url = parse_qs(urlsplit(self.path).query).get('url')
if url:
wait(1)
self.send_response(301)
self.send_header('Location', url[0])
self.end_headers()
else:
self.send_error(501)

else:
self.send_error(501)

Expand All @@ -215,6 +225,9 @@ def do_HEAD(self):
str(os.path.getsize(filepath)))
self.end_headers()

elif self.path.startswith(paths.REDIRECT):
self.send_error(404)

else:
self.send_error(501)

Expand Down Expand Up @@ -579,22 +592,28 @@ def get_client_ip_address():
return ip_address


def get_connect_address():
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
return xbmc.getIPAddress()

def get_connect_address(as_netloc=False):
address = _settings.httpd_listen()
port = _settings.httpd_port()
if address == '0.0.0.0':
address = '127.0.0.1'

sock.settimeout(0)
sock = None
try:
sock.connect((address, 0))
return sock.getsockname()[0], port
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
return xbmc.getIPAddress(), port
finally:
sock.close()
address = xbmc.getIPAddress()

if sock:
sock.settimeout(0)
try:
sock.connect((address, 0))
address = sock.getsockname()[0]
except socket.error:
address = xbmc.getIPAddress()
finally:
sock.close()

if as_netloc:
return ':'.join((address, str(port)))
return address, port
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,29 @@ def support_alternative_player(self, value=None):
return self.set_bool(settings.SUPPORT_ALTERNATIVE_PLAYER, value)
return self.get_bool(settings.SUPPORT_ALTERNATIVE_PLAYER, False)

def default_player_web_urls(self, value=None):
if value is not None:
return self.set_bool(settings.DEFAULT_PLAYER_WEB_URLS, value)
if self.support_alternative_player():
return self.get_bool(settings.DEFAULT_PLAYER_WEB_URLS, False)
return False

def alternative_player_web_urls(self, value=None):
if value is not None:
return self.set_bool(settings.ALTERNATIVE_PLAYER_WEB_URLS, value)
if self.support_alternative_player():
if (self.support_alternative_player()
and not self.default_player_web_urls()
and not self.alternative_player_adaptive()):
return self.get_bool(settings.ALTERNATIVE_PLAYER_WEB_URLS, False)
return False

def alternative_player_adaptive(self, value=None):
if value is not None:
return self.set_bool(settings.ALTERNATIVE_PLAYER_ADAPTIVE, value)
if self.support_alternative_player():
return self.get_bool(settings.ALTERNATIVE_PLAYER_ADAPTIVE, False)
return False

def use_isa(self, value=None):
if value is not None:
return self.set_bool(settings.USE_ISA, value)
Expand Down
5 changes: 3 additions & 2 deletions resources/lib/youtube_plugin/kodion/utils/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,14 @@ def select_stream(context,
stream_data_list,
quality_map_override=None,
ask_for_quality=None,
audio_only=None):
audio_only=None,
use_adaptive_formats=True):
# sort - best stream first
def _sort_stream_data(_stream_data):
return _stream_data.get('sort', (0, 0))

settings = context.get_settings()
use_adaptive = context.use_inputstream_adaptive()
use_adaptive = use_adaptive_formats and context.use_inputstream_adaptive()
if ask_for_quality is None:
ask_for_quality = context.get_settings().ask_for_video_quality()
video_quality = settings.get_video_quality(quality_map_override)
Expand Down
4 changes: 2 additions & 2 deletions resources/lib/youtube_plugin/youtube/helper/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,8 @@ def update_video_infos(provider, context, video_id_dict,

settings = context.get_settings()
alternate_player = settings.support_alternative_player()
alternate_web_urls = settings.alternative_player_web_urls()
ask_quality = not alternate_web_urls and settings.ask_for_video_quality()
default_web_urls = settings.default_player_web_urls()
ask_quality = not default_web_urls and settings.ask_for_video_quality()
audio_only = settings.audio_only()
hide_shorts = settings.hide_short_videos()
show_details = settings.show_detailed_description()
Expand Down
Loading

0 comments on commit 0d4afbe

Please sign in to comment.