shaka-player 3.1.4 → 3.3.0

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.
Files changed (214) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +1 -1
  3. package/.github/ISSUE_TEMPLATE/question.md +1 -1
  4. package/AUTHORS +6 -5
  5. package/CHANGELOG.md +363 -0
  6. package/CONTRIBUTORS +4 -2
  7. package/README.md +4 -4
  8. package/build/types/core +3 -0
  9. package/build/types/offline +1 -0
  10. package/build/types/polyfill +2 -0
  11. package/build/types/ui +2 -0
  12. package/demo/common/asset.js +9 -7
  13. package/demo/common/assets.js +28 -1
  14. package/demo/common/message_ids.js +15 -2
  15. package/demo/config.js +35 -2
  16. package/demo/index.html +1 -1
  17. package/demo/locales/en.json +14 -1
  18. package/demo/locales/source.json +56 -4
  19. package/demo/main.js +2 -1
  20. package/dist/controls.css +26 -2
  21. package/dist/controls.css.map +1 -1
  22. package/dist/demo.compiled.debug.js +24 -21
  23. package/dist/demo.compiled.debug.map +3 -3
  24. package/dist/demo.compiled.js +24 -21
  25. package/dist/demo.compiled.map +3 -3
  26. package/dist/deps.js +33 -25
  27. package/dist/locales.js +31 -29
  28. package/dist/receiver.compiled.debug.js +14 -12
  29. package/dist/receiver.compiled.debug.map +3 -3
  30. package/dist/receiver.compiled.js +14 -12
  31. package/dist/receiver.compiled.map +3 -3
  32. package/dist/shaka-player.compiled.d.ts +258 -20
  33. package/dist/shaka-player.compiled.debug.d.ts +258 -20
  34. package/dist/shaka-player.compiled.debug.externs.js +1005 -695
  35. package/dist/shaka-player.compiled.debug.js +720 -640
  36. package/dist/shaka-player.compiled.debug.map +4 -4
  37. package/dist/shaka-player.compiled.externs.js +1005 -695
  38. package/dist/shaka-player.compiled.js +850 -817
  39. package/dist/shaka-player.compiled.map +4 -4
  40. package/dist/shaka-player.ui.d.ts +274 -21
  41. package/dist/shaka-player.ui.debug.d.ts +274 -21
  42. package/dist/shaka-player.ui.debug.externs.js +766 -429
  43. package/dist/shaka-player.ui.debug.js +863 -765
  44. package/dist/shaka-player.ui.debug.map +4 -4
  45. package/dist/shaka-player.ui.externs.js +766 -429
  46. package/dist/shaka-player.ui.js +1042 -996
  47. package/dist/shaka-player.ui.map +4 -4
  48. package/docs/design/bg-fetch-after.gv +29 -0
  49. package/docs/design/bg-fetch-after.gv.png +0 -0
  50. package/docs/design/bg-fetch-before.gv +18 -0
  51. package/docs/design/bg-fetch-before.gv.png +0 -0
  52. package/docs/design/bg-fetch.md +134 -0
  53. package/docs/tutorials/blob-url.md +15 -0
  54. package/docs/tutorials/index.json +1 -0
  55. package/docs/tutorials/ui-customization.md +66 -0
  56. package/docs/tutorials/ui.md +5 -5
  57. package/externs/aria.js +6 -0
  58. package/externs/ima.js +3 -0
  59. package/externs/shaka/ads.js +29 -1
  60. package/externs/shaka/manifest.js +18 -2
  61. package/externs/shaka/manifest_parser.js +10 -1
  62. package/externs/shaka/net.js +20 -4
  63. package/externs/shaka/offline.js +36 -2
  64. package/externs/shaka/player.js +182 -13
  65. package/externs/shaka/text.js +24 -10
  66. package/externs/texttrack.js +3 -0
  67. package/externs/webcrypto.js +18 -0
  68. package/lib/abr/ewma.js +14 -0
  69. package/lib/abr/ewma_bandwidth_estimator.js +16 -2
  70. package/lib/abr/simple_abr_manager.js +6 -0
  71. package/lib/ads/ad_manager.js +16 -15
  72. package/lib/ads/client_side_ad.js +8 -0
  73. package/lib/ads/client_side_ad_manager.js +14 -6
  74. package/lib/ads/server_side_ad.js +7 -0
  75. package/lib/ads/server_side_ad_manager.js +19 -2
  76. package/lib/cast/cast_proxy.js +8 -0
  77. package/lib/cast/cast_utils.js +7 -1
  78. package/lib/cea/cea608_data_channel.js +56 -56
  79. package/lib/cea/cea608_memory.js +33 -33
  80. package/lib/cea/cea708_service.js +43 -43
  81. package/lib/cea/cea708_window.js +38 -38
  82. package/lib/cea/cea_decoder.js +13 -14
  83. package/lib/cea/cea_utils.js +23 -23
  84. package/lib/cea/dtvcc_packet_builder.js +7 -7
  85. package/lib/cea/i_caption_decoder.js +2 -3
  86. package/lib/cea/i_cea_parser.js +2 -2
  87. package/lib/cea/mp4_cea_parser.js +6 -6
  88. package/lib/dash/dash_parser.js +53 -14
  89. package/lib/dash/segment_base.js +25 -1
  90. package/lib/dash/segment_list.js +18 -9
  91. package/lib/dash/segment_template.js +23 -10
  92. package/lib/hls/hls_parser.js +210 -30
  93. package/lib/media/closed_caption_parser.js +1 -2
  94. package/lib/media/drm_engine.js +162 -192
  95. package/lib/media/quality_observer.js +291 -0
  96. package/lib/media/segment_index.js +9 -1
  97. package/lib/media/segment_reference.js +37 -5
  98. package/lib/media/streaming_engine.js +48 -10
  99. package/lib/net/http_fetch_plugin.js +31 -11
  100. package/lib/net/http_plugin_utils.js +1 -0
  101. package/lib/net/http_xhr_plugin.js +40 -14
  102. package/lib/net/networking_engine.js +82 -18
  103. package/lib/offline/download_info.js +68 -0
  104. package/lib/offline/download_manager.js +14 -7
  105. package/lib/offline/indexeddb/base_storage_cell.js +35 -0
  106. package/lib/offline/indexeddb/storage_mechanism.js +1 -1
  107. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  108. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  109. package/lib/offline/indexeddb/v5_storage_cell.js +5 -0
  110. package/lib/offline/manifest_converter.js +3 -1
  111. package/lib/offline/storage.js +404 -297
  112. package/lib/offline/stored_content_utils.js +2 -0
  113. package/lib/player.js +622 -153
  114. package/lib/polyfill/aria.js +82 -0
  115. package/lib/polyfill/random_uuid.js +52 -0
  116. package/lib/routing/walker.js +2 -3
  117. package/lib/text/cue.js +12 -0
  118. package/lib/text/srt_text_parser.js +4 -4
  119. package/lib/text/text_engine.js +2 -2
  120. package/lib/text/ttml_text_parser.js +25 -2
  121. package/lib/text/ui_text_displayer.js +2 -2
  122. package/lib/text/vtt_text_parser.js +2 -2
  123. package/lib/text/web_vtt_generator.js +55 -12
  124. package/lib/util/cmcd_manager.js +826 -0
  125. package/lib/util/error.js +12 -0
  126. package/lib/util/language_utils.js +12 -0
  127. package/lib/util/manifest_parser_utils.js +1 -0
  128. package/lib/util/mp4_box_parsers.js +20 -20
  129. package/lib/util/multi_map.js +8 -0
  130. package/lib/util/mutex.js +52 -0
  131. package/lib/util/periods.js +98 -64
  132. package/lib/util/player_configuration.js +31 -1
  133. package/lib/util/stream_utils.js +140 -85
  134. package/lib/util/xml_utils.js +31 -12
  135. package/package.json +1 -1
  136. package/roadmap.md +24 -22
  137. package/shaka-player.uncompiled.js +4 -0
  138. package/test/cast/cast_utils_unit.js +1 -0
  139. package/test/cea/cea608_memory_unit.js +1 -1
  140. package/test/cea/cea708_service_unit.js +8 -8
  141. package/test/cea/cea708_window_unit.js +6 -6
  142. package/test/cea/cea_decoder_unit.js +1 -1
  143. package/test/cea/dtvcc_packet_builder_unit.js +2 -2
  144. package/test/dash/dash_parser_content_protection_unit.js +2 -0
  145. package/test/dash/dash_parser_live_unit.js +101 -1
  146. package/test/dash/dash_parser_manifest_unit.js +78 -2
  147. package/test/dash/dash_parser_segment_base_unit.js +2 -0
  148. package/test/dash/dash_parser_segment_list_unit.js +2 -1
  149. package/test/dash/dash_parser_segment_template_unit.js +2 -1
  150. package/test/hls/hls_live_unit.js +2 -0
  151. package/test/hls/hls_parser_unit.js +252 -0
  152. package/test/media/drm_engine_integration.js +86 -12
  153. package/test/media/drm_engine_unit.js +310 -450
  154. package/test/media/quality_observer_unit.js +139 -0
  155. package/test/media/segment_reference_unit.js +16 -1
  156. package/test/media/streaming_engine_integration.js +2 -1
  157. package/test/media/streaming_engine_unit.js +2 -0
  158. package/test/net/http_plugin_unit.js +20 -15
  159. package/test/offline/manifest_convert_unit.js +2 -0
  160. package/test/offline/storage_integration.js +117 -23
  161. package/test/player_integration.js +151 -0
  162. package/test/player_src_equals_integration.js +52 -0
  163. package/test/player_unit.js +11 -33
  164. package/test/test/assets/chapters.srt +11 -0
  165. package/test/test/assets/chapters.vtt +10 -0
  166. package/test/test/util/cea_utils.js +12 -12
  167. package/test/test/util/dash_parser_util.js +4 -0
  168. package/test/test/util/fake_ad.js +7 -0
  169. package/test/test/util/fake_ad_manager.js +7 -0
  170. package/test/test/util/fake_drm_engine.js +9 -2
  171. package/test/test/util/manifest_generator.js +5 -2
  172. package/test/test/util/manifest_parser_util.js +3 -1
  173. package/test/test/util/test_scheme.js +14 -1
  174. package/test/text/ttml_text_parser_unit.js +47 -0
  175. package/test/text/web_vtt_generator_unit.js +81 -7
  176. package/test/ui/ui_unit.js +250 -0
  177. package/test/util/cmcd_manager_unit.js +277 -0
  178. package/test/util/stream_utils_unit.js +118 -10
  179. package/ui/airplay_button.js +2 -1
  180. package/ui/audio_language_selection.js +9 -5
  181. package/ui/cast_button.js +5 -6
  182. package/ui/constants.js +0 -3
  183. package/ui/context_menu.js +109 -0
  184. package/ui/controls.js +41 -7
  185. package/ui/controls.less +1 -0
  186. package/ui/enums.js +4 -0
  187. package/ui/externs/ui.js +28 -1
  188. package/ui/fast_forward_button.js +16 -8
  189. package/ui/fullscreen_button.js +2 -3
  190. package/ui/language_utils.js +1 -1
  191. package/ui/less/buttons.less +0 -4
  192. package/ui/less/containers.less +74 -0
  193. package/ui/less/overflow_menu.less +0 -10
  194. package/ui/less/tooltip.less +97 -0
  195. package/ui/locales/en.json +1 -0
  196. package/ui/locales/source.json +4 -0
  197. package/ui/loop_button.js +6 -3
  198. package/ui/mute_button.js +3 -4
  199. package/ui/overflow_menu.js +7 -28
  200. package/ui/pip_button.js +10 -7
  201. package/ui/play_button.js +2 -2
  202. package/ui/playback_rate_selection.js +11 -15
  203. package/ui/presentation_time.js +1 -3
  204. package/ui/resolution_selection.js +11 -7
  205. package/ui/rewind_button.js +17 -9
  206. package/ui/seek_bar.js +6 -6
  207. package/ui/settings_menu.js +36 -4
  208. package/ui/small_play_button.js +1 -0
  209. package/ui/spacer.js +1 -1
  210. package/ui/statistics_button.js +253 -0
  211. package/ui/text_selection.js +19 -15
  212. package/ui/ui.js +30 -0
  213. package/ui/ui_utils.js +1 -1
  214. package/ui/volume_bar.js +2 -4
