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.
- 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/AUTHORS +6 -5
- package/CHANGELOG.md +363 -0
- package/CONTRIBUTORS +4 -2
- package/README.md +4 -4
- package/build/types/core +3 -0
- package/build/types/offline +1 -0
- package/build/types/polyfill +2 -0
- package/build/types/ui +2 -0
- package/demo/common/asset.js +9 -7
- package/demo/common/assets.js +28 -1
- package/demo/common/message_ids.js +15 -2
- package/demo/config.js +35 -2
- package/demo/index.html +1 -1
- package/demo/locales/en.json +14 -1
- package/demo/locales/source.json +56 -4
- package/demo/main.js +2 -1
- package/dist/controls.css +26 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +24 -21
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +24 -21
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +33 -25
- package/dist/locales.js +31 -29
- package/dist/receiver.compiled.debug.js +14 -12
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +14 -12
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +258 -20
- package/dist/shaka-player.compiled.debug.d.ts +258 -20
- package/dist/shaka-player.compiled.debug.externs.js +1005 -695
- package/dist/shaka-player.compiled.debug.js +720 -640
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1005 -695
- package/dist/shaka-player.compiled.js +850 -817
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +274 -21
- package/dist/shaka-player.ui.debug.d.ts +274 -21
- package/dist/shaka-player.ui.debug.externs.js +766 -429
- package/dist/shaka-player.ui.debug.js +863 -765
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +766 -429
- package/dist/shaka-player.ui.js +1042 -996
- 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/aria.js +6 -0
- package/externs/ima.js +3 -0
- package/externs/shaka/ads.js +29 -1
- package/externs/shaka/manifest.js +18 -2
- package/externs/shaka/manifest_parser.js +10 -1
- package/externs/shaka/net.js +20 -4
- package/externs/shaka/offline.js +36 -2
- package/externs/shaka/player.js +182 -13
- package/externs/shaka/text.js +24 -10
- package/externs/texttrack.js +3 -0
- package/externs/webcrypto.js +18 -0
- 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 +16 -15
- package/lib/ads/client_side_ad.js +8 -0
- package/lib/ads/client_side_ad_manager.js +14 -6
- package/lib/ads/server_side_ad.js +7 -0
- package/lib/ads/server_side_ad_manager.js +19 -2
- package/lib/cast/cast_proxy.js +8 -0
- package/lib/cast/cast_utils.js +7 -1
- package/lib/cea/cea608_data_channel.js +56 -56
- package/lib/cea/cea608_memory.js +33 -33
- package/lib/cea/cea708_service.js +43 -43
- package/lib/cea/cea708_window.js +38 -38
- package/lib/cea/cea_decoder.js +13 -14
- package/lib/cea/cea_utils.js +23 -23
- package/lib/cea/dtvcc_packet_builder.js +7 -7
- package/lib/cea/i_caption_decoder.js +2 -3
- package/lib/cea/i_cea_parser.js +2 -2
- package/lib/cea/mp4_cea_parser.js +6 -6
- package/lib/dash/dash_parser.js +53 -14
- 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 +210 -30
- package/lib/media/closed_caption_parser.js +1 -2
- package/lib/media/drm_engine.js +162 -192
- package/lib/media/quality_observer.js +291 -0
- package/lib/media/segment_index.js +9 -1
- package/lib/media/segment_reference.js +37 -5
- package/lib/media/streaming_engine.js +48 -10
- 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 +82 -18
- package/lib/offline/download_info.js +68 -0
- package/lib/offline/download_manager.js +14 -7
- package/lib/offline/indexeddb/base_storage_cell.js +35 -0
- package/lib/offline/indexeddb/storage_mechanism.js +1 -1
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v5_storage_cell.js +5 -0
- package/lib/offline/manifest_converter.js +3 -1
- package/lib/offline/storage.js +404 -297
- package/lib/offline/stored_content_utils.js +2 -0
- package/lib/player.js +622 -153
- package/lib/polyfill/aria.js +82 -0
- package/lib/polyfill/random_uuid.js +52 -0
- package/lib/routing/walker.js +2 -3
- package/lib/text/cue.js +12 -0
- package/lib/text/srt_text_parser.js +4 -4
- package/lib/text/text_engine.js +2 -2
- package/lib/text/ttml_text_parser.js +25 -2
- package/lib/text/ui_text_displayer.js +2 -2
- package/lib/text/vtt_text_parser.js +2 -2
- package/lib/text/web_vtt_generator.js +55 -12
- package/lib/util/cmcd_manager.js +826 -0
- package/lib/util/error.js +12 -0
- package/lib/util/language_utils.js +12 -0
- package/lib/util/manifest_parser_utils.js +1 -0
- package/lib/util/mp4_box_parsers.js +20 -20
- package/lib/util/multi_map.js +8 -0
- package/lib/util/mutex.js +52 -0
- package/lib/util/periods.js +98 -64
- package/lib/util/player_configuration.js +31 -1
- package/lib/util/stream_utils.js +140 -85
- package/lib/util/xml_utils.js +31 -12
- package/package.json +1 -1
- package/roadmap.md +24 -22
- package/shaka-player.uncompiled.js +4 -0
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/cea/cea608_memory_unit.js +1 -1
- package/test/cea/cea708_service_unit.js +8 -8
- package/test/cea/cea708_window_unit.js +6 -6
- package/test/cea/cea_decoder_unit.js +1 -1
- package/test/cea/dtvcc_packet_builder_unit.js +2 -2
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_live_unit.js +101 -1
- package/test/dash/dash_parser_manifest_unit.js +78 -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 +252 -0
- package/test/media/drm_engine_integration.js +86 -12
- package/test/media/drm_engine_unit.js +310 -450
- package/test/media/quality_observer_unit.js +139 -0
- package/test/media/segment_reference_unit.js +16 -1
- package/test/media/streaming_engine_integration.js +2 -1
- package/test/media/streaming_engine_unit.js +2 -0
- package/test/net/http_plugin_unit.js +20 -15
- package/test/offline/manifest_convert_unit.js +2 -0
- package/test/offline/storage_integration.js +117 -23
- package/test/player_integration.js +151 -0
- package/test/player_src_equals_integration.js +52 -0
- package/test/player_unit.js +11 -33
- package/test/test/assets/chapters.srt +11 -0
- package/test/test/assets/chapters.vtt +10 -0
- package/test/test/util/cea_utils.js +12 -12
- package/test/test/util/dash_parser_util.js +4 -0
- package/test/test/util/fake_ad.js +7 -0
- package/test/test/util/fake_ad_manager.js +7 -0
- package/test/test/util/fake_drm_engine.js +9 -2
- package/test/test/util/manifest_generator.js +5 -2
- package/test/test/util/manifest_parser_util.js +3 -1
- package/test/test/util/test_scheme.js +14 -1
- package/test/text/ttml_text_parser_unit.js +47 -0
- package/test/text/web_vtt_generator_unit.js +81 -7
- package/test/ui/ui_unit.js +250 -0
- package/test/util/cmcd_manager_unit.js +277 -0
- package/test/util/stream_utils_unit.js +118 -10
- package/ui/airplay_button.js +2 -1
- package/ui/audio_language_selection.js +9 -5
- package/ui/cast_button.js +5 -6
- package/ui/constants.js +0 -3
- package/ui/context_menu.js +109 -0
- package/ui/controls.js +41 -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 +16 -8
- package/ui/fullscreen_button.js +2 -3
- package/ui/language_utils.js +1 -1
- 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/loop_button.js +6 -3
- package/ui/mute_button.js +3 -4
- package/ui/overflow_menu.js +7 -28
- package/ui/pip_button.js +10 -7
- package/ui/play_button.js +2 -2
- package/ui/playback_rate_selection.js +11 -15
- package/ui/presentation_time.js +1 -3
- package/ui/resolution_selection.js +11 -7
- package/ui/rewind_button.js +17 -9
- package/ui/seek_bar.js +6 -6
- package/ui/settings_menu.js +36 -4
- package/ui/small_play_button.js +1 -0
- package/ui/spacer.js +1 -1
- package/ui/statistics_button.js +253 -0
- package/ui/text_selection.js +19 -15
- package/ui/ui.js +30 -0
- package/ui/ui_utils.js +1 -1
- package/ui/volume_bar.js +2 -4
|
@@ -652,8 +652,7 @@ describe('StreamUtils', () => {
|
|
|
652
652
|
});
|
|
653
653
|
|
|
654
654
|
await shaka.util.StreamUtils.filterManifest(
|
|
655
|
-
fakeDrmEngine, /* currentVariant= */ null, manifest
|
|
656
|
-
/* useMediaCapabilities= */ true);
|
|
655
|
+
fakeDrmEngine, /* currentVariant= */ null, manifest);
|
|
657
656
|
|
|
658
657
|
// Covers a regression in which we would remove streams with codecs.
|
|
659
658
|
// The last two streams should be removed because their full MIME types
|
|
@@ -680,8 +679,7 @@ describe('StreamUtils', () => {
|
|
|
680
679
|
});
|
|
681
680
|
|
|
682
681
|
await shaka.util.StreamUtils.filterManifest(
|
|
683
|
-
fakeDrmEngine, /* currentVariant= */ null, manifest
|
|
684
|
-
/* useMediaCapabilities= */ true);
|
|
682
|
+
fakeDrmEngine, /* currentVariant= */ null, manifest);
|
|
685
683
|
expect(manifest.variants.length).toBe(1);
|
|
686
684
|
});
|
|
687
685
|
|
|
@@ -698,8 +696,7 @@ describe('StreamUtils', () => {
|
|
|
698
696
|
});
|
|
699
697
|
|
|
700
698
|
await shaka.util.StreamUtils.filterManifest(
|
|
701
|
-
fakeDrmEngine, /* currentVariant= */ null, manifest
|
|
702
|
-
/* useMediaCapabilities= */ true);
|
|
699
|
+
fakeDrmEngine, /* currentVariant= */ null, manifest);
|
|
703
700
|
|
|
704
701
|
expect(manifest.variants.length).toBe(1);
|
|
705
702
|
});
|
|
@@ -714,6 +711,7 @@ describe('StreamUtils', () => {
|
|
|
714
711
|
variant.bandwidth = 5058558;
|
|
715
712
|
variant.addAudio(1, (stream) => {
|
|
716
713
|
stream.bandwidth = 129998;
|
|
714
|
+
stream.codecs = 'opus';
|
|
717
715
|
});
|
|
718
716
|
variant.addVideo(2, (stream) => {
|
|
719
717
|
stream.bandwidth = 4928560;
|
|
@@ -728,6 +726,7 @@ describe('StreamUtils', () => {
|
|
|
728
726
|
variant.bandwidth = 4911000;
|
|
729
727
|
variant.addAudio(4, (stream) => {
|
|
730
728
|
stream.bandwidth = 129998;
|
|
729
|
+
stream.codecs = 'vorbis';
|
|
731
730
|
});
|
|
732
731
|
variant.addVideo(5, (stream) => {
|
|
733
732
|
stream.bandwidth = 4781002;
|
|
@@ -742,6 +741,7 @@ describe('StreamUtils', () => {
|
|
|
742
741
|
variant.bandwidth = 10850316;
|
|
743
742
|
variant.addAudio(7, (stream) => {
|
|
744
743
|
stream.bandwidth = 129998;
|
|
744
|
+
stream.codecs = 'opus';
|
|
745
745
|
});
|
|
746
746
|
variant.addVideo(8, (stream) => {
|
|
747
747
|
stream.bandwidth = 10784324;
|
|
@@ -751,6 +751,62 @@ describe('StreamUtils', () => {
|
|
|
751
751
|
});
|
|
752
752
|
};
|
|
753
753
|
|
|
754
|
+
it('chooses preferred audio and video codecs', () => {
|
|
755
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
756
|
+
addVariant1080Avc1(manifest);
|
|
757
|
+
addVariant1080Vp9(manifest);
|
|
758
|
+
addVariant2160Vp9(manifest);
|
|
759
|
+
});
|
|
760
|
+
const variants =
|
|
761
|
+
shaka.util.StreamUtils.choosePreferredCodecs(manifest.variants,
|
|
762
|
+
/* preferredVideoCodecs= */['vp09'],
|
|
763
|
+
/* preferredAudioCodecs= */['opus']);
|
|
764
|
+
|
|
765
|
+
expect(variants.length).toBe(1);
|
|
766
|
+
expect(variants[0].video.codecs).toBe(vp09Codecs);
|
|
767
|
+
expect(variants[0].audio.codecs).toBe('opus');
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
it('chooses preferred video codecs', () => {
|
|
771
|
+
// If no preferred audio codecs is specified or can be found, choose the
|
|
772
|
+
// variants with preferred video codecs.
|
|
773
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
774
|
+
addVariant1080Avc1(manifest);
|
|
775
|
+
addVariant1080Vp9(manifest);
|
|
776
|
+
addVariant2160Vp9(manifest);
|
|
777
|
+
});
|
|
778
|
+
const variants =
|
|
779
|
+
shaka.util.StreamUtils.choosePreferredCodecs(manifest.variants,
|
|
780
|
+
/* preferredVideoCodecs= */['vp09'],
|
|
781
|
+
/* preferredAudioCodecs= */[]);
|
|
782
|
+
|
|
783
|
+
expect(variants.length).toBe(2);
|
|
784
|
+
expect(variants[0].video.codecs).toBe(vp09Codecs);
|
|
785
|
+
expect(variants[0].audio.codecs).toBe('vorbis');
|
|
786
|
+
expect(variants[1].video.codecs).toBe(vp09Codecs);
|
|
787
|
+
expect(variants[1].audio.codecs).toBe('opus');
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
it('chooses preferred audio codecs', () => {
|
|
791
|
+
// If no preferred video codecs is specified or can be found, choose the
|
|
792
|
+
// variants with preferred audio codecs.
|
|
793
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
794
|
+
addVariant1080Avc1(manifest);
|
|
795
|
+
addVariant1080Vp9(manifest);
|
|
796
|
+
addVariant2160Vp9(manifest);
|
|
797
|
+
});
|
|
798
|
+
const variants =
|
|
799
|
+
shaka.util.StreamUtils.choosePreferredCodecs(manifest.variants,
|
|
800
|
+
/* preferredVideoCodecs= */['foo'],
|
|
801
|
+
/* preferredAudioCodecs= */['opus']);
|
|
802
|
+
|
|
803
|
+
expect(variants.length).toBe(2);
|
|
804
|
+
expect(variants[0].video.codecs).toBe(avc1Codecs);
|
|
805
|
+
expect(variants[0].audio.codecs).toBe('opus');
|
|
806
|
+
expect(variants[1].video.codecs).toBe(vp09Codecs);
|
|
807
|
+
expect(variants[1].audio.codecs).toBe('opus');
|
|
808
|
+
});
|
|
809
|
+
|
|
754
810
|
it('chooses variants with different sizes (density) by codecs', () => {
|
|
755
811
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
756
812
|
addVariant1080Avc1(manifest);
|
|
@@ -758,11 +814,14 @@ describe('StreamUtils', () => {
|
|
|
758
814
|
addVariant2160Vp9(manifest);
|
|
759
815
|
});
|
|
760
816
|
|
|
761
|
-
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
|
|
817
|
+
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
|
|
818
|
+
/* preferredVideoCodecs= */[],
|
|
819
|
+
/* preferredAudioCodecs= */[],
|
|
820
|
+
/* preferredAudioChannelCount= */2,
|
|
821
|
+
/* preferredDecodingAttributes= */[]);
|
|
762
822
|
|
|
763
|
-
expect(manifest.variants.length).toBe(
|
|
823
|
+
expect(manifest.variants.length).toBe(1);
|
|
764
824
|
expect(manifest.variants[0].video.codecs).toBe(vp09Codecs);
|
|
765
|
-
expect(manifest.variants[1].video.codecs).toBe(vp09Codecs);
|
|
766
825
|
});
|
|
767
826
|
|
|
768
827
|
it('chooses variants with same sizes (density) by codecs', () => {
|
|
@@ -771,10 +830,59 @@ describe('StreamUtils', () => {
|
|
|
771
830
|
addVariant1080Vp9(manifest);
|
|
772
831
|
});
|
|
773
832
|
|
|
774
|
-
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
|
|
833
|
+
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
|
|
834
|
+
/* preferredVideoCodecs= */[],
|
|
835
|
+
/* preferredAudioCodecs= */[],
|
|
836
|
+
/* preferredAudioChannelCount= */2,
|
|
837
|
+
/* preferredDecodingAttributes= */[]);
|
|
775
838
|
|
|
776
839
|
expect(manifest.variants.length).toBe(1);
|
|
777
840
|
expect(manifest.variants[0].video.codecs).toBe(vp09Codecs);
|
|
778
841
|
});
|
|
842
|
+
|
|
843
|
+
it('chooses variants by decoding attributes', async () => {
|
|
844
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
845
|
+
manifest.addVariant(0, (variant) => {
|
|
846
|
+
variant.bandwidth = 4058558;
|
|
847
|
+
variant.addVideo(1, (stream) => {
|
|
848
|
+
stream.mime('video', 'notsmooth');
|
|
849
|
+
});
|
|
850
|
+
});
|
|
851
|
+
manifest.addVariant(1, (variant) => {
|
|
852
|
+
variant.bandwidth = 4781002;
|
|
853
|
+
variant.addVideo(2, (stream) => {
|
|
854
|
+
stream.mime('video', 'smooth');
|
|
855
|
+
});
|
|
856
|
+
});
|
|
857
|
+
manifest.addVariant(3, (variant) => {
|
|
858
|
+
variant.addVideo(4, (stream) => {
|
|
859
|
+
variant.bandwidth = 5058558;
|
|
860
|
+
stream.mime('video', 'smooth-2');
|
|
861
|
+
});
|
|
862
|
+
});
|
|
863
|
+
});
|
|
864
|
+
window.shakaMediaCapabilities.decodingInfo =
|
|
865
|
+
shaka.test.Util.spyFunc(decodingInfoSpy);
|
|
866
|
+
decodingInfoSpy.and.callFake((config) => {
|
|
867
|
+
const res = config.video.contentType.includes('notsmooth') ?
|
|
868
|
+
{supported: true, smooth: false} :
|
|
869
|
+
{supported: true, smooth: true};
|
|
870
|
+
return Promise.resolve(res);
|
|
871
|
+
});
|
|
872
|
+
|
|
873
|
+
await StreamUtils.getDecodingInfosForVariants(manifest.variants,
|
|
874
|
+
/* usePersistentLicenses= */false, /* srcEquals= */ false);
|
|
875
|
+
|
|
876
|
+
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
|
|
877
|
+
/* preferredVideoCodecs= */[],
|
|
878
|
+
/* preferredAudioCodecs= */[],
|
|
879
|
+
/* preferredAudioChannelCount= */2,
|
|
880
|
+
/* preferredDecodingAttributes= */
|
|
881
|
+
[shaka.util.StreamUtils.DecodingAttributes.SMOOTH]);
|
|
882
|
+
// 2 video codecs are smooth. Choose the one with the lowest bandwidth.
|
|
883
|
+
expect(manifest.variants.length).toBe(1);
|
|
884
|
+
expect(manifest.variants[0].id).toBe(1);
|
|
885
|
+
expect(manifest.variants[0].video.id).toBe(2);
|
|
886
|
+
});
|
|
779
887
|
});
|
|
780
888
|
});
|
package/ui/airplay_button.js
CHANGED
|
@@ -36,7 +36,8 @@ shaka.ui.AirPlayButton = class extends shaka.ui.Element {
|
|
|
36
36
|
/** @private {!HTMLButtonElement} */
|
|
37
37
|
this.airplayButton_ = shaka.util.Dom.createButton();
|
|
38
38
|
this.airplayButton_.classList.add('shaka-airplay-button');
|
|
39
|
-
this.airplayButton_.
|
|
39
|
+
this.airplayButton_.classList.add('shaka-tooltip');
|
|
40
|
+
this.airplayButton_.ariaPressed = 'false';
|
|
40
41
|
|
|
41
42
|
/** @private {!HTMLElement} */
|
|
42
43
|
this.airplayIcon_ = shaka.util.Dom.createHTMLElement('i');
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
goog.provide('shaka.ui.AudioLanguageSelection');
|
|
9
9
|
|
|
10
|
-
goog.require('shaka.ui.
|
|
10
|
+
goog.require('shaka.ui.Controls');
|
|
11
11
|
goog.require('shaka.ui.Enums');
|
|
12
12
|
goog.require('shaka.ui.LanguageUtils');
|
|
13
13
|
goog.require('shaka.ui.Locales');
|
|
@@ -32,6 +32,7 @@ shaka.ui.AudioLanguageSelection = class extends shaka.ui.SettingsMenu {
|
|
|
32
32
|
super(parent, controls, shaka.ui.Enums.MaterialDesignIcons.LANGUAGE);
|
|
33
33
|
|
|
34
34
|
this.button.classList.add('shaka-language-button');
|
|
35
|
+
this.button.classList.add('shaka-tooltip-status');
|
|
35
36
|
this.menu.classList.add('shaka-audio-languages');
|
|
36
37
|
|
|
37
38
|
this.eventManager.listen(
|
|
@@ -72,6 +73,8 @@ shaka.ui.AudioLanguageSelection = class extends shaka.ui.SettingsMenu {
|
|
|
72
73
|
|
|
73
74
|
this.controls.dispatchEvent(
|
|
74
75
|
new shaka.util.FakeEvent('languageselectionupdated'));
|
|
76
|
+
|
|
77
|
+
this.button.setAttribute('shaka-status', this.currentSelection.innerText);
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
/** @private */
|
|
@@ -96,10 +99,8 @@ shaka.ui.AudioLanguageSelection = class extends shaka.ui.SettingsMenu {
|
|
|
96
99
|
updateLocalizedStrings_() {
|
|
97
100
|
const LocIds = shaka.ui.Locales.Ids;
|
|
98
101
|
|
|
99
|
-
this.backButton.
|
|
100
|
-
|
|
101
|
-
this.button.setAttribute(shaka.ui.Constants.ARIA_LABEL,
|
|
102
|
-
this.localization.resolve(LocIds.LANGUAGE));
|
|
102
|
+
this.backButton.ariaLabel = this.localization.resolve(LocIds.BACK);
|
|
103
|
+
this.button.ariaLabel = this.localization.resolve(LocIds.LANGUAGE);
|
|
103
104
|
this.nameSpan.textContent =
|
|
104
105
|
this.localization.resolve(LocIds.LANGUAGE);
|
|
105
106
|
this.backSpan.textContent =
|
|
@@ -121,3 +122,6 @@ shaka.ui.AudioLanguageSelection.Factory = class {
|
|
|
121
122
|
|
|
122
123
|
shaka.ui.OverflowMenu.registerElement(
|
|
123
124
|
'language', new shaka.ui.AudioLanguageSelection.Factory());
|
|
125
|
+
|
|
126
|
+
shaka.ui.Controls.registerElement(
|
|
127
|
+
'language', new shaka.ui.AudioLanguageSelection.Factory());
|
package/ui/cast_button.js
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
goog.provide('shaka.ui.CastButton');
|
|
9
9
|
|
|
10
10
|
goog.require('shaka.cast.CastProxy');
|
|
11
|
-
goog.require('shaka.ui.Constants');
|
|
12
11
|
goog.require('shaka.ui.Controls');
|
|
13
12
|
goog.require('shaka.ui.Element');
|
|
14
13
|
goog.require('shaka.ui.Enums');
|
|
@@ -42,7 +41,8 @@ shaka.ui.CastButton = class extends shaka.ui.Element {
|
|
|
42
41
|
/** @private {!HTMLButtonElement} */
|
|
43
42
|
this.castButton_ = shaka.util.Dom.createButton();
|
|
44
43
|
this.castButton_.classList.add('shaka-cast-button');
|
|
45
|
-
this.castButton_.
|
|
44
|
+
this.castButton_.classList.add('shaka-tooltip');
|
|
45
|
+
this.castButton_.ariaPressed = 'false';
|
|
46
46
|
|
|
47
47
|
/** @private {!HTMLElement} */
|
|
48
48
|
this.castIcon_ = shaka.util.Dom.createHTMLElement('i');
|
|
@@ -125,9 +125,9 @@ shaka.ui.CastButton = class extends shaka.ui.Element {
|
|
|
125
125
|
// Aria-pressed set to true when casting, set to false otherwise.
|
|
126
126
|
if (canCast) {
|
|
127
127
|
if (isCasting) {
|
|
128
|
-
this.castButton_.
|
|
128
|
+
this.castButton_.ariaPressed = 'true';
|
|
129
129
|
} else {
|
|
130
|
-
this.castButton_.
|
|
130
|
+
this.castButton_.ariaPressed = 'false';
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -155,8 +155,7 @@ shaka.ui.CastButton = class extends shaka.ui.Element {
|
|
|
155
155
|
updateLocalizedStrings_() {
|
|
156
156
|
const LocIds = shaka.ui.Locales.Ids;
|
|
157
157
|
|
|
158
|
-
this.castButton_.
|
|
159
|
-
this.localization.resolve(LocIds.CAST));
|
|
158
|
+
this.castButton_.ariaLabel = this.localization.resolve(LocIds.CAST);
|
|
160
159
|
this.castNameSpan_.textContent =
|
|
161
160
|
this.localization.resolve(LocIds.CAST);
|
|
162
161
|
|
package/ui/constants.js
CHANGED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
goog.provide('shaka.ui.ContextMenu');
|
|
9
|
+
|
|
10
|
+
goog.require('goog.asserts');
|
|
11
|
+
goog.require('shaka.log');
|
|
12
|
+
goog.require('shaka.ui.Element');
|
|
13
|
+
goog.require('shaka.ui.Utils');
|
|
14
|
+
goog.require('shaka.util.Dom');
|
|
15
|
+
goog.requireType('shaka.ui.Controls');
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @extends {shaka.ui.Element}
|
|
20
|
+
* @final
|
|
21
|
+
* @export
|
|
22
|
+
*/
|
|
23
|
+
shaka.ui.ContextMenu = class extends shaka.ui.Element {
|
|
24
|
+
/**
|
|
25
|
+
* @param {!HTMLElement} parent
|
|
26
|
+
* @param {!shaka.ui.Controls} controls
|
|
27
|
+
*/
|
|
28
|
+
constructor(parent, controls) {
|
|
29
|
+
super(parent, controls);
|
|
30
|
+
|
|
31
|
+
/** @private {!shaka.extern.UIConfiguration} */
|
|
32
|
+
this.config_ = this.controls.getConfig();
|
|
33
|
+
|
|
34
|
+
/** @private {HTMLElement} */
|
|
35
|
+
this.controlsContainer_ = this.controls.getControlsContainer();
|
|
36
|
+
|
|
37
|
+
/** @private {!Array.<shaka.extern.IUIElement>} */
|
|
38
|
+
this.children_ = [];
|
|
39
|
+
|
|
40
|
+
/** @private {!HTMLElement} */
|
|
41
|
+
this.contextMenu_ = shaka.util.Dom.createHTMLElement('div');
|
|
42
|
+
this.contextMenu_.classList.add('shaka-no-propagation');
|
|
43
|
+
this.contextMenu_.classList.add('shaka-context-menu');
|
|
44
|
+
this.contextMenu_.classList.add('shaka-hidden');
|
|
45
|
+
|
|
46
|
+
this.controlsContainer_.appendChild(this.contextMenu_);
|
|
47
|
+
|
|
48
|
+
this.eventManager.listen(this.controlsContainer_, 'contextmenu', (e) => {
|
|
49
|
+
if (this.contextMenu_.classList.contains('shaka-hidden')) {
|
|
50
|
+
e.preventDefault();
|
|
51
|
+
|
|
52
|
+
const controlsLocation =
|
|
53
|
+
this.controlsContainer_.getBoundingClientRect();
|
|
54
|
+
this.contextMenu_.style.left = `${e.clientX - controlsLocation.left}px`;
|
|
55
|
+
this.contextMenu_.style.top = `${e.clientY - controlsLocation.top}px`;
|
|
56
|
+
|
|
57
|
+
shaka.ui.Utils.setDisplay(this.contextMenu_, true);
|
|
58
|
+
} else {
|
|
59
|
+
shaka.ui.Utils.setDisplay(this.contextMenu_, false);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
this.eventManager.listen(window, 'click', () => {
|
|
64
|
+
shaka.ui.Utils.setDisplay(this.contextMenu_, false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
this.createChildren_();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** @override */
|
|
71
|
+
release() {
|
|
72
|
+
this.controlsContainer_ = null;
|
|
73
|
+
|
|
74
|
+
for (const element of this.children_) {
|
|
75
|
+
element.release();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.children_ = [];
|
|
79
|
+
super.release();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @param {string} name
|
|
84
|
+
* @param {!shaka.extern.IUIElement.Factory} factory
|
|
85
|
+
* @export
|
|
86
|
+
*/
|
|
87
|
+
static registerElement(name, factory) {
|
|
88
|
+
shaka.ui.ContextMenu.elementNamesToFactories_.set(name, factory);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @private
|
|
93
|
+
*/
|
|
94
|
+
createChildren_() {
|
|
95
|
+
for (const name of this.config_.contextMenuElements) {
|
|
96
|
+
const factory =
|
|
97
|
+
shaka.ui.ContextMenu.elementNamesToFactories_.get(name);
|
|
98
|
+
if (factory) {
|
|
99
|
+
goog.asserts.assert(this.controls, 'Controls should not be null!');
|
|
100
|
+
this.children_.push(factory.create(this.contextMenu_, this.controls));
|
|
101
|
+
} else {
|
|
102
|
+
shaka.log.alwaysWarn('Unrecognized context menu element:', name);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/** @private {!Map.<string, !shaka.extern.IUIElement.Factory>} */
|
|
109
|
+
shaka.ui.ContextMenu.elementNamesToFactories_ = new Map();
|
package/ui/controls.js
CHANGED
|
@@ -16,6 +16,7 @@ goog.require('shaka.log');
|
|
|
16
16
|
goog.require('shaka.ui.AdCounter');
|
|
17
17
|
goog.require('shaka.ui.AdPosition');
|
|
18
18
|
goog.require('shaka.ui.BigPlayButton');
|
|
19
|
+
goog.require('shaka.ui.ContextMenu');
|
|
19
20
|
goog.require('shaka.ui.Locales');
|
|
20
21
|
goog.require('shaka.ui.Localization');
|
|
21
22
|
goog.require('shaka.ui.SeekBar');
|
|
@@ -323,6 +324,10 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
323
324
|
this.playButton_ = null;
|
|
324
325
|
}
|
|
325
326
|
|
|
327
|
+
if (this.contextMenu_) {
|
|
328
|
+
this.contextMenu_ = null;
|
|
329
|
+
}
|
|
330
|
+
|
|
326
331
|
if (this.controlsContainer_) {
|
|
327
332
|
shaka.util.Dom.removeAllChildren(this.controlsContainer_);
|
|
328
333
|
this.releaseChildElements_();
|
|
@@ -650,6 +655,10 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
650
655
|
this.addPlayButton_();
|
|
651
656
|
}
|
|
652
657
|
|
|
658
|
+
if (this.config_.customContextMenu) {
|
|
659
|
+
this.addContextMenu_();
|
|
660
|
+
}
|
|
661
|
+
|
|
653
662
|
if (!this.spinnerContainer_) {
|
|
654
663
|
this.addBufferingSpinner_();
|
|
655
664
|
}
|
|
@@ -708,6 +717,14 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
708
717
|
this.elements_.push(this.playButton_);
|
|
709
718
|
}
|
|
710
719
|
|
|
720
|
+
/** @private */
|
|
721
|
+
addContextMenu_() {
|
|
722
|
+
/** @private {shaka.ui.ContextMenu} */
|
|
723
|
+
this.contextMenu_ =
|
|
724
|
+
new shaka.ui.ContextMenu(this.controlsButtonPanel_, this);
|
|
725
|
+
this.elements_.push(this.contextMenu_);
|
|
726
|
+
}
|
|
727
|
+
|
|
711
728
|
/** @private */
|
|
712
729
|
addScrimContainer_() {
|
|
713
730
|
// This is the container that gets styled by CSS to have the
|
|
@@ -722,7 +739,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
722
739
|
/** @private {!HTMLElement} */
|
|
723
740
|
this.adPanel_ = shaka.util.Dom.createHTMLElement('div');
|
|
724
741
|
this.adPanel_.classList.add('shaka-ad-controls');
|
|
725
|
-
|
|
742
|
+
const showAdPanel = this.ad_ != null && this.ad_.isLinear();
|
|
743
|
+
shaka.ui.Utils.setDisplay(this.adPanel_, showAdPanel);
|
|
726
744
|
this.bottomControls_.appendChild(this.adPanel_);
|
|
727
745
|
|
|
728
746
|
const adPosition = new shaka.ui.AdPosition(this.adPanel_, this);
|
|
@@ -779,8 +797,12 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
779
797
|
// on the page. The click event listener on window ensures that.
|
|
780
798
|
// However, clicks on the bottom controls don't propagate to the container,
|
|
781
799
|
// so we have to explicitly hide the menus onclick here.
|
|
782
|
-
this.eventManager_.listen(this.bottomControls_, 'click', () => {
|
|
783
|
-
this
|
|
800
|
+
this.eventManager_.listen(this.bottomControls_, 'click', (e) => {
|
|
801
|
+
// We explicitly deny this measure when clicking on buttons that
|
|
802
|
+
// open submenus in the control panel.
|
|
803
|
+
if (!e.target['closest']('.shaka-overflow-button')) {
|
|
804
|
+
this.hideSettingsMenus();
|
|
805
|
+
}
|
|
784
806
|
});
|
|
785
807
|
|
|
786
808
|
this.addAdControls_();
|
|
@@ -790,6 +812,9 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
790
812
|
this.controlsButtonPanel_.classList.add('shaka-controls-button-panel');
|
|
791
813
|
this.controlsButtonPanel_.classList.add(
|
|
792
814
|
'shaka-show-controls-on-mouse-over');
|
|
815
|
+
if (this.config_.enableTooltips) {
|
|
816
|
+
this.controlsButtonPanel_.classList.add('shaka-tooltips-on');
|
|
817
|
+
}
|
|
793
818
|
this.bottomControls_.appendChild(this.controlsButtonPanel_);
|
|
794
819
|
|
|
795
820
|
// Create the elements specified by controlPanelElements
|
|
@@ -859,7 +884,7 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
859
884
|
|
|
860
885
|
|
|
861
886
|
/**
|
|
862
|
-
* Adds a container for
|
|
887
|
+
* Adds a container for client side ad UI with IMA SDK.
|
|
863
888
|
*
|
|
864
889
|
* @private
|
|
865
890
|
*/
|
|
@@ -868,6 +893,9 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
868
893
|
this.clientAdContainer_ = shaka.util.Dom.createHTMLElement('div');
|
|
869
894
|
this.clientAdContainer_.classList.add('shaka-client-side-ad-container');
|
|
870
895
|
shaka.ui.Utils.setDisplay(this.clientAdContainer_, false);
|
|
896
|
+
this.eventManager_.listen(this.clientAdContainer_, 'click', () => {
|
|
897
|
+
this.onContainerClick_();
|
|
898
|
+
});
|
|
871
899
|
this.videoContainer_.appendChild(this.clientAdContainer_);
|
|
872
900
|
}
|
|
873
901
|
|
|
@@ -894,6 +922,12 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
894
922
|
// Listen for click events to dismiss the settings menus.
|
|
895
923
|
this.eventManager_.listen(window, 'click', () => this.hideSettingsMenus());
|
|
896
924
|
|
|
925
|
+
// Avoid having multiple submenus open at the same time.
|
|
926
|
+
this.eventManager_.listen(
|
|
927
|
+
this, 'submenuopen', () => {
|
|
928
|
+
this.hideSettingsMenus();
|
|
929
|
+
});
|
|
930
|
+
|
|
897
931
|
this.eventManager_.listen(this.video_, 'play', () => {
|
|
898
932
|
this.onPlayStateChange_();
|
|
899
933
|
});
|
|
@@ -1100,7 +1134,7 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
1100
1134
|
// recent mouse movement, we're in keyboard navigation, or one of a special
|
|
1101
1135
|
// class of elements is hovered.
|
|
1102
1136
|
if (adIsPaused ||
|
|
1103
|
-
(!this.ad_ && videoIsPaused) ||
|
|
1137
|
+
((!this.ad_ || !this.ad_.isLinear()) && videoIsPaused) ||
|
|
1104
1138
|
this.recentMouseMovement_ ||
|
|
1105
1139
|
keyboardNavigationMode ||
|
|
1106
1140
|
this.isHovered_()) {
|
|
@@ -1144,14 +1178,14 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
1144
1178
|
|
|
1145
1179
|
if (this.anySettingsMenusAreOpen()) {
|
|
1146
1180
|
this.hideSettingsMenusTimer_.tickNow();
|
|
1147
|
-
} else {
|
|
1181
|
+
} else if (this.config_.singleClickForPlayAndPause) {
|
|
1148
1182
|
this.onPlayPauseClick_();
|
|
1149
1183
|
}
|
|
1150
1184
|
}
|
|
1151
1185
|
|
|
1152
1186
|
/** @private */
|
|
1153
1187
|
onPlayPauseClick_() {
|
|
1154
|
-
if (this.ad_) {
|
|
1188
|
+
if (this.ad_ && this.ad_.isLinear()) {
|
|
1155
1189
|
this.playPauseAd();
|
|
1156
1190
|
} else {
|
|
1157
1191
|
this.playPausePresentation();
|
package/ui/controls.less
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
@import "less/other_elements.less";
|
|
13
13
|
@import "less/overflow_menu.less";
|
|
14
14
|
@import "less/ad_controls.less";
|
|
15
|
+
@import "less/tooltip.less";
|
|
15
16
|
@import (css, inline) "https://fonts.googleapis.com/css?family=Roboto";
|
|
16
17
|
// NOTE: Working around google/material-design-icons#958
|
|
17
18
|
@import (css, inline) "https://fonts.googleapis.com/icon?family=Material+Icons+Round";
|
package/ui/enums.js
CHANGED
|
@@ -16,7 +16,9 @@ goog.provide('shaka.ui.Enums');
|
|
|
16
16
|
shaka.ui.Enums.MaterialDesignIcons = {
|
|
17
17
|
'FULLSCREEN': 'fullscreen',
|
|
18
18
|
'EXIT_FULLSCREEN': 'fullscreen_exit',
|
|
19
|
+
'CLOSE': 'close',
|
|
19
20
|
'CLOSED_CAPTIONS': 'closed_caption',
|
|
21
|
+
'CLOSED_CAPTIONS_OFF': 'closed_caption_disabled',
|
|
20
22
|
'CHECKMARK': 'done',
|
|
21
23
|
'LANGUAGE': 'language',
|
|
22
24
|
'PIP': 'picture_in_picture_alt',
|
|
@@ -40,4 +42,6 @@ shaka.ui.Enums.MaterialDesignIcons = {
|
|
|
40
42
|
'UNLOOP': 'repeat_on',
|
|
41
43
|
'AIRPLAY': 'airplay',
|
|
42
44
|
'REPLAY': 'replay',
|
|
45
|
+
'STATISTICS_ON': 'insert_chart_outlined',
|
|
46
|
+
'STATISTICS_OFF': 'insert_chart',
|
|
43
47
|
};
|
package/ui/externs/ui.js
CHANGED
|
@@ -63,8 +63,14 @@ shaka.extern.UIVolumeBarColors;
|
|
|
63
63
|
* @typedef {{
|
|
64
64
|
* controlPanelElements: !Array.<string>,
|
|
65
65
|
* overflowMenuButtons: !Array.<string>,
|
|
66
|
+
* contextMenuElements: !Array.<string>,
|
|
67
|
+
* statisticsList: !Array.<string>,
|
|
68
|
+
* playbackRates: !Array.<number>,
|
|
69
|
+
* fastForwardRates: !Array.<number>,
|
|
70
|
+
* rewindRates: !Array.<number>,
|
|
66
71
|
* addSeekBar: boolean,
|
|
67
72
|
* addBigPlayButton: boolean,
|
|
73
|
+
* customContextMenu: boolean,
|
|
68
74
|
* castReceiverAppId: string,
|
|
69
75
|
* clearBufferOnQualityChange: boolean,
|
|
70
76
|
* showUnbufferedStart: boolean,
|
|
@@ -73,20 +79,34 @@ shaka.extern.UIVolumeBarColors;
|
|
|
73
79
|
* trackLabelFormat: shaka.ui.Overlay.TrackLabelFormat,
|
|
74
80
|
* fadeDelay: number,
|
|
75
81
|
* doubleClickForFullscreen: boolean,
|
|
82
|
+
* singleClickForPlayAndPause: boolean,
|
|
76
83
|
* enableKeyboardPlaybackControls: boolean,
|
|
77
84
|
* enableFullscreenOnRotation: boolean,
|
|
78
|
-
* forceLandscapeOnFullscreen: boolean
|
|
85
|
+
* forceLandscapeOnFullscreen: boolean,
|
|
86
|
+
* enableTooltips: boolean
|
|
79
87
|
* }}
|
|
80
88
|
*
|
|
81
89
|
* @property {!Array.<string>} controlPanelElements
|
|
82
90
|
* The ordered list of control panel elements of the UI.
|
|
83
91
|
* @property {!Array.<string>} overflowMenuButtons
|
|
84
92
|
* The ordered list of the overflow menu buttons.
|
|
93
|
+
* @property {!Array.<string>} contextMenuElements
|
|
94
|
+
* The ordered list of buttons in the context menu.
|
|
95
|
+
* @property {!Array.<string>} statisticsList
|
|
96
|
+
* The ordered list of statistics present in the statistics container.
|
|
97
|
+
* @property {!Array.<number>} playbackRates
|
|
98
|
+
* The ordered list of rates for playback selection.
|
|
99
|
+
* @property {!Array.<number>} fastForwardRates
|
|
100
|
+
* The ordered list of rates for fast forward selection.
|
|
101
|
+
* @property {!Array.<number>} rewindRates
|
|
102
|
+
* The ordered list of rates for rewind selection.
|
|
85
103
|
* @property {boolean} addSeekBar
|
|
86
104
|
* Whether or not a seek bar should be part of the UI.
|
|
87
105
|
* @property {boolean} addBigPlayButton
|
|
88
106
|
* Whether or not a big play button in the center of the video
|
|
89
107
|
* should be part of the UI.
|
|
108
|
+
* @property {boolean} customContextMenu
|
|
109
|
+
* Whether or not a custom context menu replaces the default.
|
|
90
110
|
* @property {string} castReceiverAppId
|
|
91
111
|
* Receiver app id to use for the Chromecast support.
|
|
92
112
|
* @property {boolean} clearBufferOnQualityChange
|
|
@@ -135,6 +155,9 @@ shaka.extern.UIVolumeBarColors;
|
|
|
135
155
|
* Whether or not double-clicking on the UI should cause it to enter
|
|
136
156
|
* fullscreen.
|
|
137
157
|
* Defaults to true.
|
|
158
|
+
* @property {boolean} singleClickForPlayAndPause
|
|
159
|
+
* Whether or not clicking on the video should cause it to play or pause.
|
|
160
|
+
* Defaults to true.
|
|
138
161
|
* @property {boolean} enableKeyboardPlaybackControls
|
|
139
162
|
* Whether or not playback controls via keyboard is enabled, such as seek
|
|
140
163
|
* forward, seek backward, jump to the beginning/end of the video.
|
|
@@ -147,6 +170,10 @@ shaka.extern.UIVolumeBarColors;
|
|
|
147
170
|
* enters fullscreen. Note that this behavior is based on an experimental
|
|
148
171
|
* browser API, and may not work on all platforms.
|
|
149
172
|
* Defaults to true.
|
|
173
|
+
* @property {boolean} enableTooltips
|
|
174
|
+
* Whether or not buttons in the control panel display tooltips that contain
|
|
175
|
+
* information about their function.
|
|
176
|
+
* Defaults to false.
|
|
150
177
|
* @exportDoc
|
|
151
178
|
*/
|
|
152
179
|
shaka.extern.UIConfiguration;
|