shaka-player 3.2.2 → 3.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
- package/.github/ISSUE_TEMPLATE/feature_request.md +1 -1
- package/.github/ISSUE_TEMPLATE/question.md +1 -1
- package/.github/workflows/build_and_test.yaml +73 -0
- package/.github/workflows/release.yaml +53 -0
- package/AUTHORS +6 -5
- package/CHANGELOG.md +314 -1
- package/CONTRIBUTORS +4 -2
- package/build/checkversion.py +1 -1
- package/build/conformance.textproto +183 -169
- package/build/test.py +6 -0
- package/build/types/core +3 -0
- package/build/types/offline +1 -0
- package/build/types/polyfill +1 -0
- package/build/types/ui +2 -0
- package/demo/common/assets.js +18 -0
- package/demo/common/message_ids.js +13 -1
- package/demo/config.js +31 -1
- package/demo/index.html +1 -1
- package/demo/locales/en.json +12 -0
- package/demo/locales/source.json +48 -0
- package/dist/controls.css +26 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +19 -16
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +19 -16
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +21 -14
- package/dist/locales.js +31 -29
- package/dist/receiver.compiled.debug.js +11 -9
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +11 -9
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +232 -18
- package/dist/shaka-player.compiled.debug.d.ts +232 -18
- package/dist/shaka-player.compiled.debug.externs.js +293 -17
- package/dist/shaka-player.compiled.debug.js +481 -422
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +293 -17
- package/dist/shaka-player.compiled.js +846 -817
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +250 -30
- package/dist/shaka-player.ui.debug.d.ts +250 -30
- package/dist/shaka-player.ui.debug.externs.js +322 -28
- package/dist/shaka-player.ui.debug.js +630 -553
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +322 -28
- package/dist/shaka-player.ui.js +1048 -1006
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/bg-fetch-after.gv +29 -0
- package/docs/design/bg-fetch-after.gv.png +0 -0
- package/docs/design/bg-fetch-before.gv +18 -0
- package/docs/design/bg-fetch-before.gv.png +0 -0
- package/docs/design/bg-fetch.md +134 -0
- package/docs/tutorials/blob-url.md +15 -0
- package/docs/tutorials/index.json +1 -0
- package/docs/tutorials/ui-customization.md +66 -0
- package/docs/tutorials/ui.md +5 -5
- package/externs/cmcd.js +186 -0
- package/externs/ima.js +3 -0
- package/externs/shaka/ads.js +5 -0
- package/externs/shaka/manifest.js +12 -1
- package/externs/shaka/manifest_parser.js +10 -1
- package/externs/shaka/net.js +20 -4
- package/externs/shaka/offline.js +31 -2
- package/externs/shaka/player.js +138 -5
- package/externs/shaka/text.js +24 -0
- package/externs/webcrypto.js +18 -0
- package/karma.conf.js +19 -15
- package/lib/abr/ewma.js +14 -0
- package/lib/abr/ewma_bandwidth_estimator.js +16 -2
- package/lib/abr/simple_abr_manager.js +6 -0
- package/lib/ads/ad_manager.js +1 -0
- package/lib/ads/client_side_ad.js +8 -0
- package/lib/ads/client_side_ad_manager.js +8 -4
- package/lib/ads/server_side_ad.js +7 -0
- package/lib/cast/cast_proxy.js +3 -0
- package/lib/cast/cast_receiver.js +3 -0
- package/lib/cast/cast_utils.js +1 -0
- package/lib/dash/dash_parser.js +79 -33
- package/lib/dash/segment_base.js +25 -1
- package/lib/dash/segment_list.js +18 -9
- package/lib/dash/segment_template.js +23 -10
- package/lib/hls/hls_parser.js +116 -23
- package/lib/hls/manifest_text_parser.js +1 -0
- package/lib/media/quality_observer.js +274 -0
- package/lib/media/region_observer.js +39 -33
- package/lib/media/region_timeline.js +17 -19
- package/lib/media/segment_index.js +8 -1
- package/lib/media/segment_reference.js +37 -4
- package/lib/media/streaming_engine.js +47 -6
- package/lib/net/http_fetch_plugin.js +31 -11
- package/lib/net/http_plugin_utils.js +1 -0
- package/lib/net/http_xhr_plugin.js +40 -14
- package/lib/net/networking_engine.js +85 -18
- package/lib/offline/download_info.js +68 -0
- package/lib/offline/download_manager.js +13 -5
- package/lib/offline/indexeddb/base_storage_cell.js +35 -0
- package/lib/offline/indexeddb/storage_mechanism.js +1 -1
- package/lib/offline/indexeddb/v5_storage_cell.js +5 -0
- package/lib/offline/storage.js +401 -293
- package/lib/offline/stored_content_utils.js +2 -0
- package/lib/player.js +254 -27
- package/lib/polyfill/media_capabilities.js +30 -15
- package/lib/polyfill/random_uuid.js +52 -0
- package/lib/text/cue.js +18 -0
- package/lib/text/ttml_text_parser.js +109 -60
- package/lib/text/ui_text_displayer.js +19 -13
- package/lib/util/cmcd_manager.js +672 -0
- package/lib/util/error.js +6 -0
- package/lib/util/fake_event_target.js +21 -1
- package/lib/util/language_utils.js +12 -0
- package/lib/util/mutex.js +52 -0
- package/lib/util/periods.js +98 -64
- package/lib/util/player_configuration.js +18 -0
- package/lib/util/stream_utils.js +86 -10
- package/lib/util/xml_utils.js +19 -0
- package/package.json +3 -6
- package/shaka-player.uncompiled.js +3 -0
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_live_unit.js +144 -1
- package/test/dash/dash_parser_manifest_unit.js +37 -2
- package/test/dash/dash_parser_segment_base_unit.js +2 -0
- package/test/dash/dash_parser_segment_list_unit.js +2 -1
- package/test/dash/dash_parser_segment_template_unit.js +2 -1
- package/test/hls/hls_live_unit.js +2 -0
- package/test/hls/hls_parser_unit.js +76 -0
- package/test/media/drm_engine_unit.js +3 -3
- package/test/media/quality_observer_unit.js +142 -0
- package/test/media/region_observer_unit.js +40 -5
- package/test/media/region_timeline_unit.js +40 -22
- package/test/media/segment_reference_unit.js +16 -1
- package/test/media/streaming_engine_integration.js +4 -2
- package/test/media/streaming_engine_unit.js +147 -0
- package/test/net/http_plugin_unit.js +20 -15
- package/test/offline/storage_integration.js +108 -4
- package/test/player_integration.js +140 -8
- package/test/player_src_equals_integration.js +41 -8
- package/test/player_unit.js +19 -9
- package/test/test/assets/chapters.vtt +2 -2
- package/test/test/assets/chapters2.vtt +10 -0
- package/test/test/util/dash_parser_util.js +4 -0
- package/test/test/util/fake_ad.js +7 -0
- package/test/test/util/fake_drm_engine.js +9 -2
- package/test/test/util/manifest_generator.js +3 -2
- package/test/test/util/test_scheme.js +14 -1
- package/test/test/util/ttml_utils.js +81 -0
- package/test/test/util/util.js +10 -7
- package/test/text/mp4_ttml_parser_unit.js +11 -18
- package/test/text/ttml_text_parser_unit.js +544 -228
- package/test/ui/text_displayer_layout_unit.js +8 -7
- package/test/ui/ui_unit.js +250 -0
- package/test/util/cmcd_manager_unit.js +291 -0
- package/test/util/stream_utils_unit.js +36 -30
- package/third_party/closure-uri/uri.js +21 -0
- package/ui/airplay_button.js +1 -0
- package/ui/audio_language_selection.js +7 -0
- package/ui/cast_button.js +1 -0
- package/ui/context_menu.js +109 -0
- package/ui/controls.js +44 -7
- package/ui/controls.less +1 -0
- package/ui/enums.js +4 -0
- package/ui/externs/ui.js +28 -1
- package/ui/fast_forward_button.js +14 -5
- package/ui/fullscreen_button.js +1 -0
- package/ui/less/buttons.less +0 -4
- package/ui/less/containers.less +74 -0
- package/ui/less/overflow_menu.less +0 -10
- package/ui/less/tooltip.less +97 -0
- package/ui/locales/en.json +1 -0
- package/ui/locales/source.json +4 -0
- package/ui/localization.js +12 -36
- package/ui/loop_button.js +5 -0
- package/ui/mute_button.js +2 -1
- package/ui/overflow_menu.js +5 -25
- package/ui/pip_button.js +5 -0
- package/ui/play_button.js +2 -2
- package/ui/playback_rate_selection.js +8 -9
- package/ui/resolution_selection.js +7 -0
- package/ui/rewind_button.js +15 -6
- package/ui/seek_bar.js +4 -2
- package/ui/settings_menu.js +36 -4
- package/ui/small_play_button.js +1 -0
- package/ui/statistics_button.js +253 -0
- package/ui/text_selection.js +12 -4
- package/ui/ui.js +30 -0
- package/ui/volume_bar.js +1 -1
- package/externs/media_capabilities.js +0 -16
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Generate png with: dot -Tpng -O after.gv
|
|
2
|
+
digraph storage_after {
|
|
3
|
+
subgraph cluster_0 {
|
|
4
|
+
label="Shaka Player";
|
|
5
|
+
parse[label="Download and parse manifest (parseManifest)"];
|
|
6
|
+
drm[label="Make DRM engine and load keys (createDrmEngine)"]
|
|
7
|
+
filter[label="Filter manifest (filterManifest_)"];
|
|
8
|
+
segments[label="Download segments (downloadSegments_)"];
|
|
9
|
+
store[label="Store manifest (cell.addManifests)"];
|
|
10
|
+
parse -> drm;
|
|
11
|
+
drm -> filter;
|
|
12
|
+
filter -> store;
|
|
13
|
+
store -> segments[label="BG Fetch Not Available"];
|
|
14
|
+
}
|
|
15
|
+
subgraph cluster_1 {
|
|
16
|
+
label="Service Worker";
|
|
17
|
+
bgSegments[label="Download segments in background (backgroundFetch.fetch)"]
|
|
18
|
+
store -> bgSegments[label="BG Fetch Available"];
|
|
19
|
+
}
|
|
20
|
+
subgraph cluster_2 {
|
|
21
|
+
label="Shaka Player Static Methods";
|
|
22
|
+
storeSeg[label="Store segments one-by-one (assignStreamToManifest)"]
|
|
23
|
+
remove[label="Clean up (cleanStoredManifest)"];
|
|
24
|
+
segments -> remove[label="On Fail"];
|
|
25
|
+
segments -> storeSeg;
|
|
26
|
+
bgSegments -> storeSeg;
|
|
27
|
+
bgSegments -> remove[label="On Fail"];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generate png with: dot -Tpng -O before.gv
|
|
2
|
+
digraph storage_before {
|
|
3
|
+
subgraph cluster_0 {
|
|
4
|
+
label="Shaka Player";
|
|
5
|
+
parse[label="Download and parse manifest (parseManifest)"];
|
|
6
|
+
drm[label="Make DRM engine and load keys (createDrmEngine)"]
|
|
7
|
+
filter[label="Filter manifest (filterManifest_)"];
|
|
8
|
+
segments[label="Download and store segments (downloadManifest_)"];
|
|
9
|
+
store[label="Store manifest (cell.addManifests)"];
|
|
10
|
+
remove[label="Clean up (cell.removeSegments)"];
|
|
11
|
+
parse -> drm;
|
|
12
|
+
drm -> filter;
|
|
13
|
+
filter -> segments;
|
|
14
|
+
segments -> store;
|
|
15
|
+
segments -> remove[label="On Fail"];
|
|
16
|
+
store -> remove[label="On Fail"];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Shaka Player Background Fetch Support
|
|
2
|
+
|
|
3
|
+
last update: 2021-7-12
|
|
4
|
+
|
|
5
|
+
by: [theodab@google.com](mailto:theodab@google.com)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
The feature of background fetch has been in Shaka Player’s backlog [since 2017].
|
|
11
|
+
At the time it was added to the backlog, the feature was not quite ready for
|
|
12
|
+
use. Since then, it has matured, and now is something we could feasibly use, but
|
|
13
|
+
it has still been a low-priority feature.
|
|
14
|
+
|
|
15
|
+
[since 2017]: https://github.com/google/shaka-player/issues/879
|
|
16
|
+
|
|
17
|
+
## Design Concept
|
|
18
|
+
|
|
19
|
+
This design attempts to reuse existing code whenever possible, in order to
|
|
20
|
+
minimize the amount of new code that has to be tested. The code will be made in
|
|
21
|
+
two main stages:
|
|
22
|
+
1. Refactor the offline download process to change the order that the asset is
|
|
23
|
+
downloaded. The manifest should be downloaded and stored first, and then every
|
|
24
|
+
segment should be downloaded. As a segment is downloaded, it should be stored.
|
|
25
|
+
The code for storing a segment, in particular, should be broken out into an
|
|
26
|
+
exported static (e.g. stateless) function.
|
|
27
|
+
1. Modify the Shaka Player wrapper to add the appropriate background fetch event
|
|
28
|
+
listeners if the environment is detected to be a service worker, so that a
|
|
29
|
+
compiled Shaka Player bundle can be used as a service worker. If background
|
|
30
|
+
fetch is used, the segment downloading step should be passed to this service
|
|
31
|
+
worker. When each segment is downloaded, it should be passed to the static
|
|
32
|
+
storage functions added in stage 1.
|
|
33
|
+
|
|
34
|
+
By restructuring the offline storage code in this way, switching between
|
|
35
|
+
foreground and background fetch will just be a matter of calling a different
|
|
36
|
+
segment-downloading function. In addition, it is possible that, in the future, a
|
|
37
|
+
plugin interface could be made for this. That probably won’t be necessary unless
|
|
38
|
+
another browser makes a competing API for downloading in the background (which
|
|
39
|
+
is admittedly a possibility, as background fetch [is not yet a W3C standard]).
|
|
40
|
+
|
|
41
|
+
[is not yet a W3C standard]: https://wicg.github.io/background-fetch/
|
|
42
|
+
|
|
43
|
+
### Storage System Process: Before
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Storage System Process: After
|
|
49
|
+
|
|
50
|
+

|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## Implementation
|
|
54
|
+
|
|
55
|
+
### Changes to shaka.offline.Storage
|
|
56
|
+
|
|
57
|
+
1. Change createOfflineManifest_ to leave the storage indexes on the segments
|
|
58
|
+
null at first. With this change, downloadManifest_ will now only be downloading
|
|
59
|
+
the encryption keys (which cannot be downloaded via background fetch, as they
|
|
60
|
+
require request bodies).
|
|
61
|
+
1. Create a new step within store_, after the manifest is stored, called
|
|
62
|
+
“downloadSegments_” that makes a Set of SegmentReference objects that need to be
|
|
63
|
+
downloaded.
|
|
64
|
+
1. We use SegmentReference objects in order to contain the URI, startByte,
|
|
65
|
+
and endByte.
|
|
66
|
+
1. This change also means we will no longer need an internal cache for
|
|
67
|
+
downloaded segments, as they will be deduplicated by the use of a Set.
|
|
68
|
+
1. If background fetch is not available, downloadSegments_ will simply download
|
|
69
|
+
the segments from this set as before, and then once they are all downloaded,
|
|
70
|
+
pass them all to assignStreamsToManifest.
|
|
71
|
+
1. If background fetch is available, this set will be turned into an array,
|
|
72
|
+
Request objects should be made for the individual uris (with appropriate headers
|
|
73
|
+
applied), and then that array will be passed to the service worker with a
|
|
74
|
+
background fetch call. The service worker will then, after everything is
|
|
75
|
+
downloaded and stored, call assignStreamsToManifest. An estimate of the total
|
|
76
|
+
download size will need to be computed here, and padded to avoid premature
|
|
77
|
+
cancellation for inaccurate manifests.
|
|
78
|
+
1. Create a new public static method, assignStreamToManifest. This is a static
|
|
79
|
+
method that requires no internal state, so that the service worker can call it.
|
|
80
|
+
It stores the data provided, loads the manifest from storage, applies the
|
|
81
|
+
storage id of the data to the appropriate segments (based on uri), and then
|
|
82
|
+
stores the modified manifest. It should have a mutex over the part that loads
|
|
83
|
+
and changes the manifest, to keep one invocation from overriding the manifest
|
|
84
|
+
changes of another. It should have the following parameters:
|
|
85
|
+
1. manifestStorageId
|
|
86
|
+
1. uri
|
|
87
|
+
1. data
|
|
88
|
+
1. throwIfAbortedFn
|
|
89
|
+
1. Create a second public static method, cleanStoredManifest. This method is
|
|
90
|
+
meant to be called by the service worker in the instance of the fetch operation
|
|
91
|
+
being aborted, and will simply clear the manifest away. It will also clear any
|
|
92
|
+
segments that have been stored already. This also means we will no longer need
|
|
93
|
+
the segmentsFromStore_ array, which we had previously been using to un-store
|
|
94
|
+
after canceled or failed downloads. It should have the following parameters:
|
|
95
|
+
1. manifestStorageId
|
|
96
|
+
1. When filling out shaka.extern.StoredContent entries for the list() method,
|
|
97
|
+
the storage system should be sure to set the offlineUri field to null if the
|
|
98
|
+
manifest is still “isIncomplete”, to mark that the asset has not yet finished
|
|
99
|
+
downloading. This will help developers detect that an asset is mid-download on
|
|
100
|
+
page load, so that they can set up progress indicators if they so wish.
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
### Service Worker Design
|
|
104
|
+
|
|
105
|
+
1. This code should go in, or at least be loaded in, the wrapper code. This will
|
|
106
|
+
let us access Shaka Player methods inside the service worker, without having to
|
|
107
|
+
coordinate how to load a compiled Shaka Player bundle from a service worker;
|
|
108
|
+
the user can simply load a Shaka Player bundle as a service worker.
|
|
109
|
+
1. When the background fetch message is called (see [the documentation]), the
|
|
110
|
+
“id” field should be set to the storage id of the manifest, with an added prefix
|
|
111
|
+
of “Shaka-”. The API does not provide any field for custom data, but this value
|
|
112
|
+
still needs to be provided to the service worker somehow. Luckily, this is the
|
|
113
|
+
only extra data the service worker needs, so it can just be the id of the fetch
|
|
114
|
+
operation.
|
|
115
|
+
1. When handling background fetch-related events, we can simply ignore any
|
|
116
|
+
event that does not start with the prefix. This will help prevent any
|
|
117
|
+
contamination with other service worker code from the developer.
|
|
118
|
+
1. As each segment is downloaded, the assignStreamToManifest method should be
|
|
119
|
+
called to store that data in the manifest.
|
|
120
|
+
1. If the download is canceled, call the cleanStoredManifest method, so that the
|
|
121
|
+
player doesn’t pollute indexedDb with unused segment data.
|
|
122
|
+
1. As a service worker is essentially just a collection of event listeners, one
|
|
123
|
+
can theoretically listen to the same event multiple times. This is relevant
|
|
124
|
+
because [a given scope] can only have a single service worker, so our service
|
|
125
|
+
worker code will have to be something that other people can load into their
|
|
126
|
+
existing service workers, if they have any.
|
|
127
|
+
1. Our system should use the message event to pass a specific identifying
|
|
128
|
+
message to the service worker, and the service worker will be expected to
|
|
129
|
+
respond with a specific response message. This way, we won’t mistake an
|
|
130
|
+
unrelated service worker for our own.
|
|
131
|
+
1. This message can also be used to make sure the versions are the same.
|
|
132
|
+
|
|
133
|
+
[the documentation]: https://developers.google.com/web/updates/2018/12/background-fetch#starting_a_background_fetch
|
|
134
|
+
[a given scope]: https://developers.google.com/web/fundamentals/primers/service-workers#register_a_service_worker
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Blob URL
|
|
2
|
+
|
|
3
|
+
In case you need shaka-player to load a blob url mpd:
|
|
4
|
+
|
|
5
|
+
`player.load(computedMpdBlobURL, startTime, 'application/dash+xml');`
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
In case you need shaka-player to load a blob url m3u8 :
|
|
9
|
+
|
|
10
|
+
`player.load(computedMpdBlobURL, startTime, 'application/x-mpegurl');`
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Note: relative URIs in the manifest are broken because the original manifest URI is lost. This can be worked around with either absolute URIs or the use of BaseURL element in DASH.
|
|
14
|
+
|
|
15
|
+
Note: this tutorial only applies to v3.3 or higher
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
{ "offline": { "title": "Offline Storage and Playback" } },
|
|
19
19
|
{ "fairplay": { "title": "FairPlay support" } },
|
|
20
20
|
{ "application-level-redirects": { "title": "Application-Level Redirects" } },
|
|
21
|
+
{ "blob-url": { "title": "Blob URL" } },
|
|
21
22
|
{ "faq": { "title": "Frequently Asked Questions" } },
|
|
22
23
|
{ "upgrade": {
|
|
23
24
|
"title": "Upgrade Guide",
|
|
@@ -67,6 +67,10 @@ The following elements can be added to the UI bar using this configuration value
|
|
|
67
67
|
supports AirPlay.
|
|
68
68
|
* cast: adds a button that opens a Chromecast dialog. The button is visible only if there is
|
|
69
69
|
at least one Chromecast device on the same network available for casting.
|
|
70
|
+
* quality: adds a button that controls enabling/disabling of abr and video resolution selection.
|
|
71
|
+
* language: adds a button that controls audio language selection.
|
|
72
|
+
* playback_rate: adds a button that controls the playback rate selection.
|
|
73
|
+
* captions: adds a button that controls the current text track selection (including turning it off).
|
|
70
74
|
<!-- TODO: If we add more buttons that can be put in the order this way, list them here. -->
|
|
71
75
|
|
|
72
76
|
Similarly, the 'overflowMenuButtons' configuration option can be used to control
|
|
@@ -84,6 +88,7 @@ The following buttons can be added to the overflow menu:
|
|
|
84
88
|
* playback_rate: adds a button that controls the playback rate selection.
|
|
85
89
|
* airplay: adds a button that opens a AirPlay dialog. The button is visible only if the browser
|
|
86
90
|
supports AirPlay.
|
|
91
|
+
* Statistics: adds a button that displays statistics of the video.
|
|
87
92
|
<!-- TODO: If we add more buttons that can be put in the order this way, list them here. -->
|
|
88
93
|
|
|
89
94
|
Example:
|
|
@@ -98,6 +103,51 @@ ui.configure(config);
|
|
|
98
103
|
An important note: the 'overflow_menu' button needs to be part of the 'controlPanelElements'
|
|
99
104
|
layout for the overflow menu to be available to the user.
|
|
100
105
|
|
|
106
|
+
#### Adding tooltips to control panel buttons
|
|
107
|
+
|
|
108
|
+
Tooltips can be enabled to display the function of every button in the control panel. Where applicable, they will also contain the current selection in parenthesis.
|
|
109
|
+
|
|
110
|
+
Example:
|
|
111
|
+
```js
|
|
112
|
+
const config = {
|
|
113
|
+
'enableTooltips' : true
|
|
114
|
+
}
|
|
115
|
+
ui.configure(config);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### Replacing the default context menu
|
|
119
|
+
|
|
120
|
+
A custom context menu can be added through the `customContextMenu` boolean. Additionally, the `contextMenuElements` option can be used to add elements to it.
|
|
121
|
+
The following buttons can be added to the context menu:
|
|
122
|
+
* Statistics: adds a button that displays statistics of the video.
|
|
123
|
+
* loop: adds a button that controls if the currently selected video is played in a loop.
|
|
124
|
+
* picture_in_picture: adds a button that enables/disables picture-in-picture mode on browsers
|
|
125
|
+
that support it. Button is invisible on other browsers.
|
|
126
|
+
|
|
127
|
+
Example:
|
|
128
|
+
```js
|
|
129
|
+
const config = {
|
|
130
|
+
'customContextMenu' : true,
|
|
131
|
+
'contextMenuElements' : ['statistics'],
|
|
132
|
+
}
|
|
133
|
+
ui.configure(config);
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
#### Configuring Statistics
|
|
137
|
+
The list of statistics that are displayed when toggling the statistics button can be customized by specifying a `statisticsList` on the configuration. With the exception of `switchHistory` and `stateHistory`, all of the statistics from the {@link shaka.extern.Stats `Stats`} extern can be displayed.
|
|
138
|
+
|
|
139
|
+
Example:
|
|
140
|
+
```js
|
|
141
|
+
// Add a context menu with the 'statistics' button that displays a container with
|
|
142
|
+
// the current 'width', 'height', 'playTime', and 'bufferingTime' values.
|
|
143
|
+
const config = {
|
|
144
|
+
'customContextMenu' : true,
|
|
145
|
+
'contextMenuElements' : ['statistics'],
|
|
146
|
+
'statisticsList' : ['width', 'height', 'playTime', 'bufferingTime'],
|
|
147
|
+
}
|
|
148
|
+
ui.configure(config);
|
|
149
|
+
```
|
|
150
|
+
|
|
101
151
|
The presence of the seek bar and the big play button in the center of the video element can be
|
|
102
152
|
customized with `addSeekBar` and `addBigPlayButton` booleans in the config.
|
|
103
153
|
|
|
@@ -130,6 +180,22 @@ const config = {
|
|
|
130
180
|
ui.configure(config);
|
|
131
181
|
```
|
|
132
182
|
|
|
183
|
+
#### Configuring playback, fast forward and rewind rates
|
|
184
|
+
The rate in which the player can play, fast forward and rewind content can be configured using the `playbackRates`, `fastForwardRates` and `rewindRates` options.
|
|
185
|
+
|
|
186
|
+
* `playbackRates`: List of rates available in the `playback_rate` menu.
|
|
187
|
+
* `fastForwardRates`: List of rates available to cycle through every time the `fast_forward` button is clicked.
|
|
188
|
+
* `rewindRates`: List of rates available to cycle through every time the `rewind` button is clicked.
|
|
189
|
+
|
|
190
|
+
```js
|
|
191
|
+
const config = {
|
|
192
|
+
'controlPanelElements': ['playback_rate', 'fast_forward', 'rewind'],
|
|
193
|
+
'playbackRates': [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
|
|
194
|
+
'fastForwardRates': [2, 4, 8, 1],
|
|
195
|
+
'rewindRates': [-1, -2, -4, -8],
|
|
196
|
+
}
|
|
197
|
+
ui.configure(config);
|
|
198
|
+
```
|
|
133
199
|
|
|
134
200
|
#### Creating custom elements and adding them to the UI
|
|
135
201
|
It's possible to add custom application-specific buttons to the UI.
|
package/docs/tutorials/ui.md
CHANGED
|
@@ -30,7 +30,7 @@ Set up controls with HTML data attributes:
|
|
|
30
30
|
The data-shaka-player-cast-receiver-id tag allows you to provide a Cast Application ID that
|
|
31
31
|
the cast button will cast to; the value provided here is the sample cast receiver. -->
|
|
32
32
|
<div data-shaka-player-container style="max-width:40em"
|
|
33
|
-
data-shaka-player-cast-receiver-id="
|
|
33
|
+
data-shaka-player-cast-receiver-id="BBED8D28">
|
|
34
34
|
<!-- The data-shaka-player tag will make the UI library use this video element.
|
|
35
35
|
If no video is provided, the UI will automatically make one inside the container div. -->
|
|
36
36
|
<video autoplay data-shaka-player id="video" style="width:100%;height:100%"></video>
|
|
@@ -111,7 +111,7 @@ set up a listener for the 'caststatuschanged' events.
|
|
|
111
111
|
<!-- Add a data-shaka-player-cast-receiver-id tag to provide a Cast Application ID that
|
|
112
112
|
the cast button will cast to; the value provided here is the sample cast receiver. -->
|
|
113
113
|
<div data-shaka-player-container style="max-width:40em"
|
|
114
|
-
data-shaka-player-cast-receiver-id="
|
|
114
|
+
data-shaka-player-cast-receiver-id="BBED8D28">
|
|
115
115
|
</div>
|
|
116
116
|
```
|
|
117
117
|
|
|
@@ -137,7 +137,7 @@ or a `<source>` tag inside it to enable auto loading of the specified content.
|
|
|
137
137
|
|
|
138
138
|
```html
|
|
139
139
|
<div data-shaka-player-container style="max-width:40em"
|
|
140
|
-
data-shaka-player-cast-receiver-id="
|
|
140
|
+
data-shaka-player-cast-receiver-id="BBED8D28">
|
|
141
141
|
<!-- The manifest url in the src attribute will be automatically loaded -->
|
|
142
142
|
<video autoplay data-shaka-player id="video" style="width:100%;height:100%"
|
|
143
143
|
src="https://storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd"></video>
|
|
@@ -148,7 +148,7 @@ or
|
|
|
148
148
|
|
|
149
149
|
```html
|
|
150
150
|
<div data-shaka-player-container style="max-width:40em"
|
|
151
|
-
data-shaka-player-cast-receiver-id="
|
|
151
|
+
data-shaka-player-cast-receiver-id="BBED8D28">
|
|
152
152
|
<video autoplay data-shaka-player id="video" style="width:100%;height:100%">
|
|
153
153
|
<!-- The manifest url in the src attribute will be auto loaded -->
|
|
154
154
|
<source src="https://storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd"/>
|
|
@@ -161,7 +161,7 @@ call to the first one fails.
|
|
|
161
161
|
|
|
162
162
|
```html
|
|
163
163
|
<div data-shaka-player-container style="max-width:40em"
|
|
164
|
-
data-shaka-player-cast-receiver-id="
|
|
164
|
+
data-shaka-player-cast-receiver-id="BBED8D28">
|
|
165
165
|
<video autoplay data-shaka-player id="video" style="width:100%;height:100%">
|
|
166
166
|
<!-- Try this first -->
|
|
167
167
|
<source src="https://storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd"/>
|
package/externs/cmcd.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview Externs for CMCD data.
|
|
9
|
+
* @see https://github.com/google/shaka-player/issues/3619
|
|
10
|
+
* @see https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf
|
|
11
|
+
*
|
|
12
|
+
* @externs
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {{
|
|
17
|
+
* br: (number|undefined),
|
|
18
|
+
* d: (number|undefined),
|
|
19
|
+
* ot: (string|undefined),
|
|
20
|
+
* tb: (number|undefined),
|
|
21
|
+
* bl: (number|undefined),
|
|
22
|
+
* dl: (number|undefined),
|
|
23
|
+
* mtp: (number|undefined),
|
|
24
|
+
* nor: (string|undefined),
|
|
25
|
+
* nrr: (string|undefined),
|
|
26
|
+
* su: (boolean|undefined),
|
|
27
|
+
* cid: (string|undefined),
|
|
28
|
+
* pr: (number|undefined),
|
|
29
|
+
* sf: (string|undefined),
|
|
30
|
+
* sid: (string|undefined),
|
|
31
|
+
* st: (string|undefined),
|
|
32
|
+
* v: (number|undefined),
|
|
33
|
+
* bs: (boolean|undefined),
|
|
34
|
+
* rtp: (number|undefined)
|
|
35
|
+
* }}
|
|
36
|
+
*
|
|
37
|
+
* @description
|
|
38
|
+
* Client Media Common Data (CMCD) data.
|
|
39
|
+
*
|
|
40
|
+
* @property {number} br
|
|
41
|
+
* The encoded bitrate of the audio or video object being requested. This may
|
|
42
|
+
* not be known precisely by the player; however, it MAY be estimated based
|
|
43
|
+
* upon playlist/manifest declarations. If the playlist declares both peak and
|
|
44
|
+
* average bitrate values, the peak value should be transmitted.
|
|
45
|
+
*
|
|
46
|
+
* @property {number} d
|
|
47
|
+
* The playback duration in milliseconds of the object being requested. If a
|
|
48
|
+
* partial segment is being requested, then this value MUST indicate the
|
|
49
|
+
* playback duration of that part and not that of its parent segment. This
|
|
50
|
+
* value can be an approximation of the estimated duration if the explicit
|
|
51
|
+
* value is not known.
|
|
52
|
+
*
|
|
53
|
+
* @property {string} ot
|
|
54
|
+
* The media type of the current object being requested:
|
|
55
|
+
* - `m` = text file, such as a manifest or playlist
|
|
56
|
+
* - `a` = audio only
|
|
57
|
+
* - `v` = video only
|
|
58
|
+
* - `av` = muxed audio and video
|
|
59
|
+
* - `i` = init segment
|
|
60
|
+
* - `c` = caption or subtitle
|
|
61
|
+
* - `tt` = ISOBMFF timed text track
|
|
62
|
+
* - `k` = cryptographic key, license or certificate.
|
|
63
|
+
* - `o` = other
|
|
64
|
+
*
|
|
65
|
+
* If the object type being requested is unknown, then this key MUST NOT be
|
|
66
|
+
* used.
|
|
67
|
+
*
|
|
68
|
+
* @property {number} tb
|
|
69
|
+
* The highest bitrate rendition in the manifest or playlist that the client
|
|
70
|
+
* is allowed to play, given current codec, licensing and sizing constraints.
|
|
71
|
+
*
|
|
72
|
+
* @property {number} bl
|
|
73
|
+
* The buffer length associated with the media object being requested. This
|
|
74
|
+
* value MUST be rounded to the nearest 100 ms. This key SHOULD only be sent
|
|
75
|
+
* with an object type of ‘a’, ‘v’ or ‘av’.
|
|
76
|
+
*
|
|
77
|
+
* @property {number} dl
|
|
78
|
+
* Deadline from the request time until the first sample of this
|
|
79
|
+
* Segment/Object needs to be available in order to not create a buffer
|
|
80
|
+
* underrun or any other playback problems. This value MUST be rounded to the
|
|
81
|
+
* nearest 100ms. For a playback rate of 1, this may be equivalent to the
|
|
82
|
+
* player’s remaining buffer length.
|
|
83
|
+
*
|
|
84
|
+
* @property {number} mtp
|
|
85
|
+
* The throughput between client and server, as measured by the client and
|
|
86
|
+
* MUST be rounded to the nearest 100 kbps. This value, however derived,
|
|
87
|
+
* SHOULD be the value that the client is using to make its next Adaptive
|
|
88
|
+
* Bitrate switching decision. If the client is connected to multiple
|
|
89
|
+
* servers concurrently, it must take care to report only the throughput
|
|
90
|
+
* measured against the receiving server. If the client has multiple
|
|
91
|
+
* concurrent connections to the server, then the intent is that this value
|
|
92
|
+
* communicates the aggregate throughput the client sees across all those
|
|
93
|
+
* connections.
|
|
94
|
+
*
|
|
95
|
+
* @property {string} nor
|
|
96
|
+
* Relative path of the next object to be requested. This can be used to
|
|
97
|
+
* trigger pre-fetching by the CDN. This MUST be a path relative to the
|
|
98
|
+
* current request. This string MUST be URLEncoded. The client SHOULD NOT
|
|
99
|
+
* depend upon any pre-fetch action being taken - it is merely a request for
|
|
100
|
+
* such a pre-fetch to take place.
|
|
101
|
+
*
|
|
102
|
+
* @property {string} nrr
|
|
103
|
+
* If the next request will be a partial object request, then this string
|
|
104
|
+
* denotes the byte range to be requested. If the ‘nor’ field is not set, then
|
|
105
|
+
* the object is assumed to match the object currently being requested. The
|
|
106
|
+
* client SHOULD NOT depend upon any pre-fetch action being taken – it is
|
|
107
|
+
* merely a request for such a pre-fetch to take place. Formatting is similar
|
|
108
|
+
* to the HTTP Range header, except that the unit MUST be ‘byte’, the ‘Range:’
|
|
109
|
+
* prefix is NOT required and specifying multiple ranges is NOT allowed. Valid
|
|
110
|
+
* combinations are:
|
|
111
|
+
*
|
|
112
|
+
* - `"\<range-start\>-"`
|
|
113
|
+
* - `"\<range-start\>-\<range-end\>"`
|
|
114
|
+
* - `"-\<suffix-length\>"`
|
|
115
|
+
*
|
|
116
|
+
* @property {boolean} su
|
|
117
|
+
* Key is included without a value if the object is needed urgently due to
|
|
118
|
+
* startup, seeking or recovery after a buffer-empty event. The media SHOULD
|
|
119
|
+
* not be rendering when this request is made. This key MUST not be sent if it
|
|
120
|
+
* is FALSE.
|
|
121
|
+
*
|
|
122
|
+
* @property {string} cid
|
|
123
|
+
* A unique string identifying the current content. Maximum length is 64
|
|
124
|
+
* characters. This value is consistent across multiple different sessions and
|
|
125
|
+
* devices and is defined and updated at the discretion of the service
|
|
126
|
+
* provider.
|
|
127
|
+
*
|
|
128
|
+
* @property {number} pr
|
|
129
|
+
* The playback rate. `1` if real-time, `2` if double speed, `0` if not
|
|
130
|
+
* playing. SHOULD only be sent if not equal to `1`.
|
|
131
|
+
*
|
|
132
|
+
* @property {string} sf
|
|
133
|
+
* The streaming format that defines the current request.
|
|
134
|
+
*
|
|
135
|
+
* - `d` = MPEG DASH
|
|
136
|
+
* - `h` = HTTP Live Streaming (HLS)
|
|
137
|
+
* - `s` = Smooth Streaming
|
|
138
|
+
* - `o` = other
|
|
139
|
+
*
|
|
140
|
+
* If the streaming format being requested is unknown, then this key MUST NOT
|
|
141
|
+
* be used.
|
|
142
|
+
*
|
|
143
|
+
* @property {string} sid
|
|
144
|
+
* A GUID identifying the current playback session. A playback session
|
|
145
|
+
* typically ties together segments belonging to a single media asset. Maximum
|
|
146
|
+
* length is 64 characters. It is RECOMMENDED to conform to the UUID
|
|
147
|
+
* specification.
|
|
148
|
+
*
|
|
149
|
+
* @property {string} st
|
|
150
|
+
* Stream type
|
|
151
|
+
* - `v` = all segments are available – e.g., VOD
|
|
152
|
+
* - `l` = segments become available over time – e.g., LIVE
|
|
153
|
+
*
|
|
154
|
+
* @property {number} v
|
|
155
|
+
* The version of this specification used for interpreting the defined key
|
|
156
|
+
* names and values. If this key is omitted, the client and server MUST
|
|
157
|
+
* interpret the values as being defined by version 1. Client SHOULD omit this
|
|
158
|
+
* field if the version is 1.
|
|
159
|
+
*
|
|
160
|
+
* @property {boolean} bs
|
|
161
|
+
* Buffer starvation key is included without a value if the buffer was starved
|
|
162
|
+
* at some point between the prior request and this object request, resulting
|
|
163
|
+
* in the player being in a rebuffering state and the video or audio playback
|
|
164
|
+
* being stalled. This key MUST NOT be sent if the buffer was not starved
|
|
165
|
+
* since the prior request.
|
|
166
|
+
*
|
|
167
|
+
* If the object type `ot` key is sent along with this key, then the `bs` key
|
|
168
|
+
* refers to the buffer associated with the particular object type. If no
|
|
169
|
+
* object type is communicated, then the buffer state applies to the current
|
|
170
|
+
* session.
|
|
171
|
+
*
|
|
172
|
+
* @property {number} rtp
|
|
173
|
+
* Requested maximum throughput
|
|
174
|
+
*
|
|
175
|
+
* The requested maximum throughput that the client considers sufficient for
|
|
176
|
+
* delivery of the asset. Values MUST be rounded to the nearest 100kbps. For
|
|
177
|
+
* example, a client would indicate that the current segment, encoded at
|
|
178
|
+
* 2Mbps, is to be delivered at no more than 10Mbps, by using rtp=10000.
|
|
179
|
+
*
|
|
180
|
+
* Note: This can benefit clients by preventing buffer saturation through
|
|
181
|
+
* over-delivery and can also deliver a community benefit through fair-share
|
|
182
|
+
* delivery. The concept is that each client receives the throughput necessary
|
|
183
|
+
* for great performance, but no more. The CDN may not support the rtp
|
|
184
|
+
* feature.
|
|
185
|
+
*/
|
|
186
|
+
var CmcdData;
|
package/externs/ima.js
CHANGED
package/externs/shaka/ads.js
CHANGED
|
@@ -238,6 +238,7 @@ shaka.extern.CreateSegmentIndexFunction;
|
|
|
238
238
|
* id: number,
|
|
239
239
|
* originalId: ?string,
|
|
240
240
|
* createSegmentIndex: shaka.extern.CreateSegmentIndexFunction,
|
|
241
|
+
* closeSegmentIndex: (function()|undefined),
|
|
241
242
|
* segmentIndex: shaka.media.SegmentIndex,
|
|
242
243
|
* mimeType: string,
|
|
243
244
|
* codecs: string,
|
|
@@ -263,7 +264,10 @@ shaka.extern.CreateSegmentIndexFunction;
|
|
|
263
264
|
* audioSamplingRate: ?number,
|
|
264
265
|
* spatialAudio: boolean,
|
|
265
266
|
* closedCaptions: Map.<string, string>,
|
|
266
|
-
* tilesLayout: (string|undefined)
|
|
267
|
+
* tilesLayout: (string|undefined),
|
|
268
|
+
* matchedStreams:
|
|
269
|
+
* (!Array.<shaka.extern.Stream>|!Array.<shaka.extern.StreamDB>|
|
|
270
|
+
* undefined)
|
|
267
271
|
* }}
|
|
268
272
|
*
|
|
269
273
|
* @description
|
|
@@ -280,6 +284,9 @@ shaka.extern.CreateSegmentIndexFunction;
|
|
|
280
284
|
* @property {shaka.extern.CreateSegmentIndexFunction} createSegmentIndex
|
|
281
285
|
* <i>Required.</i> <br>
|
|
282
286
|
* Creates the Stream's segmentIndex (asynchronously).
|
|
287
|
+
* @property {(function()|undefined)} closeSegmentIndex
|
|
288
|
+
* <i>Optional.</i> <br>
|
|
289
|
+
* Closes the Stream's segmentIndex.
|
|
283
290
|
* @property {shaka.media.SegmentIndex} segmentIndex
|
|
284
291
|
* <i>Required.</i> <br>
|
|
285
292
|
* May be null until createSegmentIndex() is complete.
|
|
@@ -370,6 +377,10 @@ shaka.extern.CreateSegmentIndexFunction;
|
|
|
370
377
|
* The value is a grid-item-dimension consisting of two positive decimal
|
|
371
378
|
* integers in the format: column-x-row ('4x3'). It describes the arrangement
|
|
372
379
|
* of Images in a Grid. The minimum valid LAYOUT is '1x1'.
|
|
380
|
+
* @property {(!Array.<shaka.extern.Stream>|!Array.<shaka.extern.StreamDB>|
|
|
381
|
+
* undefined)} matchedStreams
|
|
382
|
+
* The streams in all periods which match the stream. Used for Dash.
|
|
383
|
+
*
|
|
373
384
|
* @exportDoc
|
|
374
385
|
*/
|
|
375
386
|
shaka.extern.Stream;
|
|
@@ -100,6 +100,10 @@ shaka.extern.ManifestParser = class {
|
|
|
100
100
|
/**
|
|
101
101
|
* @typedef {{
|
|
102
102
|
* networkingEngine: !shaka.net.NetworkingEngine,
|
|
103
|
+
* modifyManifestRequest: function(!shaka.extern.Request,
|
|
104
|
+
* shaka.util.CmcdManager.ManifestInfo),
|
|
105
|
+
* modifySegmentRequest: function(!shaka.extern.Request,
|
|
106
|
+
* shaka.util.CmcdManager.SegmentInfo),
|
|
103
107
|
* filter: function(shaka.extern.Manifest):!Promise,
|
|
104
108
|
* makeTextStreamsForClosedCaptions: function(shaka.extern.Manifest),
|
|
105
109
|
* onTimelineRegionAdded: function(shaka.extern.TimelineRegionInfo),
|
|
@@ -118,6 +122,12 @@ shaka.extern.ManifestParser = class {
|
|
|
118
122
|
*
|
|
119
123
|
* @property {!shaka.net.NetworkingEngine} networkingEngine
|
|
120
124
|
* The networking engine to use for network requests.
|
|
125
|
+
* @property {function(!shaka.extern.Request,
|
|
126
|
+
* shaka.util.CmcdManager.ManifestInfo)} modifyManifestRequest
|
|
127
|
+
* Modify a manifest request
|
|
128
|
+
* @property {function(!shaka.extern.Request,
|
|
129
|
+
* shaka.util.CmcdManager.SegmentInfo)} modifySegmentRequest
|
|
130
|
+
* Modify a segment request
|
|
121
131
|
* @property {function(shaka.extern.Manifest):!Promise} filter
|
|
122
132
|
* Should be called when new variants or text streams are added to the
|
|
123
133
|
* Manifest. Note that this operation is asynchronous.
|
|
@@ -150,4 +160,3 @@ shaka.extern.ManifestParser.PlayerInterface;
|
|
|
150
160
|
* @exportDoc
|
|
151
161
|
*/
|
|
152
162
|
shaka.extern.ManifestParser.Factory;
|
|
153
|
-
|