plugin.video.viervijfzes/resources/lib/modules/player.py

162 lines
6.3 KiB
Python
Raw Normal View History

2020-03-19 16:45:31 +01:00
# -*- coding: utf-8 -*-
""" Player module """
from __future__ import absolute_import, division, unicode_literals
import logging
2020-04-02 20:21:00 +02:00
import os
2020-03-19 16:45:31 +01:00
from resources.lib import kodiutils
2020-04-02 20:21:00 +02:00
from resources.lib.downloader import Downloader
2020-03-19 16:45:31 +01:00
from resources.lib.viervijfzes.auth import AuthApi
2020-03-22 10:30:23 +01:00
from resources.lib.viervijfzes.auth_awsidp import InvalidLoginException, AuthenticationException
2020-03-19 16:45:31 +01:00
from resources.lib.viervijfzes.content import ContentApi, UnavailableException, GeoblockedException
_LOGGER = logging.getLogger('player')
class Player:
""" Code responsible for playing media """
def __init__(self):
""" Initialise object """
2020-04-02 20:21:00 +02:00
auth = AuthApi(kodiutils.get_setting('username'), kodiutils.get_setting('password'), kodiutils.get_tokens_path())
self._api = ContentApi(auth)
2020-03-19 16:45:31 +01:00
def play_from_page(self, channel, path):
""" Play the requested item.
:type channel: string
:type path: string
"""
# Get episode information
2020-03-21 20:34:07 +01:00
episode = ContentApi().get_episode(channel, path)
2020-03-19 16:45:31 +01:00
# Play this now we have the uuid
self.play(episode.uuid)
2020-03-19 16:45:31 +01:00
2020-04-02 20:21:00 +02:00
def play(self, uuid):
2020-03-19 16:45:31 +01:00
""" Play the requested item.
2020-04-02 20:21:00 +02:00
:type uuid: string
2020-03-19 16:45:31 +01:00
"""
2020-04-02 20:21:00 +02:00
if kodiutils.get_setting_bool('episode_cache_enabled'):
# Check for a cached version
cached_file = self._check_cached_episode(uuid)
if cached_file:
kodiutils.play(cached_file)
return
2020-03-25 07:50:45 +01:00
# Workaround for Raspberry Pi 3 and older
omxplayer = kodiutils.get_global_setting('videoplayer.useomxplayer')
if omxplayer is False:
kodiutils.set_global_setting('videoplayer.useomxplayer', True)
2020-04-02 20:21:00 +02:00
# Resolve the stream
resolved_stream = self._fetch_stream(uuid)
if not resolved_stream:
kodiutils.end_of_directory()
return
# Play this item
kodiutils.play(resolved_stream)
def download(self, uuid):
""" Download the requested item to cache.
:type uuid: string
"""
# We can notify Kodi already that we won't be returning a listing.
# This also fixes an odd Kodi bug where a starting a Progress() without closing the directory listing causes Kodi to hang.
kodiutils.end_of_directory()
# Check ffmpeg
if not Downloader.check():
kodiutils.ok_dialog(message=kodiutils.localize(30719)) # Could not download this episode since ffmpeg seems to be unavailable.
return
# Check download folder
download_folder = kodiutils.get_setting('episode_cache_folder').rstrip('/')
if not os.path.exists(download_folder):
kodiutils.ok_dialog(message=kodiutils.localize(30718)) # Could not download this episode since the download folder is not set or does not exist.
return
# Check if we already have downloaded this file
download_path = '%s/%s.mp4' % (download_folder, uuid)
if os.path.isfile(download_path):
# You have already downloaded this episode. Do you want to download it again?
result = kodiutils.yesno_dialog(message=kodiutils.localize(30726))
if not result:
return
# Download this item
downloader = Downloader()
progress = kodiutils.progress(message=kodiutils.localize(30723)) # Starting download...
def callback(total, current):
""" Callback function to update the progress bar. """
percentage = current * 100 / total
progress.update(int(percentage), kodiutils.localize(30724, amount=round(percentage, 2))) # Downloading... ({amount}%)
return progress.iscanceled()
# Resolve the stream and start the download
resolved_stream = self._fetch_stream(uuid)
status = downloader.download(resolved_stream, download_path, callback)
# Close the progress bar
progress.close()
if status:
kodiutils.ok_dialog(message=kodiutils.localize(30725)) # Download has finished. You can now play this episode from cache.
def _fetch_stream(self, uuid):
""" Fetches the HLS stream of the item.
:type uuid: string
"""
2020-03-19 16:45:31 +01:00
try:
2020-03-21 20:34:07 +01:00
# Check if we have credentials
if not kodiutils.get_setting('username') or not kodiutils.get_setting('password'):
2020-03-22 10:30:23 +01:00
confirm = kodiutils.yesno_dialog(
message=kodiutils.localize(30701)) # To watch a video, you need to enter your credentials. Do you want to enter them now?
2020-03-21 20:34:07 +01:00
if confirm:
kodiutils.open_settings()
2020-04-02 20:21:00 +02:00
return None
2020-03-21 20:34:07 +01:00
2020-03-22 10:30:23 +01:00
try:
# Get stream information
2020-04-02 20:21:00 +02:00
resolved_stream = self._api.get_stream_by_uuid(uuid)
2020-03-22 10:30:23 +01:00
except (InvalidLoginException, AuthenticationException) as ex:
_LOGGER.error(ex)
kodiutils.ok_dialog(message=kodiutils.localize(30702, error=str(ex)))
2020-04-02 20:21:00 +02:00
return None
2020-03-21 20:34:07 +01:00
2020-03-19 16:45:31 +01:00
except GeoblockedException:
kodiutils.ok_dialog(heading=kodiutils.localize(30709), message=kodiutils.localize(30710)) # This video is geo-blocked...
2020-04-02 20:21:00 +02:00
return None
2020-03-19 16:45:31 +01:00
except UnavailableException:
kodiutils.ok_dialog(heading=kodiutils.localize(30711), message=kodiutils.localize(30712)) # The video is unavailable...
2020-04-02 20:21:00 +02:00
return None
2020-03-19 16:45:31 +01:00
2020-04-02 20:21:00 +02:00
return resolved_stream
@staticmethod
def _check_cached_episode(uuid):
""" Check if this episode is available in the download cache.
:type uuid: string
"""
download_folder = kodiutils.get_setting('episode_cache_folder').rstrip('/')
if not download_folder or not os.path.exists(download_folder):
return None
# Check if we already have downloaded this file
download_path = '%s/%s.mp4' % (download_folder, uuid)
if os.path.isfile(download_path):
# You have cached this episode. Do you want to play from your cache or stream it?
result = kodiutils.yesno_dialog(message=kodiutils.localize(30720),
yeslabel=kodiutils.localize(30721), # Stream
nolabel=kodiutils.localize(30722)) # Play from cache
if not result:
return download_path
return None