@@ -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
+ }
@@ -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
+ }
@@ -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
+ ![Shaka storage system flow before](bg-fetch-before.gv.png)
46
+
47
+
48
+ ### Storage System Process: After
49
+
50
+ ![Shaka storage system flow after](bg-fetch-after.gv.png)
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.
@@ -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="1BA79154">
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="1BA79154">
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="1BA79154">
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="1BA79154">
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="1BA79154">
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/aria.js CHANGED
@@ -16,3 +16,9 @@ Element.prototype.ariaLabel;
16
16
 
17
17
  /** @type {string} */
18
18
  Element.prototype.ariaPressed;
19
+
20
+ /** @type {string} */
21
+ Element.prototype.ariaSelected;
22
+
23
+ /** @type {string} */
24
+ Element.prototype.ariaHidden;
package/externs/ima.js CHANGED
@@ -164,6 +164,9 @@ google.ima.Ad = class {
164
164
 
165
165
  /** @return {string} */
166
166
  getAdvertiserName() {}
167
+
168
+ /** @return {boolean} */
169
+ isLinear() {}
167
170
  };
168
171
 
169
172
 
@@ -33,6 +33,24 @@
33
33
  shaka.extern.AdsStats;
34
34
 
35
35
 
36
+ /**
37
+ * @typedef {{
38
+ * start: number,
39
+ * end: ?number
40
+ * }}
41
+ *
42
+ * @description
43
+ * Contains the times of a range of an Ad.
44
+ *
45
+ * @property {number} start
46
+ * The start time of the range, in milliseconds.
47
+ * @property {number} end
48
+ * The end time of the range, in milliseconds.
49
+ * @exportDoc
50
+ */
51
+ shaka.extern.AdCuePoint;
52
+
53
+
36
54
  /**
37
55
  * An object that's responsible for all the ad-related logic
38
56
  * in the player.
@@ -70,7 +88,7 @@ shaka.extern.IAdManager = class extends EventTarget {
70
88
  /**
71
89
  * @param {!google.ima.dai.api.StreamRequest} imaRequest
72
90
  * @param {string=} backupUrl
73
- * @return {!Promise.<!string>}
91
+ * @return {!Promise.<string>}
74
92
  */
