From f84114f370cf0117e26e05c1c47c923f4afd4a19 Mon Sep 17 00:00:00 2001 From: Juan Fran Date: Fri, 27 Oct 2023 14:16:07 +0200 Subject: [PATCH 1/5] Create shaka.py Create ShakaController to interact with ShakaPlayer --- pychromecast/controllers/shaka.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 pychromecast/controllers/shaka.py diff --git a/pychromecast/controllers/shaka.py b/pychromecast/controllers/shaka.py new file mode 100644 index 000000000..d09162806 --- /dev/null +++ b/pychromecast/controllers/shaka.py @@ -0,0 +1,13 @@ +""" +Simple Controller to use Shaka as a media controller. +""" + +from ..config import APP_SHAKA +from .media import BaseMediaPlayer + + +class ShakaController(BaseMediaPlayer): + """Controller to interact with Shaka app namespace.""" + + def __init__(self): + super().__init__(supporting_app_id=APP_SHAKA) From c31fa8cf1fdb8780f1bd79b9547bc74db86e44be Mon Sep 17 00:00:00 2001 From: Juan Fran Date: Fri, 27 Oct 2023 14:19:31 +0200 Subject: [PATCH 2/5] Add changes to Shaka player and example --- examples/shaka_drm_example.py | 131 ++++++++++++++++++++++++++++++++++ pychromecast/config.py | 1 + pychromecast/quick_play.py | 3 + 3 files changed, 135 insertions(+) create mode 100644 examples/shaka_drm_example.py diff --git a/examples/shaka_drm_example.py b/examples/shaka_drm_example.py new file mode 100644 index 000000000..702b2b94c --- /dev/null +++ b/examples/shaka_drm_example.py @@ -0,0 +1,131 @@ +""" +Example on how to use the BubbleUPNP Controller to play an URL. + +""" +# pylint: disable=invalid-name + +import argparse +import logging +import sys +from time import sleep + +import zeroconf + +import pychromecast +from pychromecast import quick_play + + +# Change to the friendly name of your Chromecast +CAST_NAME = "Living Room" + +# Change to an audio or video url +# Sample DRM request from https://reference.dashif.org/dash.js/latest/samples/drm/clearkey.html +MEDIA_URL = ( + "https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p_ClearKey.mpd" +) + +parser = argparse.ArgumentParser( + description="Example on how to use the Shaka Controller to play an URL with DRM." +) +parser.add_argument( + "--cast", help='Name of cast device (default: "%(default)s")', default=CAST_NAME +) +parser.add_argument( + "--known-host", + help="Add known host (IP), can be used multiple times", + action="append", +) +parser.add_argument("--show-debug", help="Enable debug log", action="store_true") +parser.add_argument( + "--show-zeroconf-debug", help="Enable zeroconf debug log", action="store_true" +) +parser.add_argument( + "--url", help='Media url (default: "%(default)s")', default=MEDIA_URL +) +args = parser.parse_args() + +if args.show_debug: + logging.basicConfig(level=logging.DEBUG) +if args.show_zeroconf_debug: + print("Zeroconf version: " + zeroconf.__version__) + logging.getLogger("zeroconf").setLevel(logging.DEBUG) + +# pylint: disable=unbalanced-tuple-unpacking +chromecasts, browser = pychromecast.get_listed_chromecasts( + friendly_names=[args.cast], known_hosts=args.known_host +) +if not chromecasts: + print(f'No chromecast with name "{args.cast}" discovered') + sys.exit(1) + +cast = list(chromecasts)[0] +# Start socket client's worker thread and wait for initial status update +cast.wait() +print(f'Found chromecast with name "{args.cast}", attempting to play "{args.url}"') + +# Take customData from shaka player appData object sent in init message to chromecast +app_name = "shaka" +app_data = { + "media_id": args.url, + "media_type": "", + "stream_type": "LIVE", + "media_info": { + "customData": { + "asset": { + "name": "Custom DRM Video", + "shortName": "", + "iconUri": "", + "manifestUri": "https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p_ClearKey.mpd", + "source": "Custom", + "focus": False, + "disabled": False, + "extraText": [], + "extraThumbnail": [], + "certificateUri": None, + "description": None, + "isFeatured": False, + "drm": [ + "No DRM protection" + ], + "features": [ + "VOD" + ], + "licenseServers": { + "__type__": "map" + }, + "licenseRequestHeaders": { + "__type__": "map" + }, + "requestFilter": None, + "responseFilter": None, + "clearKeys": { + "__type__": "map" + }, + "extraConfig": { + "drm": { + "clearKeys": { + "nrQFDeRLSAKTLifXUIPiZg": "FmY0xnWCPCNaSpRG-tUuTQ" + } + } + }, + "adTagUri": None, + "imaVideoId": None, + "imaAssetKey": None, + "imaContentSrcId": None, + "imaManifestType": None, + "mediaTailorUrl": None, + "mediaTailorAdsParams": None, + "mimeType": None, + "mediaPlaylistFullMimeType": None, + "storedProgress": 1, + "storedContent": None + } + } + } + +} +quick_play.quick_play(cast, app_name, app_data) + +sleep(10) + +browser.stop_discovery() diff --git a/pychromecast/config.py b/pychromecast/config.py index 9a375cdda..7549f54ff 100644 --- a/pychromecast/config.py +++ b/pychromecast/config.py @@ -17,6 +17,7 @@ APP_BUBBLEUPNP = "3927FA74" APP_BBCSOUNDS = "03977A48" APP_BBCIPLAYER = "5E81F6DB" +APP_SHAKA = "07AEE832" def get_possible_app_ids(): diff --git a/pychromecast/quick_play.py b/pychromecast/quick_play.py index 96976cd37..da712df4d 100644 --- a/pychromecast/quick_play.py +++ b/pychromecast/quick_play.py @@ -8,6 +8,7 @@ from .controllers.supla import SuplaController from .controllers.yleareena import YleAreenaController from .controllers.youtube import YouTubeController +from .controllers.shaka import ShakaController def quick_play(cast, app_name, data): @@ -69,6 +70,8 @@ def quick_play(cast, app_name, data): controller = YleAreenaController() elif app_name == "youtube": controller = YouTubeController() + elif app_name == "shaka": + controller = ShakaController() else: raise NotImplementedError() From 7a37dbc58a10857c9c27fe877c6263a31bc39bde Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 3 Jan 2024 22:59:21 +0100 Subject: [PATCH 3/5] Update examples/shaka_drm_example.py --- examples/shaka_drm_example.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/shaka_drm_example.py b/examples/shaka_drm_example.py index 702b2b94c..5f62d2fd6 100644 --- a/examples/shaka_drm_example.py +++ b/examples/shaka_drm_example.py @@ -1,5 +1,6 @@ """ -Example on how to use the BubbleUPNP Controller to play an URL. +Example on how to use the Shaka Controller to play an URL. + """ # pylint: disable=invalid-name From 763330e5fb7399767fa17c348ee1e27d31be745d Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 3 Jan 2024 23:03:11 +0100 Subject: [PATCH 4/5] Format code --- examples/shaka_drm_example.py | 90 ++++++++++++++++------------------- 1 file changed, 40 insertions(+), 50 deletions(-) diff --git a/examples/shaka_drm_example.py b/examples/shaka_drm_example.py index 5f62d2fd6..4a9cb7884 100644 --- a/examples/shaka_drm_example.py +++ b/examples/shaka_drm_example.py @@ -71,60 +71,50 @@ "media_type": "", "stream_type": "LIVE", "media_info": { - "customData": { - "asset": { - "name": "Custom DRM Video", - "shortName": "", - "iconUri": "", - "manifestUri": "https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p_ClearKey.mpd", - "source": "Custom", - "focus": False, - "disabled": False, - "extraText": [], - "extraThumbnail": [], - "certificateUri": None, - "description": None, - "isFeatured": False, - "drm": [ - "No DRM protection" - ], - "features": [ - "VOD" - ], - "licenseServers": { - "__type__": "map" - }, - "licenseRequestHeaders": { - "__type__": "map" - }, - "requestFilter": None, - "responseFilter": None, - "clearKeys": { - "__type__": "map" - }, - "extraConfig": { - "drm": { - "clearKeys": { - "nrQFDeRLSAKTLifXUIPiZg": "FmY0xnWCPCNaSpRG-tUuTQ" + "customData": { + "asset": { + "name": "Custom DRM Video", + "shortName": "", + "iconUri": "", + "manifestUri": "https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p_ClearKey.mpd", + "source": "Custom", + "focus": False, + "disabled": False, + "extraText": [], + "extraThumbnail": [], + "certificateUri": None, + "description": None, + "isFeatured": False, + "drm": ["No DRM protection"], + "features": ["VOD"], + "licenseServers": {"__type__": "map"}, + "licenseRequestHeaders": {"__type__": "map"}, + "requestFilter": None, + "responseFilter": None, + "clearKeys": {"__type__": "map"}, + "extraConfig": { + "drm": { + "clearKeys": { + "nrQFDeRLSAKTLifXUIPiZg": "FmY0xnWCPCNaSpRG-tUuTQ" + } } - } - }, - "adTagUri": None, - "imaVideoId": None, - "imaAssetKey": None, - "imaContentSrcId": None, - "imaManifestType": None, - "mediaTailorUrl": None, - "mediaTailorAdsParams": None, - "mimeType": None, - "mediaPlaylistFullMimeType": None, - "storedProgress": 1, - "storedContent": None + }, + "adTagUri": None, + "imaVideoId": None, + "imaAssetKey": None, + "imaContentSrcId": None, + "imaManifestType": None, + "mediaTailorUrl": None, + "mediaTailorAdsParams": None, + "mimeType": None, + "mediaPlaylistFullMimeType": None, + "storedProgress": 1, + "storedContent": None, } } - } - + }, } + quick_play.quick_play(cast, app_name, app_data) sleep(10) From 334c14c5452c4c1adfb8a59ce00528ad381c96f2 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 3 Jan 2024 23:04:49 +0100 Subject: [PATCH 5/5] For --- examples/shaka_drm_example.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/shaka_drm_example.py b/examples/shaka_drm_example.py index 4a9cb7884..9349a812d 100644 --- a/examples/shaka_drm_example.py +++ b/examples/shaka_drm_example.py @@ -21,9 +21,7 @@ # Change to an audio or video url # Sample DRM request from https://reference.dashif.org/dash.js/latest/samples/drm/clearkey.html -MEDIA_URL = ( - "https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p_ClearKey.mpd" -) +MEDIA_URL = "https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p_ClearKey.mpd" parser = argparse.ArgumentParser( description="Example on how to use the Shaka Controller to play an URL with DRM."