75
93
  requestServerSideStream(imaRequest, backupUrl) {}
76
94
 
@@ -79,6 +97,11 @@ shaka.extern.IAdManager = class extends EventTarget {
79
97
  */
80
98
  replaceServerSideAdTagParameters(adTagParameters) {}
81
99
 
100
+ /**
101
+ * @return {!Array.<!shaka.extern.AdCuePoint>}
102
+ */
103
+ getServerSideCuePoints() {}
104
+
82
105
  /**
83
106
  * Get statistics for the current playback session. If the player is not
84
107
  * playing content, this will return an empty stats object.
@@ -184,6 +207,11 @@ shaka.extern.IAd = class {
184
207
  */
185
208
  setMuted(muted) {}
186
209
 
210
+ /**
211
+ * @return {boolean}
212
+ */
213
+ isLinear() {}
214
+
187
215
  /**
188
216
  * @param {number} width
189
217
  * @param {number} height
@@ -111,6 +111,7 @@ shaka.extern.InitDataOverride;
111
111
  * audioRobustness: string,
112
112
  * videoRobustness: string,
113
113
  * serverCertificate: Uint8Array,
114
+ * serverCertificateUri: string,
114
115
  * sessionType: string,
115
116
  * initData: Array.<!shaka.extern.InitDataOverride>,
116
117
  * keyIds: Set.<string>
@@ -150,6 +151,10 @@ shaka.extern.InitDataOverride;
150
151
  * A key-system-specific server certificate used to encrypt license requests.
151
152
  * Its use is optional and is meant as an optimization to avoid a round-trip
152
153
  * to request a certificate.
154
+ * @property {string} serverCertificateUri
155
+ * <i>Defaults to '', e.g., server certificate will be requested from the
156
+ * given URI if serverCertificate is not provided. Can be filled in by
157
+ * advanced DRM config.</i>
153
158
  * @property {Array.<!shaka.extern.InitDataOverride>} initData
154
159
  * <i>Defaults to [], e.g., no override.</i> <br>
155
160
  * A list of initialization data which override any initialization data found
@@ -233,6 +238,7 @@ shaka.extern.CreateSegmentIndexFunction;
233
238
  * id: number,
234
239
  * originalId: ?string,
235
240
  * createSegmentIndex: shaka.extern.CreateSegmentIndexFunction,
241
+ * closeSegmentIndex: (function()|undefined),
236
242
  * segmentIndex: shaka.media.SegmentIndex,
237
243
  * mimeType: string,
238
244
  * codecs: string,
@@ -258,7 +264,10 @@ shaka.extern.CreateSegmentIndexFunction;
258
264
  * audioSamplingRate: ?number,
259
265
  * spatialAudio: boolean,
260
266
  * closedCaptions: Map.<string, string>,
261
- * tilesLayout: (string|undefined)
267
+ * tilesLayout: (string|undefined),
268
+ * matchedStreams:
269
+ * (!Array.<shaka.extern.Stream>|!Array.<shaka.extern.StreamDB>|
270
+ * undefined)
262
271
  * }}
263
272
  *
264
273
  * @description
@@ -275,6 +284,9 @@ shaka.extern.CreateSegmentIndexFunction;
275
284
  * @property {shaka.extern.CreateSegmentIndexFunction} createSegmentIndex
276
285
  * <i>Required.</i> <br>
277
286
  * Creates the Stream's segmentIndex (asynchronously).
287
+ * @property {(function()|undefined)} closeSegmentIndex
288
+ * <i>Optional.</i> <br>
289
+ * Closes the Stream's segmentIndex.
278
290
  * @property {shaka.media.SegmentIndex} segmentIndex
279
291
  * <i>Required.</i> <br>
280
292
  * May be null until createSegmentIndex() is complete.
@@ -328,7 +340,7 @@ shaka.extern.CreateSegmentIndexFunction;
328
340
  * The Stream's label, unique text that should describe the audio/text track.
329
341
  * @property {string} type
330
342
  * <i>Required.</i> <br>
331
- * Content type (e.g. 'video', 'audio' or 'text')
343
+ * Content type (e.g. 'video', 'audio' or 'text', 'image')
332
344
  * @property {boolean} primary
333
345
  * <i>Defaults to false.</i> <br>
334
346
  * True indicates that the player should use this Stream over others if user
@@ -365,6 +377,10 @@ shaka.extern.CreateSegmentIndexFunction;
365
377
  * The value is a grid-item-dimension consisting of two positive decimal
366
378
  * integers in the format: column-x-row ('4x3'). It describes the arrangement
367
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
+ *
368
384
  * @exportDoc
369
385
  */
370
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
-
@@ -101,6 +101,7 @@ shaka.extern.Request;
101
101
  * @typedef {{
102
102
  * uri: string,
103
103
  * data: BufferSource,
104
+ * status: (number|undefined),
104
105
  * headers: !Object.<string, string>,
105
106
  * timeMs: (number|undefined),
106
107
  * fromCache: (boolean|undefined)
@@ -119,6 +120,8 @@ shaka.extern.Request;
119
120
  * redirects, but after request filters are executed.
120
121
  * @property {BufferSource} data
121
122
  * The body of the response.
123
+ * @property {(number|undefined)} status
124
+ * The response HTTP status code.
122
125
  * @property {!Object.<string, string>} headers
123
126
  * A map of response headers, if supported by the underlying protocol.
124
127
  * All keys should be lowercased.
@@ -139,15 +142,17 @@ shaka.extern.Response;
139
142
  * @typedef {!function(string,
140
143
  * shaka.extern.Request,
141
144
  * shaka.net.NetworkingEngine.RequestType,
142
- * shaka.extern.ProgressUpdated):
145
+ * shaka.extern.ProgressUpdated,
146
+ * shaka.extern.HeadersReceived):
143
147
  * !shaka.extern.IAbortableOperation.<shaka.extern.Response>}
144
148
  * @description
145
149
  * Defines a plugin that handles a specific scheme.
146
150
  *
147
151
  * The functions accepts four parameters, uri string, request, request type,
148
- * and a progressUpdated function. The progressUpdated function can be ignored
149
- * by plugins that do not have this information, but it will always be provided
150
- * by NetworkingEngine.
152
+ * a progressUpdated function, and a headersReceived function. The
153
+ * progressUpdated and headersReceived functions can be ignored by plugins that
154
+ * do not have this information, but it will always be provided by
155
+ * NetworkingEngine.
151
156
  *
152
157
  * @exportDoc
153
158
  */
@@ -171,6 +176,17 @@ shaka.extern.SchemePlugin;
171
176
  shaka.extern.ProgressUpdated;
172
177
 
173
178
 
179
+ /**
180
+ * @typedef {function(!Object.<string, string>)}
181
+ *
182
+ * @description
183
+ * A callback function to handle headers received events through networking
184
+ * engine in player.
185
+ * The first argument is the headers object of the response.
186
+ */
187
+ shaka.extern.HeadersReceived;
188
+
189
+
174
190
  /**
175
191
  * Defines a filter for requests. This filter takes the request and modifies
176
192
  * it before it is sent to the scheme plugin.
@@ -33,7 +33,8 @@ shaka.extern.OfflineSupport;
33
33
  * size: number,
34
34
  * expiration: number,
35
35
  * tracks: !Array.<shaka.extern.Track>,
36
- * appMetadata: Object
36
+ * appMetadata: Object,
37
+ * isIncomplete: boolean
37
38
  * }}
38
39
  *
39
40
  * @property {?string} offlineUri
@@ -53,6 +54,9 @@ shaka.extern.OfflineSupport;
53
54
  * The tracks that are stored.
54
55
  * @property {Object} appMetadata
55
56
  * The metadata passed to store().
57
+ * @property {boolean} isIncomplete
58
+ * If true, the content is still downloading. Manifests with this set cannot
59
+ * be played yet.
56
60
  * @exportDoc
57
61
  */
58
62
  shaka.extern.StoredContent;
@@ -68,7 +72,8 @@ shaka.extern.StoredContent;
68
72
  * streams: !Array.<shaka.extern.StreamDB>,
69
73
  * sessionIds: !Array.<string>,
70
74
  * drmInfo: ?shaka.extern.DrmInfo,
71
- * appMetadata: Object
75
+ * appMetadata: Object,
76
+ * isIncomplete: (boolean|undefined)
72
77
  * }}
73
78
  *
74
79
  * @property {number} creationTime
@@ -91,6 +96,8 @@ shaka.extern.StoredContent;
91
96
  * The DRM info used to initialize EME.
92
97
  * @property {Object} appMetadata
93
98
  * A metadata object passed from the application.
99
+ * @property {(boolean|undefined)} isIncomplete
100
+ * If true, the content is still downloading.
94
101
  */
95
102
  shaka.extern.ManifestDB;
96
103
 
@@ -194,6 +201,9 @@ shaka.extern.StreamDB;
194
201
  * appendWindowStart: number,
195
202
  * appendWindowEnd: number,
196
203
  * timestampOffset: number,
204
+ * tilesLayout: ?string,
205
+ * pendingSegmentRefId: (string|undefined),
206
+ * pendingInitSegmentRefId: (string|undefined),
197
207
  * dataKey: number
198
208
  * }}
199
209
  *
@@ -210,6 +220,21 @@ shaka.extern.StreamDB;
210
220
  * @property {number} timestampOffset
211
221
  * An offset which MediaSource will add to the segment's media timestamps
212
222
  * during ingestion, to align to the presentation timeline.
223
+ * @property {?string} tilesLayout
224
+ * The value is a grid-item-dimension consisting of two positive decimal
225
+ * integers in the format: column-x-row ('4x3'). It describes the
226
+ * arrangement of Images in a Grid. The minimum valid LAYOUT is '1x1'.
227
+ * @property {(string|undefined)} pendingSegmentRefId
228
+ * Contains an id that identifies what the segment was, originally. Used to
229
+ * coordinate where segments are stored, during the downloading process.
230
+ * If this field is non-null, it's assumed that the segment is not fully
231
+ * downloaded.
232
+ * @property {(string|undefined)} pendingInitSegmentRefId
233
+ * Contains an id that identifies what the init segment was, originally.
234
+ * Used to coordinate where init segments are stored, during the downloading
235
+ * process.
236
+ * If this field is non-null, it's assumed that the init segment is not fully
237
+ * downloaded.
213
238
  * @property {number} dataKey
214
239
  * The key to the data in storage.
215
240
  */
@@ -328,6 +353,15 @@ shaka.extern.StorageCell = class {
328
353
  */
329
354
  addManifests(manifests) {}
330
355
 
356
+ /**
357
+ * Updates the given manifest, stored at the given key.
358
+ *
359
+ * @param {number} key
360
+ * @param {!shaka.extern.ManifestDB} manifest
361
+ * @return {!Promise}
362
+ */
363
+ updateManifest(key, manifest) {}
364
+
331
365
  /**
332
366
  * Replace the expiration time of the manifest stored under |key| with
333
367
  * |newExpiration|. If no manifest is found under |key| then this should