From 2d4abc87f1357e5223a0841ca4a98a6f470d440b Mon Sep 17 00:00:00 2001 From: binon Date: Wed, 4 Sep 2024 12:41:44 +0100 Subject: [PATCH 01/27] Changes for MK Player UI, temoporary comit before tryin iphone fix --- .../Scripts/vuesrc/content/cmsPageRow.vue | 2 +- .../Scripts/vuesrc/mkiomediaplayer.ts | 101 + .../Views/Cms/PageDetail.cshtml | 5 +- .../wwwroot/css/mkplayer-ui.css | 1873 +++++++++++++ .../Scripts/vuesrc/mkiomediaplayer.d.ts | 2328 ----------------- .../Scripts/vuesrc/mkiomediaplayer.ts | 84 + .../vuesrc/resource/ResourceContent.vue | 46 +- .../ContributeResource.cshtml | 4 +- .../CovidTesting/_CovidTestingLayout.cshtml | 4 +- .../Views/Home/GenericTray.cshtml | 4 +- .../Views/Home/LandingPage.cshtml | 2 +- .../Views/Home/_CmsVideo.cshtml | 175 +- .../Views/Offline/Index.cshtml | 2 +- .../Views/Resource/Resource.cshtml | 4 +- .../Shared/Tenant/LearningHub/_Layout.cshtml | 2 +- 15 files changed, 2144 insertions(+), 2492 deletions(-) create mode 100644 AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/mkiomediaplayer.ts create mode 100644 AdminUI/LearningHub.Nhs.AdminUI/wwwroot/css/mkplayer-ui.css delete mode 100644 LearningHub.Nhs.WebUI/Scripts/vuesrc/mkiomediaplayer.d.ts create mode 100644 LearningHub.Nhs.WebUI/Scripts/vuesrc/mkiomediaplayer.ts diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue index ec21a1ba4..dd02810f7 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue +++ b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue @@ -196,7 +196,7 @@ // Prepare the player configuration const playerConfig = { key: this.mkioKey, - ui: false, + ui: true, playback: { muted: false, autoplay: false, diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/mkiomediaplayer.ts b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/mkiomediaplayer.ts new file mode 100644 index 000000000..988dbdace --- /dev/null +++ b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/mkiomediaplayer.ts @@ -0,0 +1,101 @@ +import { MKPlayer, MKPlayerConfig } from '@mediakind/mkplayer'; +import { MKPlayerType, MKStreamType } from './MKPlayerConfigEnum'; +interface ClearKeyConfig { + LA_URL: string; + headers: { + Authorization: string; + }; +} + +interface PlayerConfig { + key: string; + ui: boolean; + playback: { + muted: boolean; + autoplay: boolean; + preferredTech: Array<{ player: string; streaming: string }>; + }; + theme: string; + events: { + ready: () => void; + }; +} + +interface SourceConfig { + hls: string; + drm: { + clearkey: ClearKeyConfig; + }; +} + +function getBearerToken(authenticationToken: string): string { + // Replace this with your actual logic to get the bearer token + return `Bearer ${authenticationToken}`; +} + +function getPlayerConfig( + mkioKey: string, + onPlayerReady: () => void +): PlayerConfig { + return { + key: mkioKey, + ui: true, + playback: { + muted: false, + autoplay: false, + preferredTech: [{ player: "Html5", streaming: "Hls" }] // Adjust these strings if you have specific types + }, + theme: "dark", + events: { + ready: onPlayerReady, + } + }; +} + +function getSourceConfig( + locatorUri: string, + authenticationToken: string +): SourceConfig { + return { + hls: locatorUri, + drm: { + clearkey: { + LA_URL: "HLS_AES", + headers: { + Authorization: getBearerToken(authenticationToken) + } + } + } + }; +} + +function initializePlayer(videoContainer: HTMLElement, playerConfig: MKPlayerConfig, playBackUrl: string, bearerToken: string): any { + const player = new MKPlayer(videoContainer, playerConfig); + + var clearKeyConfig = { + //LA_URL: "https://ottapp-appgw-amp.prodc.mkio.tv3cloud.com/drm/clear-key?ownerUid=azuki", + LA_URL: "HLS_AES", + headers: { + "Authorization": bearerToken + } + }; + + const sourceConfig: SourceConfig = { + hls: playBackUrl, + drm: { + clearkey: clearKeyConfig + } + }; + + player.load(sourceConfig) + .then(() => { + console.log("Source loaded successfully!"); + }) + .catch(() => { + console.error("An error occurred while loading the source!"); + }); + + return player; +}; + +export { getPlayerConfig, getSourceConfig, initializePlayer }; diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Views/Cms/PageDetail.cshtml b/AdminUI/LearningHub.Nhs.AdminUI/Views/Cms/PageDetail.cshtml index f6ae3a2da..ca848cc75 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Views/Cms/PageDetail.cshtml +++ b/AdminUI/LearningHub.Nhs.AdminUI/Views/Cms/PageDetail.cshtml @@ -3,7 +3,8 @@ } @section Styles{ - + @* *@ + } @@ -14,5 +15,5 @@ @section Scripts{ - + @* *@ } \ No newline at end of file diff --git a/AdminUI/LearningHub.Nhs.AdminUI/wwwroot/css/mkplayer-ui.css b/AdminUI/LearningHub.Nhs.AdminUI/wwwroot/css/mkplayer-ui.css new file mode 100644 index 000000000..e058edfef --- /dev/null +++ b/AdminUI/LearningHub.Nhs.AdminUI/wwwroot/css/mkplayer-ui.css @@ -0,0 +1,1873 @@ +@charset "UTF-8"; +/**************************************************************************** + * Copyright (C) 2023, Bitmovin, Inc., All Rights Reserved + * + * This source code and its use and distribution, is subject to the terms + * and conditions of the applicable license agreement. + * + * Bitmovin Player Version 8.119.0 + * + ****************************************************************************/ +.bmpui-ui-subtitle-overlay.bmpui-cea608 .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-fontfamily-monospacedserif .bmpui-ui-subtitle-label { + font-family: Courier New,Courier,Nimbus Mono L,Cutive Mono,monospace +} + +.bmpui-ui-airplaytogglebutton, .bmpui-ui-audiotracksettingstogglebutton, .bmpui-ui-buffering-overlay, .bmpui-ui-button, .bmpui-ui-cast-status-overlay, .bmpui-ui-casttogglebutton, .bmpui-ui-clickoverlay, .bmpui-ui-closebutton, .bmpui-ui-component, .bmpui-ui-container, .bmpui-ui-controlbar, .bmpui-ui-errormessage-overlay, .bmpui-ui-fullscreentogglebutton, .bmpui-ui-hugeplaybacktogglebutton, .bmpui-ui-hugereplaybutton, .bmpui-ui-label, .bmpui-ui-listbox, .bmpui-ui-listbox .bmpui-ui-listbox-button, .bmpui-ui-piptogglebutton, .bmpui-ui-playbacktimelabel, .bmpui-ui-playbacktoggle-overlay, .bmpui-ui-playbacktogglebutton, .bmpui-ui-recommendation-overlay, .bmpui-ui-replaybutton, .bmpui-ui-seekbar, .bmpui-ui-seekbar-label, .bmpui-ui-selectbox, .bmpui-ui-settings-panel, .bmpui-ui-settingspanelpagebackbutton, .bmpui-ui-settingspanelpageopenbutton, .bmpui-ui-settingstogglebutton, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-button-ad-skip, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-label-ad-message, .bmpui-ui-spacer, .bmpui-ui-subtitlesettingsresetbutton, .bmpui-ui-subtitlesettingstogglebutton, .bmpui-ui-titlebar, .bmpui-ui-uicontainer, .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay, .bmpui-ui-volumecontrolbutton, .bmpui-ui-volumeslider, .bmpui-ui-volumetogglebutton, .bmpui-ui-vrtogglebutton, .bmpui-ui-watermark { /*! placeholder to avoid removal of empty selector */ + outline: 0 +} + + .bmpui-ui-buffering-overlay, .bmpui-ui-cast-status-overlay, .bmpui-ui-container, .bmpui-ui-controlbar, .bmpui-ui-errormessage-overlay, .bmpui-ui-listbox, .bmpui-ui-playbacktoggle-overlay, .bmpui-ui-recommendation-overlay, .bmpui-ui-seekbar-label, .bmpui-ui-settings-panel, .bmpui-ui-subtitle-overlay.bmpui-fontsize-100 .bmpui-ui-subtitle-label, .bmpui-ui-titlebar, .bmpui-ui-uicontainer, .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay, .bmpui-ui-volumecontrolbutton { + font-size: 1em + } + +.bmpui-ui-uicontainer { + height: 100%; + left: 0; + margin: 0; + overflow: hidden; + pointer-events: none; + position: absolute; + top: 0; + width: 100% +} + + .bmpui-ui-uicontainer * { + pointer-events: auto + } + + .bmpui-hidden.bmpui-ui-airplaytogglebutton, .bmpui-hidden.bmpui-ui-audiotracksettingstogglebutton, .bmpui-hidden.bmpui-ui-button, .bmpui-hidden.bmpui-ui-casttogglebutton, .bmpui-hidden.bmpui-ui-clickoverlay, .bmpui-hidden.bmpui-ui-closebutton, .bmpui-hidden.bmpui-ui-fullscreentogglebutton, .bmpui-hidden.bmpui-ui-hugeplaybacktogglebutton, .bmpui-hidden.bmpui-ui-hugereplaybutton, .bmpui-hidden.bmpui-ui-label, .bmpui-hidden.bmpui-ui-piptogglebutton, .bmpui-hidden.bmpui-ui-playbacktimelabel, .bmpui-hidden.bmpui-ui-playbacktogglebutton, .bmpui-hidden.bmpui-ui-replaybutton, .bmpui-hidden.bmpui-ui-seekbar, .bmpui-hidden.bmpui-ui-settingspanelpagebackbutton, .bmpui-hidden.bmpui-ui-settingspanelpageopenbutton, .bmpui-hidden.bmpui-ui-settingstogglebutton, .bmpui-hidden.bmpui-ui-subtitlesettingsresetbutton, .bmpui-hidden.bmpui-ui-subtitlesettingstogglebutton, .bmpui-hidden.bmpui-ui-volumeslider, .bmpui-hidden.bmpui-ui-volumetogglebutton, .bmpui-hidden.bmpui-ui-vrtogglebutton, .bmpui-hidden.bmpui-ui-watermark, .bmpui-no-flexbox .bmpui-ui-controlbar .bmpui-controlbar-bottom > .bmpui-container-wrapper > .bmpui-hidden, .bmpui-no-flexbox .bmpui-ui-controlbar .bmpui-controlbar-top > .bmpui-container-wrapper > .bmpui-hidden, .bmpui-ui-buffering-overlay.bmpui-hidden .bmpui-ui-buffering-overlay-indicator, .bmpui-ui-errormessage-overlay.bmpui-hidden, .bmpui-ui-listbox .bmpui-hidden.bmpui-ui-listbox-button, .bmpui-ui-settings-panel-page, .bmpui-ui-settings-panel-page .bmpui-ui-settings-panel-item.bmpui-hidden, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-hidden.bmpui-ui-button-ad-skip, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-hidden.bmpui-ui-label-ad-message, .bmpui-ui-skin-ads.bmpui-player-state-playing .bmpui-ui-playbacktoggle-overlay, .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-buffering-overlay-indicator, .bmpui-ui-skin-smallscreen .bmpui-ui-watermark, .bmpui-ui-skin-smallscreen.bmpui-no-flexbox .bmpui-ui-titlebar > .bmpui-container-wrapper > .bmpui-hidden, .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay.bmpui-hidden, .bmpui-ui-uicontainer.bmpui-hidden, .bmpui-ui-uicontainer.bmpui-layout-max-width-400 .bmpui-ui-titlebar .bmpui-label-metadata-description, .bmpui-ui-uicontainer.bmpui-player-state-finished .bmpui-ui-controlbar, .bmpui-ui-uicontainer.bmpui-player-state-finished .bmpui-ui-hugeplaybacktogglebutton, .bmpui-ui-uicontainer.bmpui-player-state-idle .bmpui-ui-controlbar, .bmpui-ui-uicontainer.bmpui-player-state-idle .bmpui-ui-hugeplaybacktogglebutton, .bmpui-ui-uicontainer.bmpui-player-state-idle .bmpui-ui-titlebar, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-bufferlevel { + display: none + } + + .bmpui-ui-uicontainer.bmpui-player-state-playing.bmpui-controls-hidden * { + cursor: none + } + + .bmpui-ui-uicontainer.bmpui-controls-shown .bmpui-ui-hugeplaybacktogglebutton:focus { + -webkit-box-shadow: inset -4px -3px 2px 9px #1b7fcc; + box-shadow: inset -4px -3px 2px 9px #1b7fcc + } + + .bmpui-ui-uicontainer.bmpui-controls-shown .bmpui-ui-hugeplaybacktogglebutton:focus:not(.bmpui-focus-visible) { + -webkit-box-shadow: none; + box-shadow: none + } + + .bmpui-ui-uicontainer.bmpui-no-flexbox { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=") + } + + .bmpui-ui-uicontainer.bmpui-no-flexbox.bmpui-fullscreen { + left: 0; + position: fixed; + top: 0; + z-index: 999999 + } + +.bmpui-ui-controlbar { + background: -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.7))); + background: linear-gradient(180deg,transparent,rgba(0,0,0,.7)); + bottom: 0; + -webkit-box-sizing: border-box; + box-sizing: border-box; + line-height: 1em; + opacity: 1; + padding: 1em 1em .5em; + position: absolute; + -webkit-transition: opacity .3s,visibility; + transition: opacity .3s,visibility; + width: 100% +} + + .bmpui-ui-controlbar.bmpui-hidden, .bmpui-ui-titlebar.bmpui-hidden { + opacity: 0; + -webkit-transition: opacity .3s; + transition: opacity .3s + } + + .bmpui-ui-controlbar .bmpui-controlbar-bottom > .bmpui-container-wrapper, .bmpui-ui-controlbar .bmpui-controlbar-top > .bmpui-container-wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + margin: .5em 0 + } + + .bmpui-ui-controlbar .bmpui-controlbar-top .bmpui-ui-label { + font-size: .9em + } + + .bmpui-ui-controlbar .bmpui-controlbar-top > .bmpui-container-wrapper > *, .bmpui-ui-settings-panel > .bmpui-container-wrapper > * { + margin: 0 .5em + } + + .bmpui-ui-controlbar .bmpui-controlbar-bottom { + white-space: nowrap + } + + .bmpui-ui-controlbar .bmpui-controlbar-bottom > .bmpui-container-wrapper .bmpui-ui-volumeslider { + margin: auto .5em; + width: 5em + } + +.bmpui-no-flexbox .bmpui-ui-controlbar .bmpui-controlbar-bottom > .bmpui-container-wrapper, .bmpui-no-flexbox .bmpui-ui-controlbar .bmpui-controlbar-top > .bmpui-container-wrapper { + border-spacing: .5em 0; + display: table +} + + .bmpui-no-flexbox .bmpui-ui-controlbar .bmpui-controlbar-bottom > .bmpui-container-wrapper > *, .bmpui-no-flexbox .bmpui-ui-controlbar .bmpui-controlbar-top > .bmpui-container-wrapper > * { + display: table-cell; + vertical-align: middle + } + + .bmpui-no-flexbox .bmpui-ui-controlbar .bmpui-controlbar-bottom > .bmpui-container-wrapper .bmpui-ui-volumeslider, .bmpui-no-flexbox .bmpui-ui-controlbar .bmpui-controlbar-top > .bmpui-container-wrapper .bmpui-ui-volumeslider { + width: 10% + } + +.bmpui-ui-airplaytogglebutton, .bmpui-ui-audiotracksettingstogglebutton, .bmpui-ui-button, .bmpui-ui-casttogglebutton, .bmpui-ui-clickoverlay, .bmpui-ui-closebutton, .bmpui-ui-fullscreentogglebutton, .bmpui-ui-hugeplaybacktogglebutton, .bmpui-ui-hugereplaybutton, .bmpui-ui-listbox .bmpui-ui-listbox-button, .bmpui-ui-piptogglebutton, .bmpui-ui-playbacktogglebutton, .bmpui-ui-replaybutton, .bmpui-ui-settingspanelpagebackbutton, .bmpui-ui-settingspanelpageopenbutton, .bmpui-ui-settingstogglebutton, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-button-ad-skip, .bmpui-ui-subtitlesettingsresetbutton, .bmpui-ui-subtitlesettingstogglebutton, .bmpui-ui-volumetogglebutton, .bmpui-ui-vrtogglebutton, .bmpui-ui-watermark { + background-color: transparent; + background-origin: content-box; + background-position: 50%; + background-repeat: no-repeat; + background-size: 1.5em; + border: 0; + -webkit-box-sizing: content-box; + box-sizing: content-box; + cursor: pointer; + font-size: 1em; + height: 1.5em; + min-width: 1.5em; + padding: .25em +} + + .bmpui-ui-airplaytogglebutton .bmpui-label, .bmpui-ui-audiotracksettingstogglebutton .bmpui-label, .bmpui-ui-button .bmpui-label, .bmpui-ui-casttogglebutton .bmpui-label, .bmpui-ui-clickoverlay .bmpui-label, .bmpui-ui-closebutton .bmpui-label, .bmpui-ui-fullscreentogglebutton .bmpui-label, .bmpui-ui-hugeplaybacktogglebutton .bmpui-label, .bmpui-ui-hugereplaybutton .bmpui-label, .bmpui-ui-listbox .bmpui-ui-listbox-button .bmpui-label, .bmpui-ui-piptogglebutton .bmpui-label, .bmpui-ui-playbacktogglebutton .bmpui-label, .bmpui-ui-replaybutton .bmpui-label, .bmpui-ui-settingspanelpagebackbutton .bmpui-label, .bmpui-ui-settingspanelpageopenbutton .bmpui-label, .bmpui-ui-settingstogglebutton .bmpui-label, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-button-ad-skip .bmpui-label, .bmpui-ui-subtitlesettingsresetbutton .bmpui-label, .bmpui-ui-subtitlesettingstogglebutton .bmpui-label, .bmpui-ui-volumetogglebutton .bmpui-label, .bmpui-ui-vrtogglebutton .bmpui-label, .bmpui-ui-watermark .bmpui-label { + color: #fff; + display: none + } + +.bmpui-disabled.bmpui-ui-airplaytogglebutton, .bmpui-disabled.bmpui-ui-audiotracksettingstogglebutton, .bmpui-disabled.bmpui-ui-button, .bmpui-disabled.bmpui-ui-casttogglebutton, .bmpui-disabled.bmpui-ui-clickoverlay, .bmpui-disabled.bmpui-ui-closebutton, .bmpui-disabled.bmpui-ui-fullscreentogglebutton, .bmpui-disabled.bmpui-ui-hugeplaybacktogglebutton, .bmpui-disabled.bmpui-ui-hugereplaybutton, .bmpui-disabled.bmpui-ui-piptogglebutton, .bmpui-disabled.bmpui-ui-playbacktogglebutton, .bmpui-disabled.bmpui-ui-replaybutton, .bmpui-disabled.bmpui-ui-settingspanelpagebackbutton, .bmpui-disabled.bmpui-ui-settingspanelpageopenbutton, .bmpui-disabled.bmpui-ui-settingstogglebutton, .bmpui-disabled.bmpui-ui-subtitlesettingsresetbutton, .bmpui-disabled.bmpui-ui-subtitlesettingstogglebutton, .bmpui-disabled.bmpui-ui-volumetogglebutton, .bmpui-disabled.bmpui-ui-vrtogglebutton, .bmpui-disabled.bmpui-ui-watermark, .bmpui-ui-listbox .bmpui-disabled.bmpui-ui-listbox-button, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-disabled.bmpui-ui-button-ad-skip { + cursor: default +} + + .bmpui-disabled.bmpui-ui-airplaytogglebutton, .bmpui-disabled.bmpui-ui-airplaytogglebutton > *, .bmpui-disabled.bmpui-ui-audiotracksettingstogglebutton, .bmpui-disabled.bmpui-ui-audiotracksettingstogglebutton > *, .bmpui-disabled.bmpui-ui-button, .bmpui-disabled.bmpui-ui-button > *, .bmpui-disabled.bmpui-ui-casttogglebutton, .bmpui-disabled.bmpui-ui-casttogglebutton > *, .bmpui-disabled.bmpui-ui-clickoverlay, .bmpui-disabled.bmpui-ui-clickoverlay > *, .bmpui-disabled.bmpui-ui-closebutton, .bmpui-disabled.bmpui-ui-closebutton > *, .bmpui-disabled.bmpui-ui-fullscreentogglebutton, .bmpui-disabled.bmpui-ui-fullscreentogglebutton > *, .bmpui-disabled.bmpui-ui-hugeplaybacktogglebutton, .bmpui-disabled.bmpui-ui-hugeplaybacktogglebutton > *, .bmpui-disabled.bmpui-ui-hugereplaybutton, .bmpui-disabled.bmpui-ui-hugereplaybutton > *, .bmpui-disabled.bmpui-ui-piptogglebutton, .bmpui-disabled.bmpui-ui-piptogglebutton > *, .bmpui-disabled.bmpui-ui-playbacktogglebutton, .bmpui-disabled.bmpui-ui-playbacktogglebutton > *, .bmpui-disabled.bmpui-ui-replaybutton, .bmpui-disabled.bmpui-ui-replaybutton > *, .bmpui-disabled.bmpui-ui-settingspanelpagebackbutton, .bmpui-disabled.bmpui-ui-settingspanelpagebackbutton > *, .bmpui-disabled.bmpui-ui-settingspanelpageopenbutton, .bmpui-disabled.bmpui-ui-settingspanelpageopenbutton > *, .bmpui-disabled.bmpui-ui-settingstogglebutton, .bmpui-disabled.bmpui-ui-settingstogglebutton > *, .bmpui-disabled.bmpui-ui-subtitlesettingsresetbutton, .bmpui-disabled.bmpui-ui-subtitlesettingsresetbutton > *, .bmpui-disabled.bmpui-ui-subtitlesettingstogglebutton, .bmpui-disabled.bmpui-ui-subtitlesettingstogglebutton > *, .bmpui-disabled.bmpui-ui-volumetogglebutton, .bmpui-disabled.bmpui-ui-volumetogglebutton > *, .bmpui-disabled.bmpui-ui-vrtogglebutton, .bmpui-disabled.bmpui-ui-vrtogglebutton > *, .bmpui-disabled.bmpui-ui-watermark, .bmpui-disabled.bmpui-ui-watermark > *, .bmpui-ui-cast-status-overlay .bmpui-ui-cast-status-label *, .bmpui-ui-listbox .bmpui-disabled.bmpui-ui-listbox-button, .bmpui-ui-listbox .bmpui-disabled.bmpui-ui-listbox-button > *, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-disabled.bmpui-ui-button-ad-skip, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-disabled.bmpui-ui-button-ad-skip > *, .bmpui-ui-titlebar > .bmpui-container-wrapper .bmpui-label-metadata { + pointer-events: none + } + + .bmpui-disabled.bmpui-ui-airplaytogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-audiotracksettingstogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-button .bmpui-label:hover, .bmpui-disabled.bmpui-ui-casttogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-clickoverlay .bmpui-label:hover, .bmpui-disabled.bmpui-ui-closebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-fullscreentogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-hugeplaybacktogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-hugereplaybutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-piptogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-playbacktogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-replaybutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-settingspanelpagebackbutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-settingspanelpageopenbutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-settingstogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-subtitlesettingsresetbutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-subtitlesettingstogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-volumetogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-vrtogglebutton .bmpui-label:hover, .bmpui-disabled.bmpui-ui-watermark .bmpui-label:hover, .bmpui-ui-listbox .bmpui-disabled.bmpui-ui-listbox-button .bmpui-label:hover, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-disabled.bmpui-ui-button-ad-skip .bmpui-label:hover { + text-decoration: none + } + +.bmpui-ui-airplaytogglebutton:focus, .bmpui-ui-audiotracksettingstogglebutton:focus, .bmpui-ui-button:focus, .bmpui-ui-casttogglebutton:focus, .bmpui-ui-clickoverlay:focus, .bmpui-ui-closebutton:focus, .bmpui-ui-fullscreentogglebutton:focus, .bmpui-ui-hugeplaybacktogglebutton:focus, .bmpui-ui-hugereplaybutton:focus, .bmpui-ui-listbox .bmpui-ui-listbox-button:focus, .bmpui-ui-piptogglebutton:focus, .bmpui-ui-playbacktogglebutton:focus, .bmpui-ui-replaybutton:focus, .bmpui-ui-seekbar:focus, .bmpui-ui-selectbox:focus, .bmpui-ui-settingspanelpagebackbutton:focus, .bmpui-ui-settingspanelpageopenbutton:focus, .bmpui-ui-settingstogglebutton:focus, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-button-ad-skip:focus, .bmpui-ui-subtitlesettingsresetbutton:focus, .bmpui-ui-subtitlesettingstogglebutton:focus, .bmpui-ui-volumeslider:focus, .bmpui-ui-volumetogglebutton:focus, .bmpui-ui-vrtogglebutton:focus, .bmpui-ui-watermark:focus { + -webkit-box-shadow: 0 0 0 2px rgba(27,127,204,.8); + box-shadow: 0 0 0 2px rgba(27,127,204,.8); + outline: 0 +} + + .bmpui-ui-airplaytogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-audiotracksettingstogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-button:focus:not(.bmpui-focus-visible), .bmpui-ui-casttogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-clickoverlay:focus:not(.bmpui-focus-visible), .bmpui-ui-closebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-fullscreentogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-hugeplaybacktogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-hugereplaybutton:focus:not(.bmpui-focus-visible), .bmpui-ui-listbox .bmpui-ui-listbox-button:focus:not(.bmpui-focus-visible), .bmpui-ui-piptogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-playbacktogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-replaybutton:focus:not(.bmpui-focus-visible), .bmpui-ui-seekbar:focus:not(.bmpui-focus-visible), .bmpui-ui-selectbox:focus:not(.bmpui-focus-visible), .bmpui-ui-settingspanelpagebackbutton:focus:not(.bmpui-focus-visible), .bmpui-ui-settingspanelpageopenbutton:focus:not(.bmpui-focus-visible), .bmpui-ui-settingstogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-button-ad-skip:focus:not(.bmpui-focus-visible), .bmpui-ui-subtitlesettingsresetbutton:focus:not(.bmpui-focus-visible), .bmpui-ui-subtitlesettingstogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-volumeslider:focus:not(.bmpui-focus-visible), .bmpui-ui-volumetogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-vrtogglebutton:focus:not(.bmpui-focus-visible), .bmpui-ui-watermark:focus:not(.bmpui-focus-visible) { + -webkit-box-shadow: none; + box-shadow: none; + outline: 0 + } + +.bmpui-ui-playbacktogglebutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cpath d='M23.3 15.2 9.8 5.6c-.3-.2-.7-.3-1-.1-.3.2-.5.5-.5.8v19.3c0 .4.2.7.6.9.1.1.3.1.4.1.2 0 .4-.1.6-.2l13.4-9.7c.3-.2.4-.5.4-.8-.1-.2-.2-.6-.4-.7zm-13 8.4V8.4L21 16l-10.7 7.6z' style='fill:%23fff'/%3E%3C/svg%3E") +} + + .bmpui-ui-airplaytogglebutton:hover, .bmpui-ui-audiotracksettingstogglebutton:hover, .bmpui-ui-casttogglebutton:hover, .bmpui-ui-fullscreentogglebutton:hover, .bmpui-ui-piptogglebutton:hover, .bmpui-ui-playbacktogglebutton:hover, .bmpui-ui-replaybutton:hover, .bmpui-ui-settingspanelpageopenbutton:hover, .bmpui-ui-settingstogglebutton:hover, .bmpui-ui-subtitlesettingstogglebutton:hover, .bmpui-ui-volumetogglebutton:hover, .bmpui-ui-vrtogglebutton:hover { + -webkit-filter: drop-shadow(0 0 1px #fff); + filter: drop-shadow(0 0 1px #fff) + } + + .bmpui-ui-playbacktogglebutton.bmpui-on { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M11.3 5.4H8.9c-1.3 0-2.4 1.1-2.4 2.4v16.5c0 1.3 1.1 2.4 2.4 2.4h2.4c1.3 0 2.4-1.1 2.4-2.4V7.7c-.1-1.3-1.1-2.3-2.4-2.3zm0 18.9H8.9V7.7h2.4v16.6z' id='Rectangle_2_copy'/%3E%3Cpath class='st0' d='M23.1 5.4h-2.4c-1.3 0-2.4 1.1-2.4 2.4v16.5c0 1.3 1.1 2.4 2.4 2.4h2.4c1.3 0 2.4-1.1 2.4-2.4V7.7c-.1-1.3-1.1-2.3-2.4-2.3zm0 18.9h-2.4V7.7h2.4v16.6z' id='Rectangle_2_copy_2'/%3E%3C/svg%3E") + } + + .bmpui-ui-playbacktogglebutton.bmpui-on.bmpui-stoptoggle { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cpath d='M24.3 5.4H7.7c-1.3 0-2.4 1.1-2.4 2.4v16.5c0 1.3 1.1 2.4 2.4 2.4h16.5c1.3 0 2.4-1.1 2.4-2.4V7.7c0-1.3-1-2.3-2.3-2.3zm0 18.9H7.7V7.7h16.5v16.6z' style='fill:%23fff'/%3E%3C/svg%3E") + } + +.bmpui-ui-fullscreentogglebutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M4.7 7.7h4.7V5.4H4.7c-1.3 0-2.4 1.1-2.4 2.4v4.7h2.4V7.7z' id='Rectangle_6'/%3E%3Cpath class='st0' d='M4.7 19.5H2.4v4.7c0 1.3 1.1 2.4 2.4 2.4h4.7v-2.4H4.7v-4.7z' id='Rectangle_6_copy'/%3E%3Cpath class='st0' d='M27.3 5.4h-4.7v2.4h4.7v4.7h2.4V7.7c-.1-1.3-1.1-2.3-2.4-2.3z' id='Rectangle_6_copy_2'/%3E%3Cpath class='st0' d='M27.3 24.3h-4.7v2.4h4.7c1.3 0 2.4-1.1 2.4-2.4v-4.7h-2.4v4.7z' id='Rectangle_6_copy_3'/%3E%3C/svg%3E") +} + + .bmpui-ui-fullscreentogglebutton.bmpui-on { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st1{fill:%231fabe2}%3C/style%3E%3Cpath class='st1' d='M4.7 7.7h22.5v16.5H4.7z' id='Rectangle_19' style='opacity:.302'/%3E%3Cpath class='st1' d='M4.7 7.7h4.7V5.4H4.7c-1.3 0-2.4 1.1-2.4 2.4v4.7h2.4V7.7z' id='Rectangle_6_1_'/%3E%3Cpath class='st1' d='M4.7 19.5H2.4v4.7c0 1.3 1.1 2.4 2.4 2.4h4.7v-2.4H4.7v-4.7z' id='Rectangle_6_copy_1_'/%3E%3Cpath class='st1' d='M27.3 5.4h-4.7v2.4h4.7v4.7h2.4V7.7c-.1-1.3-1.1-2.3-2.4-2.3z' id='Rectangle_6_copy_2_1_'/%3E%3Cpath class='st1' d='M27.3 24.3h-4.7v2.4h4.7c1.3 0 2.4-1.1 2.4-2.4v-4.7h-2.4v4.7z' id='Rectangle_6_copy_3_1_'/%3E%3C/svg%3E") + } + +.bmpui-ui-vrtogglebutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M29 5.4H3C1.7 5.4.6 6.5.6 7.8v16.5c0 1.3 1.1 2.4 2.4 2.4h9.4v-2.4H3V7.7h26v16.5h-9.4v2.4H29c1.3 0 2.4-1.1 2.4-2.4V7.7c0-1.3-1.1-2.3-2.4-2.3z' id='Rectangle_9'/%3E%3Cpath class='st0' d='M10.1 11.3c-2.6 0-4.7 2.1-4.7 4.7s2.1 4.7 4.7 4.7 4.7-2.1 4.7-4.7-2.1-4.7-4.7-4.7zm0 7.1c-1.3 0-2.4-1.1-2.4-2.4s1.1-2.4 2.4-2.4 2.4 1.1 2.4 2.4-1.1 2.4-2.4 2.4z' id='v'/%3E%3Cpath class='st0' d='M21.9 11.3c-2.6 0-4.7 2.1-4.7 4.7s2.1 4.7 4.7 4.7 4.7-2.1 4.7-4.7-2.1-4.7-4.7-4.7zm0 7.1c-1.3 0-2.4-1.1-2.4-2.4s1.1-2.4 2.4-2.4 2.4 1.1 2.4 2.4-1.1 2.4-2.4 2.4z' id='v_copy'/%3E%3Cpath class='st0' d='M16 23.1c2 0 3.5 1.5 3.5 3.5h2.4c0-3.3-2.6-5.9-5.9-5.9s-5.9 2.6-5.9 5.9h2.4c0-2 1.5-3.5 3.5-3.5z' id='Rectangle_10'/%3E%3C/svg%3E") +} + + .bmpui-ui-vrtogglebutton.bmpui-on { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st1{fill:%231fabe2}%3C/style%3E%3Cpath class='st1' d='M3 7.7v16.5h10.6v-2.4h4.7v2.4H29V7.7H3zm4.7 11.8v-7.1h5.9v7.1H7.7zm17.7 0h-7.1v-7.1h7.1v7.1z' id='Rectangle_25' style='opacity:.302'/%3E%3Cpath class='st1' d='M21.9 20.7c2.6 0 4.7-2.1 4.7-4.7s-2.1-4.7-4.7-4.7-4.7 2.1-4.7 4.7 2.1 4.7 4.7 4.7zm0-7.1c1.3 0 2.4 1.1 2.4 2.4s-1.1 2.4-2.4 2.4-2.4-1.1-2.4-2.4 1.1-2.4 2.4-2.4zm-11.8 7.1c2.6 0 4.7-2.1 4.7-4.7s-2.1-4.7-4.7-4.7-4.7 2.1-4.7 4.7 2.1 4.7 4.7 4.7zm0-7.1c1.3 0 2.4 1.1 2.4 2.4s-1.1 2.4-2.4 2.4-2.4-1.1-2.4-2.4 1.1-2.4 2.4-2.4zM29 5.4H3C1.7 5.4.6 6.5.6 7.8v16.5c0 1.3 1.1 2.4 2.4 2.4h9.4c0-2 1.5-3.5 3.5-3.5s3.5 1.5 3.5 3.5H29c1.3 0 2.4-1.1 2.4-2.4V7.7c0-1.3-1.1-2.3-2.4-2.3zm0 18.9h-7.6c-.9-2.1-3-3.5-5.4-3.5s-4.5 1.4-5.4 3.5H3V7.7h26v16.6z' id='Rectangle_10_1_'/%3E%3C/svg%3E") + } + +.bmpui-ui-volumetogglebutton.bmpui-muted, .bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="0"] { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M12.2 13.1H6.4c-1.1 0-1.9.9-1.9 1.9v2c0 1.1.9 1.9 1.9 1.9h5.8c1.1 0 1.9-.9 1.9-1.9v-2c0-1-.9-1.9-1.9-1.9zm0 3.9H6.4v-2h5.8v2z' id='Rectangle_2_copy_4'/%3E%3Cpath class='st0' d='M18.1 11.9c-.4.4-.4 1 0 1.4l6.8 6.8c.4.4 1 .4 1.4 0s.4-1 0-1.4l-6.8-6.8c-.4-.4-1-.4-1.4 0z' id='Rounded_Rectangle_3'/%3E%3Cpath class='st0' d='M26.3 11.9c-.4-.4-1-.4-1.4 0l-6.8 6.8c-.4.4-.4 1 0 1.4s1 .4 1.4 0l6.8-6.8c.4-.4.4-1 0-1.4z' id='Rounded_Rectangle_3_1_'/%3E%3Cpath class='st0' d='M17.9 21.7v2l-9.6-7v2.5l10 7.1c.2.1.4.2.6.2s.3 0 .5-.1c.3-.2.6-.5.6-.9v-3.9l-2.1.1zM17.9 10.3H20v-4c-.1-.4-.3-.7-.7-.9-.3-.2-.8-.1-1.1.1l-9.9 7.1v2.5l9.6-6.9v2.1z'/%3E%3C/svg%3E") +} + +.bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="1"], .bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="2"], .bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="3"], .bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="4"], .bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="5"] { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M19.3 5.5c-.3-.2-.8-.1-1.1.1l-9.9 7.1v2.5l9.6-6.9v15.4l-9.6-7v2.5l10 7.1c.2.1.4.2.6.2s.3 0 .5-.1c.3-.2.6-.5.6-.9V6.3c-.1-.3-.3-.6-.7-.8z' id='Rectangle_4'/%3E%3Cpath class='st0' d='M12.2 13.1H6.4c-1.1 0-1.9.9-1.9 1.9v2c0 1.1.9 1.9 1.9 1.9h5.8c1.1 0 1.9-.9 1.9-1.9v-2c0-1-.9-1.9-1.9-1.9zm0 3.9H6.4v-2h5.8v2z' id='Rectangle_2_copy_4'/%3E%3Cpath class='st0' d='M23.7 12.1c-.6 0-1 .4-1 1v5.8c0 .6.4 1 1 1s1-.4 1-1v-5.8c0-.6-.4-1-1-1z' id='Rounded_Rectangle_4'/%3E%3C/svg%3E") +} + +.bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="10"], .bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="6"], .bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="7"], .bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="8"], .bmpui-ui-volumetogglebutton.bmpui-unmuted[data-bmpui-volume-level-tens="9"] { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M19.3 5.5c-.3-.2-.8-.1-1.1.1l-9.9 7.1v2.5l9.6-6.9v15.4l-9.6-7v2.5l10 7.1c.2.1.4.2.6.2s.3 0 .5-.1c.3-.2.6-.5.6-.9V6.3c-.1-.3-.3-.6-.7-.8z' id='Rectangle_4'/%3E%3Cpath class='st0' d='M12.2 13.1H6.4c-1.1 0-1.9.9-1.9 1.9v2c0 1.1.9 1.9 1.9 1.9h5.8c1.1 0 1.9-.9 1.9-1.9v-2c0-1-.9-1.9-1.9-1.9zm0 3.9H6.4v-2h5.8v2z' id='Rectangle_2_copy_4'/%3E%3Cpath class='st0' d='M27.6 10.2c-.6 0-1 .4-1 1v9.7c0 .6.4 1 1 1s1-.4 1-1v-9.7c0-.6-.4-1-1-1z' id='Rounded_Rectangle_3'/%3E%3Cpath class='st0' d='M23.7 12.1c-.6 0-1 .4-1 1v5.8c0 .6.4 1 1 1s1-.4 1-1v-5.8c0-.6-.4-1-1-1z' id='Rounded_Rectangle_4'/%3E%3C/svg%3E") +} + +.bmpui-ui-watermark { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 68 68' style='enable-background:new 0 0 68 68' xml:space='preserve'%3E%3Cpath d='M63.3 32.5 24.3 5v13.4l20.4 14.5c.8.6.8 1.8 0 2.4L24.3 49.6V63l39-27.5c.9-.8.9-2.2 0-3zm-25.3 0L12.8 14.7V25l11.1 7.9c.8.6.8 1.8 0 2.4L12.8 43v10.3L38 35.5c1-.8 1-2.2 0-3zm-20.8.1L4 23.2v6.5l4.5 3.2c.8.6.8 1.8 0 2.4L4 38.4v6.5l13.2-9.4c1-.8 1-2.2 0-2.9z' style='fill-rule:evenodd;clip-rule:evenodd;fill:%231fabe2'/%3E%3C/svg%3E"); + background-size: initial; + height: 4em; + margin: 2em; + opacity: .8; + position: absolute; + right: 0; + top: 0; + width: 4em +} + +.bmpui-ui-settingspanelpageopenbutton, .bmpui-ui-settingstogglebutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cpath d='m25.6 13.8-1.4-.3c-.2-.5-.4-1-.6-1.4l.9-1.3c.4-.5.3-1.3-.1-1.7L23 7.7c-.3-.3-.6-.4-1-.4-.3 0-.6.1-.8.3l-1.2.9c-.5-.3-1-.5-1.5-.6l-.3-1.4c0-.6-.6-1.1-1.3-1.1H15c-.7 0-1.2.5-1.3 1.1L13.5 8c-.5.2-1 .4-1.4.6l-1.3-.9c-.2-.2-.5-.3-.8-.3-.4 0-.7.1-1 .4L7.8 9.1c-.5.5-.5 1.2-.1 1.7l.9 1.3c-.3.5-.5 1-.6 1.4l-1.4.3c-.7 0-1.2.6-1.2 1.3V17c0 .7.5 1.2 1.1 1.3l1.5.2c.2.5.4 1 .6 1.4l-.9 1.3c-.4.5-.3 1.3.1 1.7l1.4 1.4c.3.3.6.4 1 .4.3 0 .6-.1.8-.3l1.3-.9c.5.2 1 .4 1.4.6l.3 1.4c.1.7.7 1.1 1.3 1.1H17c.7 0 1.2-.5 1.3-1.1l.3-1.4c.5-.2 1-.4 1.4-.6l1.3.9c.2.2.5.3.8.3.4 0 .7-.1 1-.4l1.4-1.4c.5-.5.5-1.2.1-1.7L23.5 20c.3-.5.5-1 .6-1.4l1.4-.3c.7-.1 1.1-.7 1.1-1.3v-2c0-.5-.5-1.1-1-1.2zm-1 3.1c0 .1 0 .1 0 0l-1.8.4c-.2 0-.4.2-.4.4-.2.6-.4 1.2-.7 1.6-.1.2-.1.4 0 .6l1 1.4v.1l-1.2 1.2h-.2l-1.4-1c-.2-.1-.4-.1-.6 0-.5.3-1.1.6-1.6.7-.2.1-.4.2-.4.4l-.3 1.8c0 .1-.1.1-.1.1h-1.7c-.1 0-.1 0-.1-.1l-.3-1.7c0-.2-.2-.4-.4-.4-.6-.2-1.2-.4-1.6-.7-.1 0-.2-.1-.3-.1-.1 0-.2 0-.3.1l-1.4 1h-.2l-1.2-1.2v-.1l1-1.4c.1-.2.1-.4 0-.6-.4-.4-.7-1-.8-1.6-.1-.2-.2-.4-.4-.4L7.5 17c-.1 0-.1-.1-.1-.1v-1.7c0-.1 0-.1.1-.1l1.7-.2c.2 0 .4-.2.5-.4.2-.6.4-1.2.7-1.6.1-.2.1-.4 0-.6l-1-1.4v-.1l1.2-1.2h.2l1.4 1c.2.1.4.1.6 0 .5-.3 1.1-.6 1.6-.7.2-.1.4-.2.4-.4l.2-2c0-.1.1-.1.1-.1h1.7c.1 0 .1 0 .1.1l.2 1.7c0 .2.2.4.4.5.6.2 1.2.4 1.7.7.2.1.4.1.6 0l1.4-1h.2l1.2 1.2v.1l-1 1.4c-.1.2-.1.4 0 .6.3.5.6 1.1.7 1.6.1.2.2.4.4.4l1.6.3c.1 0 .1.1.1.1v1.8h.2zM16 11.5c-2.5 0-4.5 2-4.5 4.5s2 4.5 4.5 4.5 4.5-2 4.5-4.5-2-4.5-4.5-4.5zm0 7.3c-1.5 0-2.8-1.3-2.8-2.8s1.3-2.8 2.8-2.8 2.8 1.3 2.8 2.8-1.3 2.8-2.8 2.8z' style='fill:%23fff'/%3E%3C/svg%3E") +} + +.bmpui-ui-watermark:hover { + opacity: 1 +} + +.bmpui-ui-hugeplaybacktogglebutton { + cursor: default; + height: 8em; + outline: 0; + overflow: hidden; + width: 8em +} + +@-webkit-keyframes fade-out { + 0% { + opacity: 1; + visibility: visible + } + + to { + opacity: 0; + -webkit-transform: scale(2); + transform: scale(2); + visibility: hidden + } +} + +@keyframes fade-out { + 0% { + opacity: 1; + visibility: visible + } + + to { + opacity: 0; + -webkit-transform: scale(2); + transform: scale(2); + visibility: hidden + } +} + +@-webkit-keyframes fade-in { + 0% { + opacity: 0; + -webkit-transform: scale(2); + transform: scale(2); + visibility: visible + } + + to { + opacity: 1 + } +} + +@keyframes fade-in { + 0% { + opacity: 0; + -webkit-transform: scale(2); + transform: scale(2); + visibility: visible + } + + to { + opacity: 1 + } +} + +@-webkit-keyframes breathe { + 30% { + -webkit-transform: scale(1.1); + transform: scale(1.1) + } + + 60% { + -webkit-transform: scale(1); + transform: scale(1) + } +} + +@keyframes breathe { + 30% { + -webkit-transform: scale(1.1); + transform: scale(1.1) + } + + 60% { + -webkit-transform: scale(1); + transform: scale(1) + } +} + +.bmpui-ui-hugeplaybacktogglebutton .bmpui-image { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 140 140' style='enable-background:new 0 0 140 140' xml:space='preserve'%3E%3Cpath d='M70 5C34.1 5 5 34.1 5 70s29.1 65 65 65 65-29.1 65-65S105.9 5 70 5zm0 127c-34.2 0-62-27.8-62-62S35.8 8 70 8s62 27.8 62 62-27.8 62-62 62z' style='opacity:.6;fill-rule:evenodd;clip-rule:evenodd;fill:%23fff'/%3E%3Cpath d='M89.2 68.5 63.1 50.4c-.6-.4-1.4-.5-2-.1-.6.3-1.1 1-1.1 1.7v36.2c0 .7.4 1.4 1.1 1.7.3.1.6.2.9.2.4 0 .8-.1 1.1-.4l26.1-18.1c.5-.4.8-.9.8-1.5 0-.7-.3-1.3-.8-1.6zM63.9 84.4V55.6L84.7 70 63.9 84.4z' style='fill-rule:evenodd;clip-rule:evenodd;fill:%23fff'/%3E%3C/svg%3E"); + background-position: 50%; + background-repeat: no-repeat; + background-size: 7em; + height: 100%; + width: 100% +} + + .bmpui-ui-hugeplaybacktogglebutton .bmpui-image:hover { + -webkit-animation: 3s ease-in-out infinite breathe; + animation: 3s ease-in-out infinite breathe + } + +.bmpui-ui-hugeplaybacktogglebutton.bmpui-on .bmpui-image { + -webkit-animation: .3s cubic-bezier(.55,.055,.675,.19) fade-out; + animation: .3s cubic-bezier(.55,.055,.675,.19) fade-out; + -webkit-transition: visibility 0s .3s; + transition: visibility 0s .3s; + visibility: hidden +} + +.bmpui-ui-hugeplaybacktogglebutton.bmpui-off .bmpui-image { + -webkit-animation: .3s cubic-bezier(.55,.055,.675,.19) fade-in; + animation: .3s cubic-bezier(.55,.055,.675,.19) fade-in; + visibility: visible +} + +.bmpui-ui-hugeplaybacktogglebutton.bmpui-no-transition-animations.bmpui-off .bmpui-image, .bmpui-ui-hugeplaybacktogglebutton.bmpui-no-transition-animations.bmpui-on .bmpui-image, .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-hugeplaybacktogglebutton.bmpui-off .bmpui-image, .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-hugeplaybacktogglebutton.bmpui-on .bmpui-image { + -webkit-animation: none; + animation: none; + -webkit-transition: none; + transition: none +} + +.bmpui-ui-label, .bmpui-ui-playbacktimelabel, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-label-ad-message { + cursor: default; + white-space: nowrap +} + +.bmpui-ui-settings-panel { + background-color: hsla(0,0%,7%,.85); + bottom: 5em; + opacity: 1; + overflow: hidden; + padding: 0; + position: absolute; + right: 2em; + -webkit-transition: opacity .3s,visibility,height .35s cubic-bezier(.4, 0, .2, 1),width .35s cubic-bezier(.4, 0, .2, 1); + transition: opacity .3s,visibility,height .35s cubic-bezier(.4, 0, .2, 1),width .35s cubic-bezier(.4, 0, .2, 1); + visibility: visible +} + +.bmpui-hidden.bmpui-ui-settings-panel, .bmpui-ui-cast-status-overlay.bmpui-hidden, .bmpui-ui-seekbar-label.bmpui-hidden { + opacity: 0; + -webkit-transition: opacity .3s,visibility .3s; + transition: opacity .3s,visibility .3s; + visibility: hidden +} + +.bmpui-ui-cast-status-overlay, .bmpui-ui-seekbar-label { + opacity: 1; + -webkit-transition: opacity .3s,visibility; + visibility: visible +} + +.bmpui-ui-settings-panel > .bmpui-container-wrapper { + margin: .5em; + overflow-y: auto +} + +.bmpui-container-wrapper > .bmpui-ui-settings-panel { + margin: 0 +} + +.bmpui-active.bmpui-ui-settings-panel-page, .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay p { + display: block +} + +.bmpui-ui-settings-panel-page .bmpui-container-wrapper > .bmpui-ui-label { + display: inline-block; + font-size: .8em; + width: 45% +} + +.bmpui-ui-settings-panel-page .bmpui-container-wrapper > .bmpui-ui-selectbox { + margin-left: 10%; + width: 45% +} + +.bmpui-ui-settings-panel-page .bmpui-ui-settings-panel-item { + border-bottom: 1px solid hsla(0,0%,60%,.3); + padding: .5em 0; + white-space: nowrap +} + + .bmpui-ui-listbox .bmpui-ui-listbox-button:last-child, .bmpui-ui-settings-panel-page .bmpui-ui-settings-panel-item.bmpui-last { + border-bottom: 0 + } + +.bmpui-ui-settingspanelpageopenbutton { + max-height: .8em; + padding: .3em 0; + vertical-align: bottom +} + +.bmpui-on.bmpui-ui-settingspanelpageopenbutton, .bmpui-ui-settingstogglebutton.bmpui-on { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st1{fill:%231fabe2}%3C/style%3E%3Cpath class='st1' d='M23.6 12.9c-.5-1.1-.7-2.2-1.4-3-.9-.9-2.2-1.2-3.3-1.6-1-.4-1.7-1-2.9-1s-2.1.7-3.2 1.1c-1.1.5-2.1.7-3 1.4-.9.8-1 1.8-1.4 2.9-.4 1.1-1.1 2-1.1 3.3s.6 2 1 3.1c.5 1.1.8 2.3 1.6 3.1.8.8 1.8 1 2.9 1.4 1.1.4 2 1.1 3.2 1.1s2.3-.7 3.4-1.2c1.1-.4 1.9-.6 2.8-1.4.9-.9 1.1-1.9 1.4-3.1.4-1 1.2-2 1.2-3.1-.1-1.1-.8-2-1.2-3zm-7.6 7c-2.1 0-3.9-1.7-3.9-3.9s1.7-3.9 3.9-3.9 3.9 1.7 3.9 3.9-1.8 3.9-3.9 3.9z' id='Ellipse_1_copy' style='opacity:.302'/%3E%3Cpath class='st1' d='m25.6 13.8-1.4-.3c-.2-.5-.4-1-.6-1.4l.9-1.3c.4-.5.3-1.3-.1-1.7L23 7.7c-.3-.3-.6-.4-1-.4-.3 0-.6.1-.8.3l-1.2.9c-.5-.3-1-.5-1.5-.6l-.3-1.4c0-.6-.6-1.1-1.3-1.1H15c-.7 0-1.2.5-1.3 1.1L13.5 8c-.5.2-1 .4-1.4.6l-1.3-.9c-.2-.2-.5-.3-.8-.3-.4 0-.7.1-1 .4L7.8 9.1c-.5.5-.5 1.2-.1 1.7l.9 1.3c-.3.5-.5 1-.6 1.4l-1.4.3c-.7 0-1.2.6-1.2 1.3V17c0 .7.5 1.2 1.1 1.3l1.5.2c.2.5.4 1 .6 1.4l-.9 1.3c-.4.5-.3 1.3.1 1.7l1.4 1.4c.3.3.6.4 1 .4.3 0 .6-.1.8-.3l1.3-.9c.5.2 1 .4 1.4.6l.3 1.4c.1.7.7 1.1 1.3 1.1H17c.7 0 1.2-.5 1.3-1.1l.3-1.4c.5-.2 1-.4 1.4-.6l1.3.9c.2.2.5.3.8.3.4 0 .7-.1 1-.4l1.4-1.4c.5-.5.5-1.2.1-1.7L23.5 20c.3-.5.5-1 .6-1.4l1.4-.3c.7-.1 1.1-.7 1.1-1.3v-2c0-.5-.5-1.1-1-1.2zm-1 3.1c0 .1 0 .1 0 0l-1.8.4c-.2 0-.4.2-.4.4-.2.6-.4 1.2-.7 1.6-.1.2-.1.4 0 .6l1 1.4v.1l-1.2 1.2h-.2l-1.4-1c-.2-.1-.4-.1-.6 0-.5.3-1.1.6-1.6.7-.2.1-.4.2-.4.4l-.3 1.8c0 .1-.1.1-.1.1h-1.7c-.1 0-.1 0-.1-.1l-.3-1.7c0-.2-.2-.4-.4-.4-.6-.2-1.2-.4-1.6-.7-.1 0-.2-.1-.3-.1-.1 0-.2 0-.3.1l-1.4 1h-.2l-1.2-1.2v-.1l1-1.4c.1-.2.1-.4 0-.6-.4-.4-.7-1-.8-1.6-.1-.2-.2-.4-.4-.4L7.5 17c-.1 0-.1-.1-.1-.1v-1.7c0-.1 0-.1.1-.1l1.7-.2c.2 0 .4-.2.5-.4.2-.6.4-1.2.7-1.6.1-.2.1-.4 0-.6l-1-1.4v-.1l1.2-1.2h.2l1.4 1c.2.1.4.1.6 0 .5-.3 1.1-.6 1.6-.7.2-.1.4-.2.4-.4l.2-2c0-.1.1-.1.1-.1h1.7c.1 0 .1 0 .1.1l.2 1.7c0 .2.2.4.4.5.6.2 1.2.4 1.7.7.2.1.4.1.6 0l1.4-1h.2l1.2 1.2v.1l-1 1.4c-.1.2-.1.4 0 .6.3.5.6 1.1.7 1.6.1.2.2.4.4.4l1.6.3c.1 0 .1.1.1.1v1.8h.2zM16 11.5c-2.5 0-4.5 2-4.5 4.5s2 4.5 4.5 4.5 4.5-2 4.5-4.5-2-4.5-4.5-4.5zm0 7.3c-1.5 0-2.8-1.3-2.8-2.8s1.3-2.8 2.8-2.8 2.8 1.3 2.8 2.8-1.3 2.8-2.8 2.8z' id='Shape_4_1_'/%3E%3C/svg%3E") +} + +.bmpui-ui-settingspanelpagebackbutton { + font-size: .8em; + position: relative; + width: 8em +} + + .bmpui-ui-settingspanelpagebackbutton .bmpui-label, .bmpui-ui-subtitlesettingsresetbutton .bmpui-label { + display: inline-block + } + + .bmpui-ui-settingspanelpagebackbutton .bmpui-label:before { + border-bottom: .2em solid #fff; + border-left: .2em solid #fff; + content: ""; + height: .6em; + margin-left: -.8em; + position: absolute; + top: .6em; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + width: .6em + } + +.bmpui-on.bmpui-ui-audiotracksettingstogglebutton:hover, .bmpui-on.bmpui-ui-settingstogglebutton:hover, .bmpui-on.bmpui-ui-subtitlesettingstogglebutton:hover { + -webkit-filter: drop-shadow(0 0 1px #1fabe2); + filter: drop-shadow(0 0 1px #1fabe2) +} + +.bmpui-ui-selectbox { + background-color: transparent; + border: 0; + color: #1fabe2; + cursor: pointer; + font-size: .8em; + padding: .3em +} + + .bmpui-ui-selectbox option { + color: #999 + } + + .bmpui-ui-selectbox option:checked { + color: #1fabe2 + } + +.bmpui-ui-listbox .bmpui-ui-listbox-button { + -webkit-box-sizing: border-box; + box-sizing: border-box; + display: block; + font-size: .8em; + height: 100%; + min-width: 10em; + padding: .5em; + width: 100% +} + + .bmpui-ui-listbox .bmpui-ui-listbox-button .bmpui-label, .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-button-ad-skip .bmpui-label { + display: inherit + } + + .bmpui-ui-listbox .bmpui-ui-listbox-button.bmpui-selected { + background-color: rgba(31,171,226,.7) + } + + .bmpui-ui-listbox .bmpui-ui-listbox-button:hover { + background-color: rgba(31,171,226,.85) + } + +.bmpui-ui-seekbar-label { + bottom: 100%; + left: 0; + margin-bottom: 1em; + pointer-events: none; + position: absolute; + text-align: center; + transition: opacity .3s,visibility +} + + .bmpui-ui-seekbar-label > .bmpui-container-wrapper { + margin-left: -50%; + margin-right: 50%; + position: relative + } + + .bmpui-ui-seekbar-label .bmpui-seekbar-label-inner { + border-bottom: .2em solid #fff + } + + .bmpui-ui-seekbar-label .bmpui-seekbar-label-inner:after { + border: .5em solid transparent; + border-top-color: #fff; + content: " "; + height: 0; + left: 50%; + margin-left: -.5em; + pointer-events: none; + position: absolute; + top: 100%; + width: 0 + } + + .bmpui-ui-seekbar-label .bmpui-seekbar-label-inner > .bmpui-container-wrapper { + position: relative + } + + .bmpui-ui-seekbar-label .bmpui-seekbar-label-inner > .bmpui-container-wrapper .bmpui-seekbar-thumbnail { + width: 6em + } + + .bmpui-ui-seekbar-label .bmpui-seekbar-label-inner > .bmpui-container-wrapper .bmpui-seekbar-label-metadata { + background: -webkit-gradient(linear,left top,left bottom,from(transparent),to(rgba(0,0,0,.7))); + background: linear-gradient(180deg,transparent,rgba(0,0,0,.7)); + bottom: 0; + -webkit-box-sizing: border-box; + box-sizing: border-box; + display: block; + padding: .5em; + position: absolute; + width: 100% + } + + .bmpui-ui-seekbar-label .bmpui-seekbar-label-inner > .bmpui-container-wrapper .bmpui-seekbar-label-metadata .bmpui-seekbar-label-time { + display: block; + line-height: .8em + } + + .bmpui-ui-seekbar-label .bmpui-seekbar-label-inner > .bmpui-container-wrapper .bmpui-seekbar-label-metadata .bmpui-seekbar-label-title { + display: block; + margin-bottom: .3em; + white-space: normal + } + +.bmpui-ui-seekbar, .bmpui-ui-volumeslider { + cursor: pointer; + font-size: 1em; + height: 1em; + position: relative; + width: 100% +} + + .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-backdrop, .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-bufferlevel, .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-markers, .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-markers > .bmpui-seekbar-marker, .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-playbackposition, .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-playbackposition-marker, .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-seekposition, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-backdrop, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-bufferlevel, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-markers, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-markers > .bmpui-seekbar-marker, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-playbackposition, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-playbackposition-marker, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-seekposition { + bottom: 0; + -webkit-box-sizing: border-box; + box-sizing: border-box; + height: .3125em; + left: 0; + margin: auto; + position: absolute; + right: auto; + top: 0; + -ms-transform-origin: 0 0; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + width: 100% + } + + .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-backdrop, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-backdrop { + background-color: hsla(0,0%,100%,.2); + margin: auto 0; + width: 100% + } + + .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-bufferlevel, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-bufferlevel { + background-color: #fff; + margin: auto 0; + -webkit-transition: -webkit-transform .3s linear,_ .3s linear; + transition: transform .3s linear,-webkit-transform .3s linear + } + + .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-seekposition, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-seekposition { + background-color: hsla(0,0%,100%,.2); + margin: auto 0 + } + + .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-playbackposition, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-playbackposition { + background-color: #004f88; + margin: auto 0; + -webkit-transition: -webkit-transform .1s linear,_ .1s linear; + transition: transform .1s linear,-webkit-transform .1s linear + } + + .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-playbackposition-marker, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-playbackposition-marker { + background-color: #004f88; + border: .1875em solid #004f88; + border-radius: 50%; + height: .9375em; + left: -.46875em; + width: .9375em + } + + .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-markers, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-markers { + height: .5625em + } + + .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-markers > .bmpui-seekbar-marker, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-markers > .bmpui-seekbar-marker { + background-color: #fff; + height: 100%; + text-align: center; + -webkit-transition-duration: 1s; + transition-duration: 1s; + -webkit-transition-property: -webkit-transform; + transition-property: transform,-webkit-transform; + -webkit-transition-timing-function: linear; + transition-timing-function: linear; + width: 2px + } + + .bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-markers > .bmpui-seekbar-marker > .bmpui-seekbar-marker-image, .bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-markers > .bmpui-seekbar-marker > .bmpui-seekbar-marker-image { + height: 1.25em; + position: absolute; + -webkit-transform: translate(-50%,calc(-100% - .2em)); + transform: translate(-50%,calc(-100% - .2em)) + } + +.bmpui-seeking.bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-bufferlevel, .bmpui-seeking.bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-playbackposition, .bmpui-seeking.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-bufferlevel, .bmpui-seeking.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-playbackposition, .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-seekbar-bufferlevel, .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-seekbar-playbackposition, .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-buffering-overlay, .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-controlbar, .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay, .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-titlebar { + -webkit-transition: none; + transition: none +} + +.bmpui-vertical.bmpui-ui-seekbar .bmpui-seekbar, .bmpui-vertical.bmpui-ui-volumeslider .bmpui-seekbar { + height: 100%; + width: auto +} + + .bmpui-vertical.bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-backdrop, .bmpui-vertical.bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-bufferlevel, .bmpui-vertical.bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-playbackposition, .bmpui-vertical.bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-seekposition, .bmpui-vertical.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-backdrop, .bmpui-vertical.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-bufferlevel, .bmpui-vertical.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-playbackposition, .bmpui-vertical.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-seekposition { + right: 0; + top: auto + } + + .bmpui-vertical.bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-playbackposition .bmpui-seekbar-playbackposition-marker, .bmpui-vertical.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-playbackposition .bmpui-seekbar-playbackposition-marker { + height: 1em; + top: -.5em; + width: 100% + } + + .bmpui-vertical.bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-backdrop, .bmpui-vertical.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-backdrop { + height: 100%; + margin: 0 auto; + width: auto + } + + .bmpui-vertical.bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-bufferlevel, .bmpui-vertical.bmpui-ui-seekbar .bmpui-seekbar .bmpui-seekbar-seekposition, .bmpui-vertical.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-bufferlevel, .bmpui-vertical.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-seekposition { + margin: 0 auto + } + +.bmpui-ui-volumeslider .bmpui-seekbar .bmpui-seekbar-playbackposition-marker { + background-color: #1fabe2; + border: 0; + height: .6875em; + left: -.34375em; + width: .6875em +} + +.bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay { + bottom: 0; + font-size: 1.2em; + left: 0; + pointer-events: none; + position: absolute; + right: 0; + text-align: center; + top: 0; + -webkit-transition: bottom .15s ease-out; + transition: bottom .15s ease-out +} + + .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay * { + all: unset + } + + .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay .bmpui-subtitle-region-container { + position: absolute + } + + .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay .bmpui-subtitle-region-container.bmpui-subtitle-position-default { + bottom: 2em; + left: 3em; + right: 3em; + top: auto + } + + .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay .bmpui-subtitle-region-container.bmpui-subtitle-position-bottom > div { + bottom: 0; + position: absolute; + width: 100% + } + + .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay .bmpui-ui-subtitle-label { + color: #fff; + height: -webkit-fit-content; + height: -moz-fit-content; + height: fit-content; + text-shadow: -1px -1px 0 #000,0 -1px 0 #000,1px -1px 0 #000,-1px 0 0 #000,1px 0 0 #000,-1px 1px 0 #000,0 1px 0 #000,1px 1px 0 #000 + } + + .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay .bmpui-ui-subtitle-label:nth-child(1n-1):after { + content: "\a"; + height: 0; + white-space: pre-line; + width: 0 + } + + .bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay.bmpui-controlbar-visible { + bottom: 5em; + -webkit-transition: bottom .15s ease-in; + transition: bottom .15s ease-in + } + +.bmpui-ui-subtitle-overlay.bmpui-cea608 { + bottom: 2em; + left: 3em; + right: 3em; + top: 2em +} + + .bmpui-ui-subtitle-overlay.bmpui-cea608 .bmpui-subtitle-region-container.bmpui-subtitle-position-default { + bottom: 0; + left: 0; + right: 0; + top: 0 + } + + .bmpui-ui-subtitle-overlay.bmpui-cea608 .bmpui-ui-subtitle-label { + line-height: 1em; + position: absolute; + text-transform: uppercase + } + + .bmpui-ui-subtitle-overlay.bmpui-cea608 .bmpui-ui-subtitle-label:nth-child(1n-1):after { + content: normal; + white-space: normal + } + + .bmpui-ui-subtitle-overlay.bmpui-cea608.bmpui-controlbar-visible { + bottom: 2em; + -webkit-transition: none; + transition: none + } + +.bmpui-ui-volumecontrolbutton { + line-height: 0; + position: relative +} + + .bmpui-ui-volumecontrolbutton .bmpui-ui-volumeslider { + background-color: #111; + bottom: 100%; + height: 6em; + max-height: 6em; + position: absolute; + -webkit-transition: max-height .15s ease-in; + transition: max-height .15s ease-in; + width: 1.5em + } + + .bmpui-ui-volumecontrolbutton .bmpui-ui-volumeslider.bmpui-hidden { + max-height: 0; + -webkit-transition: max-height .15s ease-out; + transition: max-height .15s ease-out + } + + .bmpui-ui-volumecontrolbutton .bmpui-ui-volumeslider .bmpui-seekbar { + bottom: .5em; + height: auto; + left: .3em; + overflow: hidden; + position: absolute; + right: .3em; + top: .5em; + width: auto + } + +.bmpui-ui-casttogglebutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M27.7 5.4H6.4c-1.2 0-2.1 1-2.1 2.1v2.1h2.1V7.5h21.3v12.8h-8.5v2.1h8.5c1.2 0 2.1-1 2.1-2.1V7.5c0-1.2-.9-2.1-2.1-2.1z' id='Rectangle_9_copy'/%3E%3Cpath class='st0' d='M2.2 12.8v2.1c6.5 0 11.7 5.2 11.7 11.7H16C16 19 9.8 12.8 2.2 12.8zm0 5.3v2.1c3.5 0 6.4 2.9 6.4 6.4h2.1c0-4.6-3.8-8.5-8.5-8.5zm0 5.3v3.2h3.2c0-1.8-1.4-3.2-3.2-3.2z' id='Rectangle_12'/%3E%3C/svg%3E") +} + + .bmpui-ui-casttogglebutton.bmpui-on { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st1{fill:%231fabe2}%3C/style%3E%3Cpath class='st1' d='M6.4 7.5v3.3c5.3.6 9.7 4.5 11.2 9.5h10.1V7.5H6.4z' id='Ellipse_1' style='opacity:.302'/%3E%3Cpath class='st1' d='M2.2 23.4v3.2h3.2c0-1.8-1.4-3.2-3.2-3.2zm0-5.3v2.1c3.5 0 6.4 2.9 6.4 6.4h2.1c0-4.6-3.8-8.5-8.5-8.5zm0-5.3v2.1c6.5 0 11.7 5.2 11.7 11.7H16C16 19 9.8 12.8 2.2 12.8zm25.5-7.4H6.4c-1.2 0-2.1 1-2.1 2.1v2.1h2.1V7.5h21.3v12.8h-8.5v2.1h8.5c1.2 0 2.1-1 2.1-2.1V7.5c0-1.2-.9-2.1-2.1-2.1z' id='Rectangle_12_2_'/%3E%3C/svg%3E") + } + +.bmpui-ui-cast-status-overlay { + background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M27.7 5.4H6.4c-1.2 0-2.1 1-2.1 2.1v2.1h2.1V7.5h21.3v12.8h-8.5v2.1h8.5c1.2 0 2.1-1 2.1-2.1V7.5c0-1.2-.9-2.1-2.1-2.1z' id='Rectangle_9_copy'/%3E%3Cpath class='st0' d='M2.2 12.8v2.1c6.5 0 11.7 5.2 11.7 11.7H16C16 19 9.8 12.8 2.2 12.8zm0 5.3v2.1c3.5 0 6.4 2.9 6.4 6.4h2.1c0-4.6-3.8-8.5-8.5-8.5zm0 5.3v3.2h3.2c0-1.8-1.4-3.2-3.2-3.2z' id='Rectangle_12'/%3E%3C/svg%3E") 50%/7em 7em no-repeat #111; + height: 100%; + left: 0; + margin: 0; + position: absolute; + top: 0; + transition: opacity .3s,visibility; + width: 100% +} + + .bmpui-ui-cast-status-overlay .bmpui-ui-cast-status-label { + color: #fff; + font-size: 1.2em; + left: 0; + margin: 0 2em; + pointer-events: none; + position: absolute; + right: 0; + text-align: center; + top: 65% + } + +.bmpui-ui-errormessage-overlay { + background-color: #111; + height: 100%; + left: 0; + margin: 0; + pointer-events: none; + position: absolute; + top: 0; + width: 100% +} + + .bmpui-ui-errormessage-overlay .bmpui-ui-errormessage-label { + color: #fff; + font-size: 1.2em; + left: 3em; + position: absolute; + right: 3em; + text-align: center; + top: 50%; + -ms-transform: translateY(-50%); + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + white-space: pre-line + } + + .bmpui-ui-errormessage-overlay .bmpui-ui-errormessage-label ul { + color: #999; + font-size: .9em; + padding: 0 + } + + .bmpui-ui-errormessage-overlay .bmpui-ui-errormessage-label ul li { + list-style: none + } + + .bmpui-ui-errormessage-overlay .bmpui-ui-tvnoisecanvas { + -webkit-filter: blur(4px); + filter: blur(4px); + height: 100%; + left: 0; + margin: 0; + position: absolute; + top: 0; + width: 100% + } + +.bmpui-ui-titlebar { + background: -webkit-gradient(linear,left bottom,left top,from(transparent),to(rgba(0,0,0,.7))); + background: linear-gradient(0deg,transparent,rgba(0,0,0,.7)); + -webkit-box-sizing: border-box; + box-sizing: border-box; + opacity: 1; + padding: .5em 1em 1em; + pointer-events: none; + position: absolute; + top: 0; + -webkit-transition: opacity .3s,visibility; + transition: opacity .3s,visibility; + width: 100% +} + +.bmpui-ui-buffering-overlay, .bmpui-ui-recommendation-overlay { + display: table; + background-color: rgba(8,43,57,.7); + left: 0; + margin: 0; + opacity: 1; + top: 0; + visibility: visible +} + +.bmpui-ui-titlebar > .bmpui-container-wrapper { + padding: .5em; + pointer-events: none +} + + .bmpui-ui-titlebar > .bmpui-container-wrapper .bmpui-label-metadata-title { + cursor: default; + display: block; + font-size: 1.2em; + text-shadow: 0 0 5px #000; + white-space: normal + } + + .bmpui-ui-titlebar > .bmpui-container-wrapper .bmpui-label-metadata-description { + color: #e6e6e6; + cursor: default; + display: block; + text-shadow: 0 0 5px #000; + white-space: normal + } + +.bmpui-ui-recommendation-overlay { + height: 100%; + position: absolute; + -webkit-transition: opacity .6s,visibility; + transition: opacity .6s,visibility; + width: 100% +} + + .bmpui-ui-buffering-overlay > .bmpui-container-wrapper, .bmpui-ui-recommendation-overlay > .bmpui-container-wrapper { + display: table-cell; + text-align: center; + vertical-align: middle; + padding: 3em + } + + .bmpui-ui-buffering-overlay.bmpui-hidden, .bmpui-ui-recommendation-overlay.bmpui-hidden { + opacity: 0; + -webkit-transition: opacity .6s,visibility .6s; + transition: opacity .6s,visibility .6s; + visibility: hidden + } + + .bmpui-ui-buffering-overlay a, .bmpui-ui-buffering-overlay a:hover, .bmpui-ui-buffering-overlay a:visited, .bmpui-ui-recommendation-overlay a, .bmpui-ui-recommendation-overlay a:hover, .bmpui-ui-recommendation-overlay a:visited, .bmpui-ui-subtitle-overlay.bmpui-fontcolor-white100 .bmpui-ui-subtitle-label { + color: #fff + } + + .bmpui-ui-recommendation-overlay.bmpui-recommendations .bmpui-ui-hugereplaybutton { + bottom: 2em; + left: 2em; + position: absolute + } + + .bmpui-ui-recommendation-overlay.bmpui-recommendations .bmpui-ui-recommendation-item { + background-position: 50%; + background-size: cover; + display: inline-block; + font-size: .7em; + height: 9em; + margin: .3em .6em; + overflow: hidden; + position: relative; + text-align: left; + text-shadow: 0 0 3px #111; + -webkit-transform: scale(1); + transform: scale(1); + -webkit-transition: -webkit-transform .15s ease-out; + transition: transform .15s ease-out; + transition: transform .15s ease-out,-webkit-transform .15s ease-out; + width: 16em + } + + .bmpui-ui-recommendation-overlay.bmpui-recommendations .bmpui-ui-recommendation-item .bmpui-background { + background: -webkit-gradient(linear,left top,left bottom,from(transparent),color-stop(transparent),to(rgba(0,0,0,.7))); + background: linear-gradient(180deg,transparent,transparent,rgba(0,0,0,.7)); + height: 100%; + position: absolute; + top: 20%; + -webkit-transition: top .15s ease-out; + transition: top .15s ease-out; + width: 100% + } + +.bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-hugeplaybacktogglebutton .bmpui-image, .bmpui-ui-skin-smallscreen.bmpui-remote-control .bmpui-ui-hugeplaybacktogglebutton.bmpui-on .bmpui-image { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M11.3 5.4H8.9c-1.3 0-2.4 1.1-2.4 2.4v16.5c0 1.3 1.1 2.4 2.4 2.4h2.4c1.3 0 2.4-1.1 2.4-2.4V7.7c-.1-1.3-1.1-2.3-2.4-2.3zm0 18.9H8.9V7.7h2.4v16.6z' id='Rectangle_2_copy'/%3E%3Cpath class='st0' d='M23.1 5.4h-2.4c-1.3 0-2.4 1.1-2.4 2.4v16.5c0 1.3 1.1 2.4 2.4 2.4h2.4c1.3 0 2.4-1.1 2.4-2.4V7.7c-.1-1.3-1.1-2.3-2.4-2.3zm0 18.9h-2.4V7.7h2.4v16.6z' id='Rectangle_2_copy_2'/%3E%3C/svg%3E") +} + +.bmpui-ui-recommendation-overlay.bmpui-recommendations .bmpui-ui-recommendation-item .bmpui-title { + bottom: 3em; + left: 1em; + position: absolute; + right: 1em +} + + .bmpui-ui-recommendation-overlay.bmpui-recommendations .bmpui-ui-recommendation-item .bmpui-title .bmpui-innertitle { + font-size: 1.2em; + white-space: normal; + word-break: break-all + } + +.bmpui-ui-recommendation-overlay.bmpui-recommendations .bmpui-ui-recommendation-item .bmpui-duration { + bottom: 1em; + left: 1em; + position: absolute +} + +.bmpui-ui-recommendation-overlay.bmpui-recommendations .bmpui-ui-recommendation-item:hover { + outline: #1fabe2 solid 2px; + -webkit-transform: scale(1.05); + transform: scale(1.05); + -webkit-transition: -webkit-transform .15s ease-in; + transition: transform .15s ease-in; + transition: transform .15s ease-in,-webkit-transform .15s ease-in +} + + .bmpui-ui-recommendation-overlay.bmpui-recommendations .bmpui-ui-recommendation-item:hover .bmpui-background { + top: 0; + -webkit-transition: top .15s ease-in; + transition: top .15s ease-in + } + +.bmpui-ui-clickoverlay, .bmpui-ui-playbacktoggle-overlay .bmpui-ui-hugeplaybacktogglebutton { + height: 100%; + left: 0; + margin: 0; + position: absolute; + top: 0; + width: 100% +} + +.bmpui-ui-hugereplaybutton { + height: 5em; + outline: 0; + width: 5em +} + + .bmpui-ui-hugereplaybutton .bmpui-image { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 80' style='enable-background:new 0 0 80 80' xml:space='preserve'%3E%3Cstyle%3E.st1{fill:%231fabe2}%3C/style%3E%3Cpath d='M40 73.5c-18.5 0-33.5-15-33.5-33.5S21.5 6.5 40 6.5s33.5 15 33.5 33.5-15 33.5-33.5 33.5z' style='opacity:.3;fill:%231fabe2'/%3E%3Cpath class='st1' d='M40 5C20.7 5 5 20.7 5 40s15.7 35 35 35 35-15.7 35-35S59.3 5 40 5zm0 67C22.3 72 8 57.7 8 40S22.3 8 40 8s32 14.3 32 32-14.3 32-32 32z' id='Ellipse_3_copy_2'/%3E%3Cpath class='st1' d='M54 40.3V40h-.1c-.2-.6-.8-1-1.4-1s-1.2.4-1.4 1H51c0 6.1-4.9 11-11 11s-11-4.9-11-11 4.9-11 11-11c.7 0 1.4.1 2 .2v3.3c0 .2.1.3.3.4.1 0 .2.1.3.1s.2 0 .3-.1l7.8-4.5c.2-.1.2-.2.2-.4s-.1-.3-.2-.4l-7.8-4.5c-.2-.1-.4-.1-.6 0-.2.1-.3.2-.3.4v2.7c-.7-.1-1.3-.2-2-.2-7.7 0-14 6.3-14 14s6.3 14 14 14c7.4 0 13.5-5.8 14-13.2v-.5z' id='Ellipse_3'/%3E%3C/svg%3E"); + background-position: 50%; + background-repeat: no-repeat; + background-size: 5em; + height: 100%; + width: 100% + } + +@-webkit-keyframes spin { + 50% { + -webkit-transform: rotate(180deg) scale(1.1); + transform: rotate(180deg) scale(1.1) + } + + to { + -webkit-transform: rotate(1turn) scale(1); + transform: rotate(1turn) scale(1) + } +} + +@keyframes spin { + 50% { + -webkit-transform: rotate(180deg) scale(1.1); + transform: rotate(180deg) scale(1.1) + } + + to { + -webkit-transform: rotate(1turn) scale(1); + transform: rotate(1turn) scale(1) + } +} + +.bmpui-ui-hugereplaybutton .bmpui-image:hover { + -webkit-animation: .5s ease-in spin; + animation: .5s ease-in spin +} + +.bmpui-ui-replaybutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cpath d='M22.8 9.1c-3.8-3.9-10.1-4-14.1-.2V7.1c0-.6-.4-1-1-1s-1 .4-1 1v4.5c0 .6.4 1 1 1h4.5c.6 0 1-.4 1-1s-.4-1-1-1H9.8c1.6-1.6 3.7-2.5 5.9-2.5 4.4 0 8 3.7 8 8.1s-3.7 8-8.1 8c-3.5 0-6.5-2.3-7.6-5.4-.1-.4-.5-.8-.9-.8-.5 0-1 .4-1 1 0 .1 0 .2.1.3.5 1.3 1.2 2.5 2.2 3.5 3.8 4 10.1 4.1 14.1.3 4-3.6 4.1-9.9.3-14z' style='fill:%23fff'/%3E%3C/svg%3E") +} + +.bmpui-ui-playbacktimelabel { + text-transform: uppercase +} + + .bmpui-ui-playbacktimelabel.bmpui-ui-playbacktimelabel-live { + cursor: pointer + } + + .bmpui-ui-playbacktimelabel.bmpui-ui-playbacktimelabel-live:before { + color: #999; + content: "●"; + padding-right: .2em + } + + .bmpui-ui-playbacktimelabel.bmpui-ui-playbacktimelabel-live.bmpui-ui-playbacktimelabel-live-edge:before, .bmpui-ui-subtitle-overlay.bmpui-fontcolor-red100 .bmpui-ui-subtitle-label { + color: red + } + +.bmpui-ui-buffering-overlay { + height: 100%; + position: absolute; + -webkit-transition: opacity .6s,visibility; + transition: opacity .6s,visibility; + width: 100% +} + + .bmpui-ui-buffering-overlay .bmpui-ui-buffering-overlay-indicator { + -webkit-animation: 2s ease-in infinite fancy; + animation: 2s ease-in infinite fancy; + background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st1{fill-rule:evenodd;clip-rule:evenodd;fill:%23004F88}%3C/style%3E%3Cpath class='st1' d='M8 8h16v16H8z' id='Rectangle_3_copy_3' style='opacity:.302'/%3E%3Cpath class='st1' d='M23 7H9c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zm0 16H9V9h14v14z' id='Rectangle_2_copy_13'/%3E%3C/svg%3E") 50% no-repeat; + display: inline-block; + height: 2em; + margin: .2em; + width: 2em + } + +@-webkit-keyframes fancy { + 0% { + opacity: 0; + -webkit-transform: scale(1); + transform: scale(1) + } + + 20%,30% { + opacity: 1 + } + + 50% { + opacity: 0; + -webkit-transform: scale(2); + transform: scale(2) + } + + to { + opacity: 0; + -webkit-transform: scale(3); + transform: scale(3) + } +} + +@keyframes fancy { + 0% { + opacity: 0; + -webkit-transform: scale(1); + transform: scale(1) + } + + 20%,30% { + opacity: 1 + } + + 50% { + opacity: 0; + -webkit-transform: scale(2); + transform: scale(2) + } + + to { + opacity: 0; + -webkit-transform: scale(3); + transform: scale(3) + } +} + +.bmpui-ui-buffering-overlay .bmpui-ui-buffering-overlay-indicator:first-child { + -webkit-animation-delay: 0s; + animation-delay: 0s +} + +.bmpui-ui-buffering-overlay .bmpui-ui-buffering-overlay-indicator:nth-child(2) { + -webkit-animation-delay: .2s; + animation-delay: .2s +} + +.bmpui-ui-buffering-overlay .bmpui-ui-buffering-overlay-indicator:nth-child(3) { + -webkit-animation-delay: .4s; + animation-delay: .4s +} + +.bmpui-ui-closebutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M26 6c-.9-.9-2.2-.9-3.1 0L6 22.8c-.9.9-.9 2.2 0 3.1.9.9 2.2.9 3.1 0L26 9.2c.9-.9.9-2.3 0-3.2z' id='Rounded_Rectangle_6'/%3E%3Cpath class='st0' d='M26 22.8 9.2 6c-.9-.9-2.2-.9-3.1 0s-.9 2.2 0 3.1L23 26c.9.9 2.2.9 3.1 0 .8-.9.8-2.3-.1-3.2z' id='Rounded_Rectangle_6_copy'/%3E%3C/svg%3E") +} + +@-webkit-keyframes pulsate { + 20%,60% { + -webkit-transform: scale(1.1); + transform: scale(1.1) + } + + 40%,80% { + -webkit-transform: scale(1); + transform: scale(1) + } +} + +@keyframes pulsate { + 20%,60% { + -webkit-transform: scale(1.1); + transform: scale(1.1) + } + + 40%,80% { + -webkit-transform: scale(1); + transform: scale(1) + } +} + +.bmpui-ui-closebutton:hover { + -webkit-animation: 1s pulsate; + animation: 1s pulsate; + -webkit-filter: drop-shadow(0 0 1px #fff); + filter: drop-shadow(0 0 1px #fff) +} + +.bmpui-ui-airplaytogglebutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M27.1 5.3H4.9c-1.3 0-2.4 1.1-2.4 2.4v11.9c0 1.3 1.1 2.4 2.4 2.4h3.6v-2.4H4.9V7.7H27v11.9h-3.6V22H27c1.3 0 2.4-1.1 2.4-2.4V7.7c0-1.3-1-2.4-2.3-2.4z' id='Rectangle_8'/%3E%3Cpath class='st0' d='M22.9 24.8 17 16.5c-.2-.2-.6-.5-1-.5s-.7.2-1 .5l-5.9 8.3c-.2.4-.2.8-.1 1.2.2.4.6.6 1.1.6H22c.5 0 .8-.2 1.1-.6.1-.1.1-.2.1-.5-.1-.2-.2-.5-.3-.7zm-10.6-.5 3.7-5.1 3.7 5.1h-7.4z' id='Shape_5'/%3E%3C/svg%3E") +} + + .bmpui-ui-airplaytogglebutton.bmpui-on { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{opacity:.302}.st1{fill:%231fabe2}%3C/style%3E%3Cg id='Rectangle_17' class='st0'%3E%3Cpath class='st1' d='M4.9 7.7H27v11.9H4.9z'/%3E%3C/g%3E%3Cg id='Rectangle_18' class='st0'%3E%3Cpath class='st1' d='M18.4 19.6h-4.8l-2.4 4.7h9.6z'/%3E%3C/g%3E%3Cpath class='st1' d='M27.1 5.3H4.9c-1.3 0-2.4 1.1-2.4 2.4v11.9c0 1.3 1.1 2.4 2.4 2.4h3.6v-2.4H4.9V7.7H27v11.9h-3.6V22H27c1.3 0 2.4-1.1 2.4-2.4V7.7c0-1.3-1-2.4-2.3-2.4zM17 16.5c-.2-.2-.6-.5-1-.5s-.7.2-1 .5l-5.9 8.3c-.2.4-.2.8-.1 1.2.2.4.6.6 1.1.6H22c.5 0 .8-.2 1.1-.6.1-.1.1-.2.1-.5 0-.2-.1-.5-.2-.7l-6-8.3zm-4.7 7.8 3.7-5.1 3.7 5.1h-7.4z' id='Shape_5_1_'/%3E%3C/svg%3E") + } + +.bmpui-ui-piptogglebutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st0{fill-rule:evenodd;clip-rule:evenodd;fill:%23fff}%3C/style%3E%3Cpath class='st0' d='M5 8.3h19.8v5.5H27V8.3c0-1.2-1-2.2-2.2-2.2H5c-1.2 0-2.2 1-2.2 2.2v12.1c0 1.2 1 2.2 2.2 2.2h7.7v-2.2H5V8.3zm9.9 7.7v9.9h14.3V16H14.9z' id='Rectangle_512'/%3E%3Cpath class='st0' d='M12.7 10.5H7.2V16h2.2v-3.3h3.3z' id='Rectangle_513'/%3E%3C/svg%3E") +} + + .bmpui-ui-piptogglebutton.bmpui-on { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cstyle%3E.st1{fill-rule:evenodd;clip-rule:evenodd;fill:%231fabe2}%3C/style%3E%3Cpath class='st1' d='M5 8.3h19.8v12.1H5z' id='Rectangle_515_2_' style='opacity:.302'/%3E%3Cpath class='st1' d='M5 8.3h19.8v5.5H27V8.3c0-1.2-1-2.2-2.2-2.2H5c-1.2 0-2.2 1-2.2 2.2v12.1c0 1.2 1 2.2 2.2 2.2h7.7v-2.2H5V8.3zm9.9 7.7v9.9h14.3V16H14.9z' id='Rectangle_512_12_'/%3E%3Cpath class='st1' d='M12.7 10.5H7.2V16h2.2v-3.3h3.3z' id='Rectangle_513_12_'/%3E%3C/svg%3E") + } + +.bmpui-ui-spacer { + height: 100%; + width: 100% +} + +.bmpui-ui-subtitlesettingsresetbutton { + font-size: .8em; + width: 12em +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-white75 .bmpui-ui-subtitle-label { + color: hsla(0,0%,100%,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-white50 .bmpui-ui-subtitle-label { + color: hsla(0,0%,100%,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-white25 .bmpui-ui-subtitle-label { + color: hsla(0,0%,100%,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-black100 .bmpui-ui-subtitle-label { + color: #000 +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-black75 .bmpui-ui-subtitle-label { + color: rgba(0,0,0,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-black50 .bmpui-ui-subtitle-label { + color: rgba(0,0,0,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-black25 .bmpui-ui-subtitle-label { + color: rgba(0,0,0,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-red75 .bmpui-ui-subtitle-label { + color: rgba(255,0,0,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-red50 .bmpui-ui-subtitle-label { + color: rgba(255,0,0,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-red25 .bmpui-ui-subtitle-label { + color: rgba(255,0,0,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-green100 .bmpui-ui-subtitle-label { + color: #0f0 +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-green75 .bmpui-ui-subtitle-label { + color: rgba(0,255,0,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-green50 .bmpui-ui-subtitle-label { + color: rgba(0,255,0,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-green25 .bmpui-ui-subtitle-label { + color: rgba(0,255,0,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-blue100 .bmpui-ui-subtitle-label { + color: #00f +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-blue75 .bmpui-ui-subtitle-label { + color: rgba(0,0,255,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-blue50 .bmpui-ui-subtitle-label { + color: rgba(0,0,255,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-blue25 .bmpui-ui-subtitle-label { + color: rgba(0,0,255,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-cyan100 .bmpui-ui-subtitle-label { + color: #0ff +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-cyan75 .bmpui-ui-subtitle-label { + color: rgba(0,255,255,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-cyan50 .bmpui-ui-subtitle-label { + color: rgba(0,255,255,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-cyan25 .bmpui-ui-subtitle-label { + color: rgba(0,255,255,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-yellow100 .bmpui-ui-subtitle-label { + color: #ff0 +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-yellow75 .bmpui-ui-subtitle-label { + color: rgba(255,255,0,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-yellow50 .bmpui-ui-subtitle-label { + color: rgba(255,255,0,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-yellow25 .bmpui-ui-subtitle-label { + color: rgba(255,255,0,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-magenta100 .bmpui-ui-subtitle-label { + color: #f0f +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-magenta75 .bmpui-ui-subtitle-label { + color: rgba(255,0,255,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-magenta50 .bmpui-ui-subtitle-label { + color: rgba(255,0,255,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontcolor-magenta25 .bmpui-ui-subtitle-label { + color: rgba(255,0,255,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-white100 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-white100 .bmpui-subtitle-region-container { + background-color: #fff +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-white75 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-white75 .bmpui-subtitle-region-container { + background-color: hsla(0,0%,100%,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-white50 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-white50 .bmpui-subtitle-region-container { + background-color: hsla(0,0%,100%,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-white25 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-white25 .bmpui-subtitle-region-container { + background-color: hsla(0,0%,100%,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-black100 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-black100 .bmpui-subtitle-region-container { + background-color: #000 +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-black75 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-black75 .bmpui-subtitle-region-container { + background-color: rgba(0,0,0,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-black50 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-black50 .bmpui-subtitle-region-container { + background-color: rgba(0,0,0,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-black25 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-black25 .bmpui-subtitle-region-container { + background-color: rgba(0,0,0,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-red100 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-red100 .bmpui-subtitle-region-container { + background-color: red +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-red75 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-red75 .bmpui-subtitle-region-container { + background-color: rgba(255,0,0,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-red50 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-red50 .bmpui-subtitle-region-container { + background-color: rgba(255,0,0,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-red25 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-red25 .bmpui-subtitle-region-container { + background-color: rgba(255,0,0,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-green100 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-green100 .bmpui-subtitle-region-container { + background-color: #0f0 +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-green75 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-green75 .bmpui-subtitle-region-container { + background-color: rgba(0,255,0,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-green50 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-green50 .bmpui-subtitle-region-container { + background-color: rgba(0,255,0,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-green25 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-green25 .bmpui-subtitle-region-container { + background-color: rgba(0,255,0,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-blue100 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-blue100 .bmpui-subtitle-region-container { + background-color: #00f +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-blue75 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-blue75 .bmpui-subtitle-region-container { + background-color: rgba(0,0,255,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-blue50 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-blue50 .bmpui-subtitle-region-container { + background-color: rgba(0,0,255,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-blue25 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-blue25 .bmpui-subtitle-region-container { + background-color: rgba(0,0,255,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-cyan100 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-cyan100 .bmpui-subtitle-region-container { + background-color: #0ff +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-cyan75 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-cyan75 .bmpui-subtitle-region-container { + background-color: rgba(0,255,255,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-cyan50 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-cyan50 .bmpui-subtitle-region-container { + background-color: rgba(0,255,255,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-cyan25 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-cyan25 .bmpui-subtitle-region-container { + background-color: rgba(0,255,255,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-yellow100 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-yellow100 .bmpui-subtitle-region-container { + background-color: #ff0 +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-yellow75 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-yellow75 .bmpui-subtitle-region-container { + background-color: rgba(255,255,0,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-yellow50 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-yellow50 .bmpui-subtitle-region-container { + background-color: rgba(255,255,0,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-yellow25 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-yellow25 .bmpui-subtitle-region-container { + background-color: rgba(255,255,0,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-magenta100 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-magenta100 .bmpui-subtitle-region-container { + background-color: #f0f +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-magenta75 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-magenta75 .bmpui-subtitle-region-container { + background-color: rgba(255,0,255,.75) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-magenta50 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-magenta50 .bmpui-subtitle-region-container { + background-color: rgba(255,0,255,.5) +} + +.bmpui-ui-subtitle-overlay.bmpui-bgcolor-magenta25 .bmpui-subtitle-region-container .bmpui-ui-subtitle-label, .bmpui-ui-subtitle-overlay.bmpui-windowcolor-magenta25 .bmpui-subtitle-region-container { + background-color: rgba(255,0,255,.25) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontsize-50 .bmpui-ui-subtitle-label { + font-size: .5em +} + +.bmpui-ui-subtitle-overlay.bmpui-fontsize-75 .bmpui-ui-subtitle-label { + font-size: .75em +} + +.bmpui-ui-subtitle-overlay.bmpui-fontsize-150 .bmpui-ui-subtitle-label { + font-size: 1.5em +} + +.bmpui-ui-subtitle-overlay.bmpui-fontsize-200 .bmpui-ui-subtitle-label { + font-size: 2em +} + +.bmpui-ui-subtitle-overlay.bmpui-fontsize-300 .bmpui-ui-subtitle-label { + font-size: 3em +} + +.bmpui-ui-subtitle-overlay.bmpui-fontsize-400 .bmpui-ui-subtitle-label { + font-size: 4em +} + +.bmpui-ui-subtitle-overlay.bmpui-characteredge-none .bmpui-ui-subtitle-label { + text-shadow: none +} + +.bmpui-ui-subtitle-overlay.bmpui-characteredge-raised .bmpui-ui-subtitle-label { + text-shadow: 0 0 4px rgba(0,0,0,.9),0 1px 4px rgba(0,0,0,.9),0 2px 4px rgba(0,0,0,.9) +} + +.bmpui-ui-subtitle-overlay.bmpui-characteredge-depressed .bmpui-ui-subtitle-label { + text-shadow: rgba(0,0,0,.8) 0 -2px 1px +} + +.bmpui-ui-subtitle-overlay.bmpui-characteredge-uniform .bmpui-ui-subtitle-label { + text-shadow: -2px 0 1px rgba(0,0,0,.8),2px 0 1px rgba(0,0,0,.8),0 -2px 1px rgba(0,0,0,.8),0 2px 1px rgba(0,0,0,.8),-1px 1px 1px rgba(0,0,0,.8),1px 1px 1px rgba(0,0,0,.8),1px -1px 1px rgba(0,0,0,.8),1px 1px 1px rgba(0,0,0,.8) +} + +.bmpui-ui-subtitle-overlay.bmpui-characteredge-dropshadowed .bmpui-ui-subtitle-label { + text-shadow: 0 2px 1px rgba(0,0,0,.8) +} + +.bmpui-ui-subtitle-overlay.bmpui-fontfamily-proportionalserif .bmpui-ui-subtitle-label { + font-family: Times New Roman,Times,Georgia,Cambria,"PT Serif Caption",serif +} + +.bmpui-ui-subtitle-overlay.bmpui-fontfamily-monospacedsansserif .bmpui-ui-subtitle-label { + font-family: Deja Vu Sans Mono,Lucida Console,Monaco,Consolas,PT Mono,monospace +} + +.bmpui-ui-subtitle-overlay.bmpui-fontfamily-proportionalsansserif .bmpui-ui-subtitle-label { + font-family: Roboto,Arial Unicode Ms,Arial,Helvetica,Verdana,PT Sans Caption,sans-serif +} + +.bmpui-ui-subtitle-overlay.bmpui-fontfamily-casual .bmpui-ui-subtitle-label { + font-family: Comic Sans MS,Impact,Handlee,fantasy +} + +.bmpui-ui-subtitle-overlay.bmpui-fontfamily-cursive .bmpui-ui-subtitle-label { + font-family: Monotype Corsiva,URW Chancery L,Apple Chancery,Dancing Script,cursive; + font-style: italic +} + +.bmpui-ui-subtitle-overlay.bmpui-fontfamily-smallcapital .bmpui-ui-subtitle-label { + font-variant: small-caps +} + +.bmpui-ui-subtitlesettingstogglebutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3Cstyle%3E.cls-1{fill:%23fff}%3C/style%3E%3C/defs%3E%3Cpath class='cls-1' d='m19.74 26.6-3.56-3.14h-11a2.77 2.77 0 0 1-2.64-2.87V8.15A2.74 2.74 0 0 1 5.22 5.3h21.57a2.75 2.75 0 0 1 2.63 2.85v12.42a2.76 2.76 0 0 1-2.63 2.85h-3.73ZM4.89 7.7v13.44h12l2.82 2.63 2.54-2.65H27V7.7Z'/%3E%3Cpath class='cls-1' d='M7.48 15.78H12a.89.89 0 0 1 .92.86v1.85a.89.89 0 0 1-.92.86H7.48a.89.89 0 0 1-.92-.86v-1.85a.89.89 0 0 1 .92-.86ZM15.07 15.78h5a.88.88 0 0 1 .91.86v1.85a.89.89 0 0 1-.91.86h-5a.89.89 0 0 1-.92-.86v-1.85a.89.89 0 0 1 .92-.86ZM23 15.78h1.08a.89.89 0 0 1 .92.86v1.85a.89.89 0 0 1-.91.86h-1.03a.89.89 0 0 1-.91-.86v-1.85a.86.86 0 0 1 .85-.86Z'/%3E%3C/svg%3E") +} + + .bmpui-ui-subtitlesettingstogglebutton.bmpui-on { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3Cstyle%3E.cls-2{fill:%2343ace5}%3C/style%3E%3C/defs%3E%3Cpath style='opacity:.3;isolation:isolate;fill:%2343ace5' d='M28.02 6.56v15.3h-6L20.3 25.3l-4.93-3.14H3.87V6.56h24.15z'/%3E%3Cpath class='cls-2' d='m19.74 26.6-3.56-3.14h-11a2.77 2.77 0 0 1-2.64-2.87V8.15A2.74 2.74 0 0 1 5.22 5.3h21.57a2.75 2.75 0 0 1 2.63 2.85v12.42a2.76 2.76 0 0 1-2.63 2.85h-3.73ZM4.89 7.7v13.44h12l2.82 2.63 2.54-2.65H27V7.7Z'/%3E%3Cpath class='cls-2' d='M7.48 15.78H12a.89.89 0 0 1 .92.86v1.85a.89.89 0 0 1-.92.86H7.48a.89.89 0 0 1-.92-.86v-1.85a.89.89 0 0 1 .92-.86ZM15.07 15.78h5a.88.88 0 0 1 .91.86v1.85a.89.89 0 0 1-.91.86h-5a.89.89 0 0 1-.92-.86v-1.85a.89.89 0 0 1 .92-.86ZM23 15.78h1.08a.89.89 0 0 1 .92.86v1.85a.89.89 0 0 1-.91.86h-1.03a.89.89 0 0 1-.91-.86v-1.85a.86.86 0 0 1 .85-.86Z'/%3E%3C/svg%3E") + } + +.bmpui-ui-audiotracksettingstogglebutton { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3Cstyle%3E.cls-1{fill:%23fff}%3C/style%3E%3C/defs%3E%3Cpath class='cls-1' d='M15.91 18.82a.62.62 0 0 1-.35.56.61.61 0 0 1-.65-.09l-3.32-2.79H9.81a.6.6 0 0 1-.6-.6v-2.43a.62.62 0 0 1 .6-.62h1.78l3.32-2.79a.63.63 0 0 1 .87.1.65.65 0 0 1 .13.38Zm2.34-.93h-.05a.64.64 0 0 1-.43-.18l-.08-.08a.6.6 0 0 1-.06-.79 3.54 3.54 0 0 0-.09-4.33.61.61 0 0 1 0-.82l.08-.08a.61.61 0 0 1 .46-.18.67.67 0 0 1 .45.22 4.89 4.89 0 0 1 .13 6 .61.61 0 0 1-.45.24Zm2.51 1.86a.58.58 0 0 1-.44.21.63.63 0 0 1-.43-.17l-.08-.09a.61.61 0 0 1 0-.82 6.5 6.5 0 0 0-.1-8.46.6.6 0 0 1 0-.83V9.5a.56.56 0 0 1 .44-.17.57.57 0 0 1 .44.2 7.8 7.8 0 0 1 .13 10.24Z'/%3E%3Cpath class='cls-1' d='m19.69 26.65-3.56-3.14h-11a2.77 2.77 0 0 1-2.64-2.87V8.2a2.74 2.74 0 0 1 2.68-2.85h21.57a2.75 2.75 0 0 1 2.63 2.85v12.42a2.76 2.76 0 0 1-2.63 2.85H23ZM4.84 7.75v13.44h12l2.82 2.63 2.54-2.65h4.71V7.75Z'/%3E%3C/svg%3E") +} + + .bmpui-ui-audiotracksettingstogglebutton.bmpui-on { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3Cstyle%3E.cls-2{fill:%2343ace5}%3C/style%3E%3C/defs%3E%3Cpath style='opacity:.3;isolation:isolate;fill:%2343ace5' d='M28.02 6.56v15.3h-6L20.3 25.3l-4.93-3.14H3.87V6.56h24.15z'/%3E%3Cpath class='cls-2' d='M15.9 18.93a.62.62 0 0 1-.35.55.6.6 0 0 1-.64-.08l-3.33-2.79H9.81A.61.61 0 0 1 9.2 16v-2.43a.62.62 0 0 1 .61-.57h1.77l3.33-2.79a.61.61 0 0 1 .86.1.62.62 0 0 1 .13.37Zm2.34-.93a.63.63 0 0 1-.43-.17l-.08-.09a.61.61 0 0 1-.06-.79 3.53 3.53 0 0 0-.09-4.32.64.64 0 0 1 0-.82l.08-.09a.6.6 0 0 1 .46-.17.67.67 0 0 1 .45.22 4.88 4.88 0 0 1 .13 6 .61.61 0 0 1-.45.24Zm2.51 1.87a.66.66 0 0 1-.44.21.6.6 0 0 1-.43-.18l-.08-.08a.61.61 0 0 1 0-.82 6.52 6.52 0 0 0-.1-8.47.6.6 0 0 1 0-.83v-.09a.62.62 0 0 1 .44-.18.58.58 0 0 1 .44.21 7.79 7.79 0 0 1 .13 10.23Z'/%3E%3Cpath class='cls-2' d='m19.68 26.76-3.56-3.15h-11a2.74 2.74 0 0 1-2.63-2.86V8.31a2.74 2.74 0 0 1 2.67-2.85h21.57a2.75 2.75 0 0 1 2.63 2.85v12.41a2.75 2.75 0 0 1-2.63 2.85H23ZM4.83 7.86V21.3h12l2.83 2.63 2.53-2.65h4.71V7.86Z'/%3E%3C/svg%3E") + } + +.bmpui-ui-skin-ads .bmpui-ui-ads-status { + background-color: rgba(0,0,0,.7); + left: 1.5em; + padding: .5em 1.5em; + position: absolute; + top: 1em +} + + .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-label-ad-message { + color: #999; + white-space: normal + } + + .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-button-ad-skip .bmpui-label:hover { + text-decoration: underline + } + + .bmpui-ui-skin-ads .bmpui-ui-ads-status .bmpui-ui-button-ad-skip:before { + color: #1fabe2; + content: "●"; + padding-left: .5em; + padding-right: .5em + } + +.bmpui-ui-skin-ads.bmpui-ui-skin-smallscreen .bmpui-ui-ads-status { + bottom: 0; + left: 0; + padding: 1em 1.5em; + top: auto; + width: 100% +} + +.bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-controlbar, .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-titlebar { + background: hsla(0,0%,7%,.85); + padding: .3em .5em +} + +.bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-controlbar { + bottom: 10%; + left: 10%; + right: 10%; + width: auto +} + +.bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-titlebar { + left: 10%; + right: 10%; + top: 10%; + width: auto +} + +.bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-watermark { + margin: 0; + right: 10%; + top: 10% +} + +.bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay { + bottom: 10% +} + + .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay.bmpui-controlbar-visible { + bottom: 20% + } + + .bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-subtitle-overlay .bmpui-ui-subtitle-label { + background-color: rgba(0,0,0,.5); + -webkit-box-decoration-break: clone; + box-decoration-break: clone; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + line-height: 2em; + padding: .3em .5em; + text-shadow: none + } + +.bmpui-ui-skin-cast-receiver.bmpui-ui-uicontainer .bmpui-ui-hugeplaybacktogglebutton .bmpui-image { + opacity: .7 +} + +.bmpui-ui-skin-smallscreen { + font-size: 1.2em +} + + .bmpui-ui-skin-smallscreen .bmpui-ui-settings-panel { + display: table; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + height: 100%; + left: 0; + margin: 0; + position: absolute; + top: 0; + width: 100% + } + + .bmpui-ui-skin-smallscreen .bmpui-ui-settings-panel > .bmpui-container-wrapper { + display: table-cell; + text-align: center; + vertical-align: middle; + margin: auto + } + + .bmpui-ui-skin-smallscreen .bmpui-ui-settings-panel .bmpui-ui-settings-panel-page { + min-width: 15em + } + + .bmpui-ui-skin-smallscreen .bmpui-ui-settings-panel .bmpui-ui-settings-panel-item { + text-align: left + } + + .bmpui-ui-skin-smallscreen .bmpui-ui-settings-panel .bmpui-ui-closebutton { + margin: 2em; + position: absolute; + right: 0; + top: 0 + } + + .bmpui-ui-skin-smallscreen .bmpui-ui-titlebar > .bmpui-container-wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex + } + + .bmpui-ui-skin-smallscreen .bmpui-ui-titlebar > .bmpui-container-wrapper .bmpui-ui-label { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + font-size: 1em + } + + .bmpui-ui-skin-smallscreen .bmpui-ui-titlebar > .bmpui-container-wrapper .bmpui-label-metadata-title, .bmpui-ui-skin-smallscreen.bmpui-no-flexbox .bmpui-ui-titlebar > .bmpui-container-wrapper .bmpui-label-metadata-title { + width: 100% + } + + .bmpui-ui-skin-smallscreen .bmpui-ui-cast-status-overlay { + background: #111 + } + + .bmpui-ui-skin-smallscreen .bmpui-ui-cast-status-overlay .bmpui-ui-cast-status-label { + top: 30% + } + + .bmpui-ui-skin-smallscreen .bmpui-ui-hugeplaybacktogglebutton .bmpui-image { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' style='enable-background:new 0 0 32 32' xml:space='preserve'%3E%3Cpath d='M23.3 15.2 9.8 5.6c-.3-.2-.7-.3-1-.1-.3.2-.5.5-.5.8v19.3c0 .4.2.7.6.9.1.1.3.1.4.1.2 0 .4-.1.6-.2l13.4-9.7c.3-.2.4-.5.4-.8-.1-.2-.2-.6-.4-.7zm-13 8.4V8.4L21 16l-10.7 7.6z' style='fill:%23fff'/%3E%3C/svg%3E"); + background-size: 4em + } + + .bmpui-ui-skin-smallscreen.bmpui-remote-control .bmpui-ui-hugeplaybacktogglebutton.bmpui-on .bmpui-image { + -webkit-animation: none; + animation: none; + visibility: visible + } + + .bmpui-ui-skin-smallscreen.bmpui-remote-control .bmpui-ui-hugeplaybacktogglebutton.bmpui-off .bmpui-image { + -webkit-animation: none; + animation: none + } + + .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-400 .bmpui-ui-buffering-overlay, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-400 .bmpui-ui-cast-status-overlay, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-400 .bmpui-ui-errormessage-overlay, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-400 .bmpui-ui-hugeplaybacktogglebutton, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-400 .bmpui-ui-hugereplaybutton, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-400 .bmpui-ui-settings-panel, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-400 .bmpui-ui-subtitle-overlay { + font-size: .6em + } + + .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-600 .bmpui-ui-buffering-overlay, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-600 .bmpui-ui-cast-status-overlay, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-600 .bmpui-ui-errormessage-overlay, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-600 .bmpui-ui-hugeplaybacktogglebutton, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-600 .bmpui-ui-hugereplaybutton, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-600 .bmpui-ui-settings-panel, .bmpui-ui-skin-smallscreen.bmpui-layout-max-width-600 .bmpui-ui-subtitle-overlay { + font-size: .8em + } + + .bmpui-ui-skin-smallscreen.bmpui-no-flexbox .bmpui-ui-titlebar > .bmpui-container-wrapper { + border-spacing: .5em 0; + display: table; + width: 100% + } + + .bmpui-ui-skin-smallscreen.bmpui-no-flexbox .bmpui-ui-titlebar > .bmpui-container-wrapper > * { + display: table-cell; + vertical-align: middle; + width: 1em + } + +.bmpui-ui-skin-tv { + font-size: 2vh +} + + .bmpui-ui-skin-tv .bmpui-ui-titlebar > .bmpui-container-wrapper { + margin: 2% 2% 2vh; + width: 96% + } + + .bmpui-ui-skin-tv .bmpui-ui-titlebar-top { + margin-bottom: 1vh + } + + .bmpui-ui-skin-tv .bmpui-ui-titlebar-top > .bmpui-container-wrapper { + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-box-pack: end; + -ms-flex-pack: end; + align-items: center; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + font-size: 3.5vh; + justify-content: flex-end; + width: 100% + } + + .bmpui-ui-skin-tv .bmpui-ui-titlebar-top > .bmpui-container-wrapper .bmpui-label-metadata-title { + font-size: 3.5vh; + margin-right: auto + } + + .bmpui-ui-skin-tv .bmpui-ui-hugeplaybacktogglebutton > .bmpui-image { + background-size: 20vh + } + + .bmpui-ui-skin-tv .bmpui-ui-titlebar-bottom > .bmpui-container-wrapper { + -webkit-box-align: start; + -ms-flex-align: start; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + align-items: flex-start; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + font-size: 3.5vh; + justify-content: space-between; + position: relative; + width: 100% + } + + .bmpui-ui-skin-tv .bmpui-ui-titlebar-bottom .bmpui-label-metadata-description { + font-size: 2vh; + line-height: 2em; + width: 66% + } + + .bmpui-ui-skin-tv .bmpui-ui-titlebar-bottom .bmpui-ui-settings-panel { + font-size: 3vh; + right: 0; + top: 0 + } + + .bmpui-ui-skin-tv .bmpui-ui-audiotracksettingstogglebutton, .bmpui-ui-skin-tv .bmpui-ui-subtitlesettingstogglebutton { + font-size: 5vh + } + + .bmpui-ui-skin-tv .bmpui-ui-controlbar { + font-size: 3vh + } + + .bmpui-ui-skin-tv .bmpui-ui-controlbar > .bmpui-container-wrapper { + margin: 2% 0; + width: 99% + } + + .bmpui-ui-skin-tv .bmpui-ui-playbacktimelabel { + font-size: 2.5vh + } + + .bmpui-ui-skin-tv :focus { + border: 0; + -webkit-box-shadow: 0 0 0 2px rgba(27,127,204,.8); + box-shadow: 0 0 0 2px rgba(27,127,204,.8); + -webkit-filter: drop-shadow(0 0 .3em #1fabe2); + filter: drop-shadow(0 0 .3em #1fabe2); + outline: 0; + -webkit-transition: .05s ease-in-out; + transition: .05s ease-in-out + } + +.bmpui-ui-uicontainer { + color: #fff; + font-family: sans-serif; + font-size: 1em; + text-align: left; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none +} + + .bmpui-ui-uicontainer .bmpui-text-right { + text-align: right + } + + .bmpui-ui-uicontainer.bmpui-layout-max-width-400 .bmpui-ui-hugeplaybacktogglebutton, .bmpui-ui-uicontainer.bmpui-layout-max-width-400 .bmpui-ui-watermark, .bmpui-ui-uicontainer.bmpui-layout-max-width-600 .bmpui-ui-hugeplaybacktogglebutton, .bmpui-ui-uicontainer.bmpui-layout-max-width-600 .bmpui-ui-watermark { + font-size: .7em + } diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkiomediaplayer.d.ts b/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkiomediaplayer.d.ts deleted file mode 100644 index 0a68d4513..000000000 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkiomediaplayer.d.ts +++ /dev/null @@ -1,2328 +0,0 @@ -/** - * API of Azure Media Player ([[amp]]), use azuremediaplayer.d.ts if caller is using [TypeScript](http://www.typescriptlang.org/). - */ -declare module mkioplayer { - - /** - * The Player instance for [[amp]], for the caller to interact with. - */ - interface Player { - - /** - * Starts media playback. - * - * myPlayer.play(); - * - * @return The [[amp.Player]] calling this function. - */ - play(): Player; - - /** - * Pauses the video playback. - * - * myPlayer.pause(); - * - * @return The [[amp.Player]] calling this function. - */ - pause(): Player; - - /** - * Get whether or not the player is in the "paused" state. - * - * var isPaused = myPlayer.paused(); - * - * @return True if the player is in the paused state, false if not. - */ - paused(): boolean; - - /** - * Get whether or not the player is in the "seeking" state. - * @return True if the player is in the seeking state, false if not. - */ - seeking(): boolean; - - /** - * Get whether or not the player is in the "ended" state. - * @return True if the player is in the ended state, false if not. - */ - ended(): boolean; - - /** - * Gets/Sets the player level options to add new options or override the given options if - * has already been set. - * - * @param options Object of new option values - * @return **New** object of this.options_ and options merged - */ - options(options: Player.Options): Player.Options; - options(): Player.Options; - - /** - * Sets a single source to play. - * Use this method if you know the type of the source and only have one source. - * - * myPlayer.src({ type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" }, - * ~~~ - * ~~~ - * [{ kind: "captions" src: "http://example.com/path/to/track.vtt" srclang: "fr" label: "French"}]); - * ~~~ - * ~~~ - * - * @param newSource Source object - * @parm optional parameter, array of the text tracks to used with the given source. - * @return The [[amp.Player]] calling this function. - */ - src(newSource: Player.Source, tracks?: Player.Track[]): Player; - - /** - * Sets multiple versions of the source to play so - * that it can be played using techs across browsers. - * - * ~~~ - * myPlayer.src([ - * ~~~ - * ~~~ - * { type: "application/dash+xml", src: "http://www.example.com/path/to/video.ism(format=mpd-csf-time)" }, - * ~~~ - * ~~~ - * { type: "application/dash+xml", src: "http://www.example.com/path/to/video.ism(format=mpd-time-csf)", protectionInfo: [{type: "AES", authenticationToken:"token"}] }, - * ~~~ - * ~~~ - * { type: "application/dash+xml", src: "http://www.example.com/path/to/video.ism(format=mpd-time-csf)", disableUrlRewriter: true }, - * ~~~ - * ~~~ - * { type: "application/dash+xml", src: "http://www.example.com/path/to/video.ism(format=mpd-time-csf)", streamingFormats: ["SMOOTH", "DASH"] }, - * ~~~ - * ~~~ - * { type: "video/ogg", src: "http://www.example.com/path/to/video.ogv" }], - * ~~~ - * ~~~ - * [{ kind: "captions" src: "http://example.com/path/to/track.vtt" srclang: "fr" label: "French"}] - * ~~~ - * ~~ - * ); - * ~~~ - * @param newSources Array of sources - * @parm optional parameter, array of the text tracks to used with the given source. - * @return The [[amp.Player]] calling this function. - */ - src(newSources: Player.Source[], textTracks?: Player.Track[]): Player; - - /** - * Get the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4. - * Can be used in conjuction with [[amp.Player.currentType]] to assist in rebuilding the current source object. - * @return Current source. - */ - currentSrc(): string; - - /** - * Get the current source type e.g. video/mp4. - * This can allow you rebuild the current source object so that you could load the same - * source and tech later. - * @return MIME type of the current source. - */ - currentType(): string; - - /** - * Get the protectionInfo for the current source. - * @return Protection information of the current source. - */ - currentProtectionInfo(): Player.ProtectionInfo; - - /** - * Get whether or not the presentation is live. - * @return true if the presentation is live, false if not. - */ - isLive(): boolean; - - /** - * Set/Get the current HeuristicProfile - */ - currentHeuristicProfile(value: string): Player; - currentHeuristicProfile(): string; - - /** - * Get the current Player settings for the given key - */ - currentPlayerSettingValue(key: string): any; - - /** - * Get the current name of the chosen tech. - * @return Name of tech(in Pascal case). - */ - currentTechName(): string; - - /** - * Gets the current video streams list. - * @return [[amp.VideoStreamList]], undefined if not available - */ - currentVideoStreamList(): VideoStreamList; - - /** - * Gets the current audio streams list. - * @return [[amp.AudioStreamList]], undefined if not available - */ - currentAudioStreamList(): AudioStreamList; - - /** - * Gets the video buffer information - * @return [[amp.BufferData]], undefined if not available - */ - videoBufferData(): BufferData; - - /** - * Gets the audio buffer information - * @return [[amp.BufferData]], undefined if not available - */ - audioBufferData(): BufferData; - - /** - * Set/Get the poster image source url. - * - * ##### Example of setting: - * myPlayer.poster('http://example.com/myImage.jpg'); - * - * ##### Example of getting: - * var currentPoster = myPlayer.poster(); - * - * @param src Poster image source URL when setting. - * @return The [[amp.Player]] calling this function when setting, posterURL when getting. - */ - poster(src: string): Player - poster(): string; - - /** - * Set/Get whether or not the controls are showing. - * - * @param value Set controls to showing or not. - * @return The [[amp.Player]] calling this function when setting, true/false when getting. - */ - controls(value: boolean): Player - controls(): boolean; - - /** - * Set/Get whether or not to autoplay on [[amp.Player.src]]. - * - * @param value Whether to autoplay or not. - * @return The [[amp.Player]] calling this function when setting, true/false when getting. - */ - autoplay(value: boolean): Player; - autoplay(): boolean; - - /** - * Set the current time. - * - * ##### Example of setting: - * myPlayer.currentTime(120); // 2 minutes into the video - * - * ##### Example of getting: - * var whereYouAt = myPlayer.currentTime(); - * - * @param seconds Time to seek to, in seconds. - * @return The [[amp.Player]] calling this function when setting, time in seconds when getting. - */ - currentTime(seconds: number): Player; - currentTime(): number; - - /** - * Gets the current absolute time, in seconds. - * @return absolute time in seconds, undefined if not available - */ - currentAbsoluteTime(): number; - currentAbsoluteTime(seconds: number): Player; - - /** - * Gets the current media time, in seconds. - * @return media time in seconds, undefined if not available - */ - currentMediaTime(): number; - - /** - * Gets the download bitrate. - * @return bitrate in bps, undefined if not available - */ - currentDownloadBitrate(): number; - - /** - * Gets the playback bitrate. - * @return bitrate in bps, undefined if not available - */ - currentPlaybackBitrate(): number; - - /** - * Gets the presentation time offset specified in the manifest ( In seconds ). - * Available only in DASH. - */ - presentationTimeOffsetInSec(): number; - - /** - * Get the length in time of the source. For live, it is the playable window. - * - * ##### Example: - * var lengthOfSource = myPlayer.duration(); - * - * **NOTE**: The source must have started loading before the duration can be - * known, and in the case of Flash, may not be known until the video starts - * playing. - * - * @return Duration of the source, in seconds. - */ - duration(): number; - - /** - * Get a TimeRanges object with the times of the source that have been downloaded. - * - * ##### Examples: - * var bufferedTimeRange = myPlayer.buffered(); - * - * Number of different ranges of time have been buffered. Usually 1. - * - * var numberOfRanges = bufferedTimeRange.length; - * - * Time in seconds when the first range starts. Usually 0. - * - * var firstRangeStart = bufferedTimeRange.start(0); - * - * Time in seconds when the first range ends - * - * var firstRangeEnd = bufferedTimeRange.end(0); - * - * Length in seconds of the first time range - * var firstRangeLength = firstRangeEnd - firstRangeStart; - * - * @return TimeRanges object [following JS spec](https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges). - */ - buffered(): TimeRanges; - - /** - * Get the current error. - * @return Media error - */ - error(): MediaError; - - /** - * Set/Get volume of the source. - * - * ##### Example: - * myPlayer.volume(0.5); // Set volume to half - * - * 0 is off (muted), 1.0 is all the way up, 0.5 is half way. - * - * @param percentAsDecimal New volume as a decimal (0 to 1.0). - * @return The [[amp.Player]] calling this function when setting, current volume when getting. - */ - volume(percentAsDecimal: number): Player; - volume(): number; - - /** - * Set/Get muted state. - * - * ##### Example of setting: - * myPlayer.muted(true); // mute the volume - * - * @param value True to mute, false to unmute. - * @return The [[amp.Player]] calling this function when setting, current mute state when getting. - */ - muted(value: boolean): Player; - muted(): boolean; - - /** - * Set/Get width of the component (CSS values). - * - * Setting the video tag dimension values works with values in pixels, % or 'auto'. - * - * @param value Value in pixels, % or 'auto'. - * @return The [[amp.Player]] calling this function when setting, pixels when getting. - */ - width(): Object; - width(value: Object): Player; - - /** - * Set/Get height of the component (CSS values). - * - * Setting the video tag dimension values works with values in pixels, % or 'auto'. - * - * @param value Value in pixels, % or 'auto'. - * @return The [[amp.Player]] calling this function when setting, pixels when getting. - */ - height(): Object; - height(value: Object): Player; - - /** - * Get the videoWidth of the player. - * - * @return Video width of the player. - */ - videoWidth(): number; - - /** - * Get the videoHeight of the player. - * - * @return Video height of the player. - */ - videoHeight(): number; - - /** - * Check if the player is in fullscreen mode. - * - * ##### Example: - * var isFullscreen = myPlayer.isFullscreen(); - * - * @return True if fullscreen, false if not. - */ - isFullscreen(): boolean; - - /** - * Increase the size of the video to full screen. - * - * ##### Example: - * myPlayer.enterFullscreen(); - * - * In some browsers, full screen is not supported natively, so it enters - * "full window mode", where the video fills the browser window. - * In browsers and devices that support native full screen, sometimes the - * browser's default controls will be shown, and not the [[amp]] custom skin. - * This includes most mobile devices (iOS, Android) and older versions of - * Safari. - * - * @return The [[amp.Player]] calling this function. - */ - enterFullscreen(): Player; - - /** - * Get the video to its normal size after having been in full screen mode. - * - * ##### Example: - * myPlayer.exitFullscreen(); - * - * @return The [[amp.Player]] calling this function. - */ - exitFullscreen(): Player; - - /** - * Bind a listener to the Player's ready state. - * - * Different from event listeners in that if the ready event has already happened - * it will trigger the function immediately. - * - * @param handler Ready handler - * @return The [[amp.Player]] calling this function. - */ - ready(handler: Function): Player; - - /** - * Add an event listener to this Player's element. - * - * ##### Example: - * myPlayer.addEventListener('eventType', myFunc); - * - * @param eventName The event type string. Use [[amp.eventName]] for the list of event types. - * ex: `amp.eventName.playing` - * - * @param handler Event handler. - * @return The [[amp.Player]] calling this function. - */ - addEventListener(eventName: string, handler: Function): Player; - - /** - * Remove an event listener from this Player's element. - * - * ##### Example: - * myPlayer.removeEventListener('eventType', myFunc); - * - * If myFunc is excluded, *all* listeners for the event type will be removed. - * If eventType is excluded, *all* listeners will be removed from the component. - * - * @param eventName The event type string. Use [[amp.eventName]] for the list of event types. - * ex: `amp.eventName.playing` - * - * @param handler Event handler. - * @return The [[amp.Player]] calling this function. - */ - removeEventListener(eventName: string, handler?: Function): Player; - - /** - * Destroys the [[amp.Player]] and does any necessary cleanup. - * - * ##### Example: - * myPlayer.dispose(); - * - * This is especially helpful if you are dynamically adding and removing videos - * to/from the DOM. - * The orignial videoTag created by the app is also deleted as part of this dispose. - */ - dispose(): void; - - /** - * Get the Log traces from the player, if memoryLog is enabled. - * - * @param flush flush memoryLog after returning the log. - * @return Log trace string from the player. - */ - getMemoryLog(flush: boolean): string; - - /** - * Get the version of AMP player in the format - * ... - * - * @return Released AMP player version string. - */ - getAmpVersion(): string; - - /** - * Get the playable window length in seconds from the manifest - * - * @return Playable window length in seconds from the manifest - * or undefined if not present in the tech - */ - manifestPlayableWindowLength(): number; - - /** - * For live presentations, get the playable window start time (current absolute time - dvr window length) and end time in seconds. - * For VOD, returns undefined. - * - * Example: If the playable window is 2 hours and the stream has been going for 3 hours, - * the returned time range would be 01:00:00 - 03:00:00 - * - * @return Playable window start and end in seconds - */ - currentPlayableWindow(): TimeRange; - - /** - * Returns the playable window end time in seconds, regardless of if presentation is live or VOD, as long as it's available. - * Returns undefined if it's not available. - * - * @return Playable window end time in seconds - */ - playableWindowEndInSec(): number; - - /** - * Get an array of the calculated segment boundary start times in seconds. - * - * @return Calculated segment boundaries - */ - segmentBoundaries(): Array; - - /** - * Get the el_ of AMP player - * - * @return the el_ from the underlying player. - */ - playerElement(): HTMLVideoElement; - - /** - * Used in live playback calculations. - * Given a time from the current playable window, returns the associated absolute time. - * - * Example: If the playable window is 2 hours and the stream has been going for 3 hours, - * if you pass the playable window time of 00:00:00, the returned absolute time would be 01:00:00 (1 hour). - * - * @param {number} target player time in seconds - * @return {number} the presentation time in seconds - */ - toPresentationTime(time: number): number; - - /** - * Used in live playback calculations. - * Given an absolute time, returns the associated time from the current playable window. - * If the given absolute time falls outside of the current playable window, - * returns the difference between the playable window edge and the given absolute time. - * - * Example: If the playable window is 2 hours and the stream has been going for 3 hours, - * if you pass the absolute time of 01:00:00 (1 hour), the returned playable window time would be 00:00:00. - * - * @param {number} target presentation time in seconds - * @return {number} the player time in seconds - */ - fromPresentationTime(time: number): number; - - /** - * Set a factory to allow custom XMLHttpRequest creation logic. - * - * @param {factory}, Factory method. @see XMLHttpRequestFactory. - */ - setXmlHttpRequestFactory(factory: XMLHttpRequestFactory): void; - - /** - * Checks if the player is able to control playback rate. - * The ability to control playback rate depends on current tech, browser and OS. - * - * ##### Example: - * var isPlaybackRateControlAvailable = myPlayer.canControlPlaybackRate(); - * - * @return True if playback rate can be changed, False otherwise. - */ - canControlPlaybackRate(): boolean; - - /** - * Gets or sets the current playback rate. A playback rate of - * 1.0 represents normal speed and 0.5 would indicate half-speed - * playback, for instance. - * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate - * - * @param value New playback rate to set. - * @return The [[amp.Player]] calling this function when setting, current playback rate when getting. - * @method playbackRate - */ - playbackRate(): number; - playbackRate(value: number): Player; - - /** - * Gets or sets downloadable media options. Setting new value completely overwrites existing downloadable media. - * - * @param value New downlodable media to set. - * @return The [[amp.Player]] calling this function when setting, current downlodable media value when getting. - * @method downloadableMedia - */ - downloadableMedia(): mkioplayer.Player.DownloadableMediaFile[]; - downloadableMedia(value: mkioplayer.Player.DownloadableMediaFile[]): Player; - - /** - * Set/Get playlist to play. - * - * @param  newPlaylist Playlist object - */ -        playlist(newPlaylist: PlayList): void; -        playlist(): PlayList; - -        /** -         * Adds a mid-roll clip schedule to the currently playing clip. -         * -         * @param  newMidRoll Mid-roll to insert or cancel -         * @return The array of scheduled mid-rolls on the currently playing clip. -         */ -        addMidRoll(newMidRoll: MidRoll): MidRoll[]; - -        /** -         * Returns newly seen splices, evt: "splicewaiting" -         * - */ -        spliceWaiting(): Splice[]; - - - /** - * Return current clip that is being played. - */ - currentClip(): Clip; - - /** - * Get an array of associated text tracks. captions, subtitles, chapters, descriptions - * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks - * - * @return {Array} Array of track objects - * @method textTracks - */ - textTracks(): Player.Track[]; - - /** - * Returns the textTrack that is currently being shown. - */ - getCurrentTextTrack(): Player.Track; - - /** - * Disables text Tracks that are currently being shown. - */ - disableTextTracks(): void; - - /** - * Sets active text Track. - * @param textTrack The text track. - */ - setActiveTextTrack(textTrack: Player.Track): void; - - /** - * Get and Set presentationLayout. - * @param value New prsentation layout for playback. - */ - presentationLayout(): PresentationLayout; - presentationLayout(value: PresentationLayout): void; - } - - /** - * Customizable Options for ad support. - */ - export interface AdOptions { - skipAd: { - enabled: boolean; // is skip allowed or not. - offset?: number; // Minimal time after which skip is allowed if it is enabled. - }; - } - - /** - * Interface describing an Advertisement. - */ - export interface AdElement { - // Add server URI. - sourceUri: string; - // Ad start time for midrolls, in seconds. - startTime?: number; - // Override options, take precendence over the ad server. - options?: AdOptions; - } - - /** - * Main program definition. - */ - export interface MainProgram { - source: mkioplayer.Player.Source; - tracks: mkioplayer.Player.Track[]; - } - - - /** - * The presentation layout defines the three logical -     * regions where ads can be inserted. All regions are -     * optional. - */ - export interface PresentationLayout { - // Pre-Roll definition, ad will be played before the content playback starts. - preRoll?: AdElement; - // Mid-roll definition, ad will be played at a specified startTime, which is offset from the start time of content. - midRoll?: AdElement[]; - // Post-roll definition, ad will be played after content had finished playing. - postRoll?: AdElement; - // Main program definition, this is the content that will be played. Contains source and track info. - mainProgram: MainProgram; - } - - /** - * Assest representing a media source. - */ - export interface Asset { - name: string; - source: Player.Source; - track?: Player.Track[]; - } - - /** - * Playable logical section of an Asset. - */ - export interface Clip { - - name: string; - - /** - * Is current Clip an advertisement or not. - */ - isAd: boolean; - - /** - * The asset from where this clip was defined. - */ - parent: Asset; - - /** - * The clip offset in seconds from the beginning of the asset. - */ - offset: number; - - /** - * The clip duration in seconds, cannot extend past the end of the asset - */ -        duration?: number; - - /** - * If set to true, clip presentation ends when the amount of time specified - * as duration has passed from when clip source was set, regardless of play status. - * Defaults to false. - * - */ -        timedReturn?: boolean; - - /** - * Optional URI to direct a user to when a click occurs while clip is active - * - */ -        clickThrough?: string; - - /** - *If set, the number of seconds to play before this clip becomes skippable - *Defaults to not skippable. - * - */ -        skippable?: number; - } - - /** - * A presentation set. - */ -    interface PlayList { -        name: string; - -        /** -         * List of clips in presentation order - */ -        clips: Clip[]; - -        /** -         * Whether current clip timeline should be paused during mid-roll insertions - */ -        pauseTimeline?: boolean; -    } - - - /** - * An insertion opportunity in the current presentation. - */ -    interface Splice { - -        /** -         * Splice unique identifier. -         */ -        id: number; - -        /** -         * Start time of the splice event as an offset from the beginning of the current clip in seconds. - * -1 if this is an immediate splice. -         */ -        startOffset: number; - -        /** -         * Splice signal is an opportunity to exit from current clip. -         */ -        out?: boolean; - -        /** -         * Duration of the splice event, in seconds. -         */ -        duration?: number; - -        /** -         * Set to true indicates that a previously sent splice event should be cancelled. -         * Defaults to false. -         */ -        cancel?: boolean; -    } - - /** - * An insertion element into the current presentation. - */ -    interface MidRoll { - -        /** -         * Splice information. -         */ -        splice: Splice; - -        /** -         * Clip information. Not present when cancelling. -         */ -        clip?: Clip; -    } - - /** - * Interface describing factory method for creation of XmlHttpRequestWrapper. - */ - export interface XMLHttpRequestFactory { - (): XMLHttpRequestWrapper; - } - - /** - * CORS setting values. - */ - export class CorsConfig { - static Anonymous: string; - static UseCredentials: string; - } - - /** - * Interface describing a HttpRequest. - * @see XMLHttpRequest - */ - export interface XMLHttpRequestWrapper { - onabort: (ev: Event) => any; - onerror: (ev: Event) => any; - onload: (ev: Event) => any; - onloadend: (ev: ProgressEvent) => any; - onloadstart: (ev: Event) => any; - onprogress: (ev: ProgressEvent) => any; - ontimeout: (ev: ProgressEvent) => any; - onreadystatechange: (ev: ProgressEvent) => any; - responseType: string; - timeout: number; - msCaching: string; - readyState: number; - status: number; - statusText: string; - response: any; - setRequestHeader(header: string, value: string): void; - abort(): void; - open(method: string, url: string, async?: boolean, user?: string, password?: string): void; - getResponseHeader(header: string): string; - send(data?: any): void; - } - - /** - * Interface describing a time range - */ - export interface TimeRange { - startInSec: number; - endInSec: number; - } - - /** - * Custom MediaError to report why playback failed - */ - interface MediaError { - - /** - * Error codes (see [[amp.ErrorCode]]) - * Bits [31-28] - Tech Id - * ``` - * Unknown = 0 - * AMP = 1 - * AzureHtml5JS = 2 - * FlashSS = 3 - * SilverlightSS = 4 - * Html5 = 5 - *.Html5FairPlayHLS = 6 - * ``` - * Bits [27-20] - High level code - * ``` - * 'MEDIA_ERR_CUSTOM' = 0 - * 'MEDIA_ERR_ABORTED' = 1 - * 'MEDIA_ERR_NETWORK' = 2 - * 'MEDIA_ERR_DECODE' = 3 - * 'MEDIA_ERR_SRC_NOT_SUPPORTED' = 4 - * 'MEDIA_ERR_ENCRYPTED' = 5 - * 'SRC_PLAYER_MISMATCH' = 6 - * 'MEDIA_ERR_UNKNOWN' = 0xFF - * ``` - * Bits [19-0] - More details of the error. See [[amp.errorCode]]. - */ - code: number; - - /** - * Optional error with more details - */ - message: string; - } - - /** - * Video stream list, returned from [[amp.Player.currentVideoStreamList]] - */ - interface VideoStreamList { - /** - * Array of available video streams - */ - streams: VideoStream[]; - - /** - * Video stream that is currently selected, for multi video streams, only 1 stream can be selected - */ - selectedIndex: number; - } - - /** - * Video stream properties and functions - */ - interface VideoStream { - /** - * Name of video stream - */ - name: string; - - /** - * codec of video stream - */ - codec: string; - - /** - * Array of video tracks - */ - tracks: VideoTrack[]; - - /** - * Select single track playback by tracks index. When selection has been honored, "changed" - * event will fire. - * @param index Index from tracks. If -1, enable auto switching heuristics. - */ - selectTrackByIndex(index: number): void; - - /** - * Method to add a listener to an event - * @param streamEventName string of event name, available events are defined in [[amp.streamEventName]] - * @param handler handler that is called when event occurs - */ - addEventListener(streamEventName: string, handler: Function): void; - - /** - * Method to remove a listener from an event - * @param streamEventName string of event name, available events are defined in [[amp.streamEventName]] - * @param handler handler that should be removed - */ - removeEventListener(streamEventName: string, handler: Function): void; - } - - /** - * Video track properties and functions - */ - interface VideoTrack { - /** - * Returns the width of the track - **/ - width?: number; - - /** - * Returns the height of the track - **/ - height?: number; - - /** - * Returns the bitrate of the track in bits per second - **/ - bitrate: number; - - /** - * Returns whether the track is currently selectable for download - **/ - selectable: boolean; - } - - interface AudioStreamList { - /** - * Array of available audio streams - */ - streams: AudioStream[]; - - /** - * Audio stream that is currently enabled, currently only 1 stream can be enabled at a single time. Returns array of indices - */ - enabledIndices: number[]; - - /** - * Switch the audiostream currently playing (current implementation is exclusive) - * @param streamIndex the index of the stream to switch to - */ - switchIndex(streamIndex: number): void; - - /** - * Method to add a listener to an event - * @param streamEventName string of event name, available events are defined in StreamEventName class - * @param handler handler that is called when event occurs - */ - addEventListener(streamEventName: string, handler: Function): void; - - /** - * Method to remove a listener from an event - * @param streamEventName string of event name, available events are defined in StreamEventName class - * @param handler handler that should be removed - */ - removeEventListener(streamEventName: string, handler: Function): void; - - } - - interface AudioStream { - /** - * name of audio stream - */ - name: string; - - /** - * codec of audio stream - */ - codec: string; - - /** - * Language of audio stream, specified in RFC 5646 - */ - language: string; - - /** - * bitrate of audio stream - */ - bitrate: number; - - /** - * Whether this stream is enabled - */ - enabled: boolean; - - } - - /** - * Buffer data, returned from [[amp.Player.videoBufferData]] and [[amp.Player.audioBufferData]] - */ - export interface BufferData { - /** - * Buffer level in seconds - */ - bufferLevel: number; - - /** - * Bandwidth used to make heuristic decision, available with [[amp.Player.videoBufferData]] only, in bps - */ - perceivedBandwidth?: number; - /** - * Returns the most recent download requested, evt: "downloadrequested" - **/ - downloadRequested: MediaDownload; - - /** - * Returns the most recent download completed, evt: "downloadcompleted" - **/ - downloadCompleted: MediaDownloadCompleted; - - /** - * Returns the most recent download decrypted, evt: "downloaddecrypted - **/ - downloadDecrypted: MediaDownloadDecrypted; - - /** - * Returns the most recent download failed, evt: "downloadfailed" - **/ - downloadFailed: MediaDownloadFailed; - - /** - * Method to add a listener to an event - * @param eventName string of event name, available events are defined in BufferDataEventName class - * @param handler handler that is called when event occurs - */ - addEventListener(eventName: string, handler: Function): void; - - /** - * Method to remove a listener from an event - * @param eventName string of event name, available events are defined in BufferDataEventName class - * @param handler handler that should be removed - */ - removeEventListener(eventName: string, handler: Function): void; - } - - export interface MediaDownload { - /** - * Returns the url for this download - **/ - url: string; - - /** - * Returns the bitrate for this download, in bps - **/ - bitrate: number; - - /** - * Returns the media time for this download in seconds, null, if initialization download - **/ - mediaTime: number; - } - - export interface MediaDownloadCompleted { - /** - * Returns the measured bandwidth for this download, in bps - **/ - measuredBandwidth: number; - - /** - * Returns the total bytes for this download - **/ - totalBytes: number; - - /** - * Returns the total time to download, in ms - **/ - totalDownloadMs: number; - - /** - * Returns the media download information - **/ - mediaDownload: MediaDownload; - - /** - * An Object containing Key value pair of response headers. - * If needed the requested headers can be passed in player options. - **/ - responseHeaders?: { [key: string]: string }; - } - - export interface MediaDownloadDecrypted { - /** - * Returns the media download information - **/ - mediaDownload: MediaDownload; - } - - export interface MediaDownloadFailed { - /** - * Error code of the failure - **/ - code: number; - - /** - * Optional information on failure - **/ - message?: string; - - /** - * Returns the media download information - **/ - mediaDownload: MediaDownload; - } - - /** - * Event types from [[amp]] - */ - export class eventName { - /** - * Buffer has met pre-roll level. Note: There are some variation across techs. - * On Html5 tech, this event is only raised for the first set source, - * if source is set again on the same player, this event will not occur again. - */ - static canplaythrough: string; - - /** - * [[amp.Player.duration]] property has changed. - */ - static durationchange: string; - - /** - * [[amp.Player.ended]] property has changed. - */ - static ended: string; - - /** - * Error occurred, playback will stop, check [[amp.Player.error]] property. - */ - static error: string; - - /** - * [[amp.Player.isFullscreen]] property has changed. - */ - static fullscreenchange: string; - - /** - * Playback is looking for media data. - */ - static loadstart: string; - - /** - * Media data has been rendered for the first time. - */ - static loadeddata: string; - - /** - * [[amp.Player.currentVideoStreamList]] maybe available. - */ - static loadedmetadata: string; - - /** - * Playback has paused, check [[amp.Player.paused]] property. - */ - static pause: string; - - /** - * Play function has begun. - */ - static play: string; - - /** - * Play function has completed, check [[amp.Player.paused]] property. - */ - static playing: string; - - /** - * Seek has complete, check [[amp.Player.seeking]] property. - */ - static seeked: string; - - /** - * Seek has begun. - */ - static seeking: string; - - /** - * App has set the source. SDN plugins should wait for this event before modifying - * [[amp.Player.Options.sourceList]]. - */ - static sourceset: string; - - /** - * [[amp.Player.currentTime]] property has changed. - */ - static timeupdate: string; - - /** - * [[amp.Player.volume]] property has changed. - */ - static volumechange: string; - - /** - * Playback has been paused to build a low buffer. - */ - static waiting: string; - - /** - * [[amp.Player.currentDownloadBitrate]] property has changed. - */ - static downloadbitratechanged: string; - - /** - * [[amp.Player.currentPlaybackBitrate]] property has changed. - */ - static playbackbitratechanged: string; - - /** - * [[amp.Player.playbackRate]] property has changed. - */ - static ratechange: string; - - /** - * [[amp.Player.dispose]] was called. - */ - static disposing: string; - - /** - * [[amp.Player.spliceWaiting]] msg was received. - */ - static splicewaiting: string; - - /** - * emsg boxes are available by examining the event [[amp.Player.emsgAvailable]]. - * Available only in DASH - * - * ##### Example: - * myPlayer.addEventListener(amp.eventName.emsgAvailable, function (event, info) { - * // emsg boxes are in info.data - * }); - * - */ - static emsgAvailable: string; - - /** - * [[amp.Player.start]] Playback started. - */ - static start: string; - - /** - * [[amp.Player.firstquartile]] Playback reached first quartile. - */ - static firstquartile: string; - - /** - * [[amp.Player.midpoint]] Playback reached middle. - */ - static midpoint: string; - - /** - * [[amp.Player.thirdquartile]] Playback reached third quarter. - */ - static thirdquartile: string; - - /** - * [[amp.Player.complete]] Playback reached end. Synonym of 'ended' - */ - static complete: string; - - /** - * [[amp.Player.mute]] Playback was muted. - */ - static mute: string; - - /** - * [[amp.Player.unmute]] Player was unmuted. - */ - static unmute: string; - - /** - * [[amp.Player.rewind]] Playback was rewound. - */ - static rewind: string; - - /** - * [[amp.Player.resume]] Player started after a pause. - */ - static resume: string; - - /** - * [[amp.Player.fullscreen]] Player has entered fullscreen mode. - */ - static fullscreen: string; - - /** - * [[amp.Player.exitfullscreen]] Player has exited fullscreen mode. - */ - static exitfullscreen: string - - /** - * [[amp.Player.click]] User clicked on video frame. - */ - static click: string; - - /** - * [[amp.Player.skip]] Skip UI control was used. - */ - static skip: string; - - /** - * [[amp.Player.errorInPlayingAd]] player encountered an error when playing an advertisement clip. - */ - static errorInPlayingAd: string; - - /** - * [[amp.Player.livestartupretry]] player encountered an retry while trying to play a live content, and being retried. - */ - static livestartupretry: string; - /** - * The decryptor has initialized in AES Handler. - */ - static decryptorInitialized: string; - } - - /** - * Stream Event types from [[amp.Player.currentVideoStreamList]] - */ - export class streamEventName { - /** - * Track has been selected in [[amp.Player.currentVideoStreamList]] - */ - static trackselected: string; - } - - /** - * Stream Event types from [[amp.Player.currentAudioStreamList]] - */ - export class streamListEventName { - /** - * Stream has been selected in [[amp.Player.currentAudioStreamList]] - */ - static streamselected: string; - /** - * Index chosen did not exist in the list of audio streams in [[amp.Player.currentAudioStreamList]] - */ - static streamindexinvalid: string; - /** - * Currently, stream selection is only supported when single stream is - * enabled in [[amp.Player.currentAudioStreamList]] - */ - static streamselectnotsupported: string; - } - - /** - * BufferData Events from [[amp.Player.videoBufferData]] or [[amp.Player.audioBufferData]] - */ - export class bufferDataEventName { - /** - * Download of media has been requested from [[amp.Player.videoBufferData]] or [[amp.Player.audioBufferData]] - */ - static downloadrequested: string; - - /** - * Download of media has been completed from [[amp.Player.videoBufferData]] or [[amp.Player.audioBufferData]] - */ - static downloadcompleted: string; - - /** - * Download of media has been decrypted from [[amp.Player.videoBufferData]] or [[amp.Player.audioBufferData]]. - * Happens only for AES. - */ - static downloaddecrypted: string; - - /** - * Download of media has failed from [[amp.Player.videoBufferData]] or [[amp.Player.audioBufferData]] - */ - static downloadfailed: string; - } - - /** - * Protection types for [[amp]] - */ - export class protectionType { - /** - * Source is PlayReady encrypted. - */ - static PlayReady: string; - - /** - * Source is Widevine encrypted. - */ - static Widevine: string; - - /** - * Source is [AES envelope](http://msdn.microsoft.com/en-us/library/azure/dn783457.aspx) encrypted. - */ - static AES: string; - - /** - * Source is FairPlay encrypted. - */ - static FairPlay: string; - } - - /** - * Error codes for [[amp.MediaError.code]] for bits 27-0. - */ - export class errorCode { - /** - * MEDIA_ERR_ABORTED errors start value (0x00100000). - */ - static abortedErrStart: number; - - /** - * Generic abort error (0x00100000). - */ - static abortedErrUnknown: number; - - /** - * Abort error, not implemented (0x00100001). - */ - static abortedErrNotImplemented: number; - - /** - * The page is loaded over HTTPS, but the source is set to serve over HTTP. - * The content must be served over HTTPS when the page is loaded over HTTPS (0x00100002). - */ - static abortedErrHttpMixedContentBlocked: number; - - /** - * MEDIA_ERR_ABORTED errors end value (0x001FFFFF). - */ - static abortedErrEnd: number; - - /** - * MEDIA_ERR_NETWORK errors start value (0x00200000). - */ - static networkErrStart: number; - - /** - * Generic network error (0x00200000). - */ - static networkErrUnknown: number; - - /** - * Http error response start value (0x00200190). - */ - static networkErrHttpResponseBegin: number; - - /** - * Http 400 error response (0x00200190). - */ - static networkErrHttpBadUrlFormat: number; - - /** - * Http 401 error response (0x00200191). - */ - static networkErrHttpUserAuthRequired: number; - - /** - * Http 403 error response (0x00200193). - */ - static networkErrHttpUserForbidden: number; - - /** - * Http 404 error response (0x00200194). - */ - static networkErrHttpUrlNotFound: number; - - /** - * Http 405 error response (0x00200195). - */ - static networkErrHttpNotAllowed: number; - - /** - * Http 410 error response (0x0020019A). - */ - static networkErrHttpGone: number; - - /** - * Http 412 error response (0x0020019C). - */ - static networkErrHttpPreconditionFailed: number; - - /** - * Http 500 error response (0x002001F4). - */ - static networkErrHttpInternalServerFailure: number; - - /** - * Http 502 error response (0x002001F6). - */ - static networkErrHttpBadGateway: number; - - /** - * Http 503 error response (0x002001F7). - */ - static networkErrHttpServiceUnavailable: number; - - /** - * Http 504 error response (0x002001F8). - */ - static networkErrHttpGatewayTimeout: number; - - /** - * Http error response end value (0x00200257). - */ - static networkErrHttpResponseEnd: number; - - /** - * Network timeout error (0x00200258). - */ - static networkErrTimeout: number; - - /** - * Connection error (0x00200259). - */ - static networkErrError: number; - - /** - * Request aborted (0x0020025A). - */ - static networkErrAbort: number; - - /** - * Client is offline (0x0020025B). - */ - static networkErrNoInternet: number; - - /** - * MEDIA_ERR_NETWORK errors end value (0x002FFFFF). - */ - static networkErrEnd: number; - - /** - * MEDIA_ERR_DECODE errors start value (0x00300000). - */ - static decodeErrStart: number; - - /** - * Generic decode error (0x00300000). - */ - static decodeErrUnknown: number; - - /** - * MEDIA_ERR_DECODE errors end value (0x003FFFFF). - */ - static decodeErrEnd: number; - - /** - * MEDIA_ERR_SRC_NOT_SUPPORTED errors start value (0x00400000). - */ - static srcErrStart: number; - - /** - * Generic source not supported error (0x00400000). - */ - static srcErrUnknown: number; - - /** - * Presentation parse error (0x00400001). - */ - static srcErrParsePresentation: number; - - /** - * Segment parse error (0x00400002). - */ - static srcErrParseSegment: number; - - /** - * Presentation not supported (0x00400003). - */ - static srcErrUnsupportedPresentation: number; - - /** - * Invalid segment (0x00400004). - */ - static srcErrInvalidSegment: number; - - /** - * Segments not available yet (0x00400005). - */ - static srcErrLiveNoSegments: number; - - /** - * MEDIA_ERR_SRC_NOT_SUPPORTED errors end value (0x004FFFFF). - */ - static srcErrEnd: number; - - /** - * MEDIA_ERR_ENCRYPTED errors start value (0x00500000). - */ - static encryptErrStart: number; - - /** - * Generic encrypted error (0x00500000). - */ - static encryptErrUnknown: number; - - /** - * Decryptor not found (0x00500001). - */ - static encryptErrDecrypterNotFound: number; - - /** - * Decryptor initialization error (0x00500002). - */ - static encryptErrDecrypterInit: number; - - /** - * Decryptor not supported (0x00500003). - */ - static encryptErrDecrypterNotSupported: number; - - /** - * Key acquire failed (0x00500004). - */ - static encryptErrKeyAcquire: number; - - /** - * Decryption of segment failed (0x00500005). - */ - static encryptErrDecryption: number; - - /** - * License acquire failed (0x00500006). - */ - static encryptErrLicenseAcquire: number; - - /** - * Certificate fetch failed (0x00500007). - */ - static encryptErrCertAcquire: number; - - /** - * MEDIA_ERR_ENCRYPTED errors end value (0x005FFFFF). - */ - static encryptErrEnd: number; - - /** - * SRC_PLAYER_MISMATCH errors start value (0x00600000). - */ - static srcPlayerMismatchStart: number; - - /** - * Generic source and tech player error (0x00600000). - */ - static srcPlayerMismatchUnknown: number; - - /** - * Flash plugin is not installed, if installed the source may play (0x00600001). - * Note: If 0x00600003, both Flash and Silverlight are not installed. - */ - static srcPlayerMismatchFlashNotInstalled: number; - - /** - * Silverlight plugin is not installed, if installed the source may play (0x00600002). - * Note: If 0x00600003, both Flash and Silverlight are not installed. - */ - static srcPlayerMismatchSilverlightNotInstalled: number; - - /** - * SRC_PLAYER_MISMATCH errors end value (0x006FFFFF). - */ - static srcPlayerMismatchEnd: number; - - /** - * Unknown errors (0x0FF00000). - */ - static errUnknown: number; - } - - - /** - * Downloadable media types for [[amp.Player.DownloadableMediaFile]] - */ - export class downloadableMediaType { - /** - * Media type is a video file - */ - static video: string; - - /** - * Media type is a video file with closed captions overlaid on the video - */ - static videoWithCC: string; - - /** - * Media type is an audio file - */ - static audio: string; - - /** - * Media type is a transcript file - */ - static transcript: string; - } - - /** - * Function to register plugins - */ - function plugin(name: string, init: Object): void; -} - -declare module mkioplayer.Player { - - /** - * Interface for the options of [[amp]] when it is created. - */ - interface Options { - /** - * Tech order for the player to decide on which tech to use. - */ - techOrder?: string[]; - - /** - * Set the autoplay for the next playback. - */ - autoplay?: boolean; - - /** - * Set whether the controls should be displayed. Default is false. - */ - controls?: boolean; - - /** - * Set whether the video should follow the width of its container while keeping - * the video aspect ratio. Default is false. - */ - fluid?: boolean; - - /** - * Sets the image that displays before the video begins playing. Defaults to no poster displayed. - */ - poster?: string; - - /** - * Sets the alt text for the img tag of the poster. Default is an empty string. - */ - posterAltString?: string; - - /** - * Set the configuration for the Tracing of [[amp]] - */ - traceConfig?: TraceConfig; - - /** - * Heuristics profile Name - */ - heuristicProfile?: string; - - /** - * custom Player settings. - * this is a JSON object. - * Ex: options.customPlayerSettings = { "customHeuristicSettings": { "windowSizeHeuristics": false } } - */ - customPlayerSettings?: any; - - /** - * Custom Player logo. - * Ex: logo: { enabled: true } - */ - logo?: LogoConfig; - - /** - * Skin configuration of [[amp]] - */ - skinConfig?: SkinConfig; - - /** - * List of sources. SDN plugins can modify source URLs using this field. - * SDN plugin can modify source URLs only after it catches [[amp.eventName.sourceset]] event triggered by AMP. - */ - sourceList?: Source[]; - - /** - * Current SDN plugin - */ - sdn?: SDN; - - /** - * Hot keys to control playback (volume, current time, toggle full screen) - */ - hotKeys?: HotKeys; - - /** - * Configuration options for playback speed control - */ - playbackSpeed?: PlaybackSpeedOptions; - - /** - * Plugin configuration. - */ - plugins?: any; - - /** - * CorsConfig to be used for request made by AzureMediaPlayer. - * Currently applied to all request [ Poster, TextTrack, Key, Fragments and Manifest ] for html5 tech. - * Applied to [ Poster, TextTrack ]in all other tech's. - */ - corsPolicy?: CorsConfig; - - /** - * Segment download response headers required. - * When provided downloadCompleted of BufferData would have a responseHeaders object containing the headers requested. - * Available only on AzureHtml5JS tech. - */ - headers?: string[]; - - /** - * Max time for stale data. Any Media data more then staleDataTimeLimitInSec behind - * current playback position is flushed. - * Disabled by default. - */ - staleDataTimeLimitInSec?: number; - - /** - * Boolean value specifying if audio should be muted at start. - */ - muted?: boolean; - - /** - * Configuration options for CEA708 closed captions - */ - cea708CaptionsSettings?: Cea708CaptionsSettings; - - /** - * Configuration options for IMSC1 captions - */ - imsc1CaptionsSettings?: Imsc1CaptionsSettings[]; - - /** - * Object specifying wall clock time display settings. - * If enabled, will display an overlay with the wall clock time, and change how the time is displayed on the control bar. - * Disabled by default. - */ - wallClockTimeDisplaySettings?: WallClockTimeDisplaySettings; - } - - /** - * Interface for the Logo of [[amp]] - */ - interface LogoConfig { - - /** - * Set if logo is displayed. Default is true. - */ - enabled?: boolean; - } - - /** - * Interface for the SkinConfig of [[amp]] - */ - interface SkinConfig { - - audioTracksMenu?: AudioTracksMenu; - } - - /** - * Interface for the AudioTracksMenu of [[amp]] - * Controls for multi-audio scenarios. - * Ex: audioTracksMenu: { enabled: true, useManifestForLabel: false } - */ - interface AudioTracksMenu { - - /** - * Set if audiotracks menu should be displayed on the default skin. Default is true. - * Note if there is only 1 audiostream no audio selection menu will be shown. - */ - enabled?: boolean; - - /** - * Set to turn off automatic label generation and use label from manifest. Default is false. - * When false, label shows language, bitrate and codec information if available and distinct - * When fields aren't available, stream will be called "Track {i}" - * When true, the label will use the audiostream name specified in the manifest - */ - useManifestForLabel ?: boolean; - } - - /** - * Interface for the Trace Configuration of [[amp]] - */ - interface TraceConfig { - - /** - * list of all the targets and its configuration for the Traces. - */ - TraceTargets?: TraceTarget[]; - - /** - * Set the trace level to log. Default value is 0. - * values: - * none = 0, - * error = 1, - * warning = 2, - * verbose = 3 - */ - maxLogLevel: number; - } - - /** - * Target location and the configuration for the Traces. - */ - interface TraceTarget { - - /** - * Target location for the Logs. - * Available targets are "console" or "memory" - */ - target: string; - - /** - * Max number of Traces. Only available for Memory Trace Target. - */ - maxMemoryTraceCount?: number; - } - - /** - * Heuristic profiles for [[amp]] - */ - export class HeuristicProfile { - - /** - * Profile that starts the playback as fast as possible. - * It also takes the width and height of the player into account when switching bitrates. - * For live streams this profile tries to stay close to the live edge. - */ - static QuickStart: string; - - /** - * Profile that tries to play highest quality possible. - * It builds the buffer to limit potential buffering. - * It does not take the width and height of the player into account when switching bitrates. - * For live streams this profile has a backoff from the live edge to avoid potential buffering. - */ - static HighQuality: string; - - /** - * Profile that tries to balance quality and speed. - * It builds the buffer more than QuickStart but less than HighQuality. - * It takes the width and height of the player into account when switching bitrates. - * For live streams this profile tries to stay close to the live edge. - * This is the default profile. - */ - static Hybrid: string; - - /** - * Profile designed to work alongside Azure Media Services low latency feature for live streaming. - * If low latency is not enabled on the stream, this heuristic profile will not yield a latency improvement. - */ - static LowLatency: string; - } - - /** - * Source object to hold the source information in [[Options]] and [[amp.Player.src]]. - */ - interface Source { - - /** - * Source Url - */ - src: string; - - /** - * Mime type (ex: "application/dash+xml", "video/mp4", "application/dash+xml", - * "application/vnd.apple.mpegurl"). - */ - type: string; - - /** - * Array of [[ProtectionInfo]] for the source - */ - protectionInfo?: ProtectionInfo[]; - - /** - * Streaming formats for the UrlRewiter to expand the sources from [Azure Media Services](http://azure.microsoft.com/en-us/services/media-services/) - * (ex: "SMOOTH", "DASH", "HLS-V3" and "HLS-V4"). - * Default is all the streaming formats supported by [Azure Media Services](http://azure.microsoft.com/en-us/services/media-services/). - */ - streamingFormats?: string[]; - - /** - * Disable UrlRewiter and use the given sources. - * Default is false, to perform the url rewriting. - */ - disableUrlRewriter?: boolean; - } - - /** - * Track object to hold the text track information in [[amp.Player.src]] - */ - interface Track { - - /** - * Type or category of the timed text track. [kind](http://www.w3.org/html/wg/drafts/html/master/semantics.html#attr-track-kind) - */ - kind: string; - - /** - * Label attribute to create a user readable title for the track. [label](http://www.w3.org/html/wg/drafts/html/master/semantics.html#attr-track-label) - */ - label: string; - - /** - * The address or Url of the media resource. [src](http://www.w3.org/html/wg/drafts/html/master/semantics.html#attr-track-label) - */ - src: string; - - /** - * The language of the text track data. [srclang](http://www.w3.org/html/wg/drafts/html/master/semantics.html#attr-track-srclang) - */ - srclang?: string; - } - - /** - * Interface for protection information of the [[Source]] - */ - interface ProtectionInfo { - - /** - * Protection type string. - * Use [[amp.protectionType]] for the list of protection types. - * ex: `amp.protectionType.AES` - */ - type: string; - - /** - * Authentication Token for the player. - */ - authenticationToken?: string; - - /** - * Certificate URL for Fairplay. - */ - certificateUrl?: string; - } - - /** - * Interface for SDN (Software-Defined Networking) - */ - interface SDN { - name: string; - } - - /** - * Interface for hot keys settings - */ - interface HotKeys { - - /** - * Volume change step - */ - volumeStep?: number; - - /** - * Seek step in seconds - */ - seekStep?: number; - - /** - * Flag to control whether muting is allowed - */ - enableMute?: boolean; - - /** - * Flag to control whether volume scrolling is allowed - */ - enableVolumeScroll?: boolean; - - /** - * Flag to control whether switching to fullscreen is allowed - */ - enableFullscreen?: boolean; - - /** - * Flag to control whether seeking to a percentage of a video by pressing number keys is allowed - */ - enableNumbers?: boolean; - - /** - * Flag to control whether seeking forth/back by 1 sec with up/down arrows is allowed - */ - enableJogStyle?: boolean; - } - - interface KeyValuePair { - name: string; - value: T; - } - - /** - * Interface for playback speeed control configuration options - */ - interface PlaybackSpeedOptions { - /** - * Enable playback speed control. Default is false. - */ - enabled?: boolean; - - /** - * Initial playback speed. Default is 1.0. - * Value must be between 0.5 and 4.0 inclusively. Invalid values are ignored, and initial speed will be set to default value of 1.0. - */ - initialSpeed?: number; - - /** - * Playback speed levels. - * Every element in the levels array specify name/value pair for the playback speed choice that will be available in the user selection menu. - * Default speed levels are: - * [{ name: '2.0x', value: 2}, - * { name: '1.0x', value: 1}, - * { name: '0.5x', value: 0.5}] - * values have to be between 0.5 and 4.0 inclusively. - */ - speedLevels?: KeyValuePair[]; - } - - /** - * Interface for downloadable media file - */ - interface DownloadableMediaFile { - /** - * The language of the downloadable media file in BCP47 format. Example: "en-us". [lang](https://tools.ietf.org/html/rfc5646) - */ - lang: string; - - /** - * Downloadable media file type. - * use [[amp.downloadableMediaType]] for the list of media file types. - * ex: `amp.downloadableMediaType.transcript` - */ - type: string; - - /** - * Optional media file bitrate, in bits per second. - */ - bitrate?: number; - - /** - * Optional media file size, in bytes. - */ - size?: number; - - /** - * Uri of the downloadable media file. - */ - uri: string; - } - - /** - * Interface for CEA708 captions configuration options - */ - interface Cea708CaptionsSettings { - /** - * Enable CEA708 auto-parsing. Default is false. - */ - enabled?: boolean; - - /** - * Label attribute to create a user readable title for the track. [label](http://www.w3.org/html/wg/drafts/html/master/semantics.html#attr-track-label) - */ - label: string; - - /** - * The language of the text track data. [srclang](http://www.w3.org/html/wg/drafts/html/master/semantics.html#attr-track-srclang) - */ - srclang?: string; - } - - /** - * Interface for IMSC1 captions configuration options - */ - interface Imsc1CaptionsSettings { - /** - * Label attribute to create a user readable title for the track. Cannot be empty. [label](http://www.w3.org/html/wg/drafts/html/master/semantics.html#attr-track-label) - */ - label: string; - - /** - * The language of the text track data. Can be empty. It needs to match the value of the xml:lang tag in the IMSC1. Example: "en-us". [srclang](http://www.w3.org/html/wg/drafts/html/master/semantics.html#attr-track-srclang) - */ - srclang: string; - } - - /** - * Interface for wall clock time display settings - */ - interface WallClockTimeDisplaySettings { - /** - * Enable display of wall clock time. Default is false. - */ - enabled: boolean; - - /** - * Boolean specifying if to use local client time zone. If true, ignores timezone parameter. Default is false. - */ - useLocalTimeZone?: boolean; - - /** - * Number specifying a time zone to display wall clock time in. Ex: -8 is Pacific Standard Time. Default is 0 (UTC) - */ - timezone?: number; - - /* - * Boolean specifying if the time shown in the control bar will be displayed in 12-hour am/pm format or 24-hour format. Default is true. - */ - controlBar12HourFormat?: boolean; - } -} - -/** - * FlashSS tech options. - */ -declare module mkioplayer.options.flashSS { - - /** - * Url to Strobe media player - */ - export var swf: string; - - /** - * Url to the AdaptiveStreaming plugin for OSMF. - */ - export var plugin: string; -} - -/** - * SilverlightSS tech options - */ -declare module mkioplayer.options.silverlightSS { - - /** - * Url to the silverlight player - */ - export var xap: string; -} - -/** - * AzureHtml5JS tech options - */ -declare module mkioplayer.options.azureHtml5JS { - - /** - * Number of segments to skip in case of http errors - */ - export var maxSkipSegments: number; - - /** - * Number of total retries in case of http errors - */ - export var maxTotalRetries: number; - - /** - * Number of retries for each segment in case of http errors - */ - export var maxRetryPerSegment: number; - - /** - * Number of retries for key requests in case of http errors - */ - export var maxRetriesForKeyAcquireFailure: number; - - /** - * Wait time between retrying for another key acquire request - */ - export var maxWaitTimeBetweenRetriesForKeyAcquireMS: number; -} - -/** - * The main function for users to create a player instance - * - * The `amp` function can be used to initialize or retrieve a player. - * - * ##### Example: - * var myPlayer = amp('my_video_id'); - * - * @param id Video element or video element ID string - * @param options Optional options object for config/settings - * @param ready Optional ready handler - * @return Player instance - */ -declare function mkioplayer(id: any, options?: mkioplayer.Player.Options, ready?: Function): mkioplayer.Player; - diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkiomediaplayer.ts b/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkiomediaplayer.ts new file mode 100644 index 000000000..17c48d8fb --- /dev/null +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkiomediaplayer.ts @@ -0,0 +1,84 @@ +import { MKPlayer, MKPlayerConfig } from '@mediakind/mkplayer'; + +interface ClearKeyConfig { + LA_URL: string; + headers: { + Authorization: string; + }; +} + +interface PlayerConfig { + key: string; + ui: boolean; + theme: string; + playback: { + muted: boolean; + autoplay: boolean; + preferredTech: Array<{ player: string; streaming: string }>; + }; + events: { + ready: () => void; + subtitleadded: () => void; + // Add other event handlers as needed + }; +} + +interface SourceConfig { + hls: string; + drm: { + clearkey: ClearKeyConfig; + }; +} + +function getBearerToken(): string { + // Replace this with your actual logic to get the bearer token + return "your_bearer_token_here"; +} + +function getClearKeyConfig(): ClearKeyConfig { + return { + LA_URL: "HLS_AES", + headers: { + Authorization: getBearerToken() + } + }; +} + +function getPlayerConfig(mkioKey: string, onPlayerReady: () => void, onSubtitleAdded: () => void): PlayerConfig { + return { + key: mkioKey, + ui: true, + theme: "dark", + playback: { + muted: false, + autoplay: false, + preferredTech: [{ player: "Html5", streaming: "Hls" }] // Adjust these strings if you have specific types + }, + events: { + ready: onPlayerReady, + subtitleadded: onSubtitleAdded + } + }; +} + +function initializePlayer(videoContainer: HTMLElement, playerConfig: MKPlayerConfig, playBackUrl: string): any { + const player = new MKPlayer(videoContainer, playerConfig); + const sourceConfig: SourceConfig = { + hls: playBackUrl, + drm: { + clearkey: getClearKeyConfig() + } + }; + + player.load(sourceConfig) + .then(() => { + console.log("Source loaded successfully!"); + }) + .catch(() => { + console.error("An error occurred while loading the source!"); + }); + + return player; +} + +export { getPlayerConfig, initializePlayer }; diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue index 435dc8a1f..73dc8e5c1 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue @@ -236,24 +236,24 @@ methods: { onPlayerReady() { - const videoElement = document.getElementById("bitmovinplayer-video-resourceMediaPlayer") as HTMLVideoElement; - if (videoElement) { - videoElement.controls = true; - - // Add the track element - var captionsInfo = this.resourceItem.videoDetails.closedCaptionsFile; - if (captionsInfo) { - const trackElement = document.createElement('track'); - var srcPath = this.getFileLink(captionsInfo.filePath, captionsInfo.fileName); - trackElement.kind = 'captions'; // Or 'subtitles' or 'descriptions' depending on your track type - trackElement.label = captionsInfo.language || 'english'; - trackElement.srclang = captionsInfo.language || 'en'; - trackElement.src = srcPath; - - // Append the track to the video element - videoElement.appendChild(trackElement); - } - } + //const videoElement = document.getElementById("bitmovinplayer-video-resourceMediaPlayer") as HTMLVideoElement; + //if (videoElement) { + // videoElement.controls = true; + + // // Add the track element + // var captionsInfo = this.resourceItem.videoDetails.closedCaptionsFile; + // if (captionsInfo) { + // const trackElement = document.createElement('track'); + // var srcPath = this.getFileLink(captionsInfo.filePath, captionsInfo.fileName); + // trackElement.kind = 'captions'; // Or 'subtitles' or 'descriptions' depending on your track type + // trackElement.label = captionsInfo.language || 'english'; + // trackElement.srclang = captionsInfo.language || 'en'; + // trackElement.src = srcPath; + + // // Append the track to the video element + // videoElement.appendChild(trackElement); + // } + //} this.checkForAutoplay(this.player); }, @@ -276,7 +276,7 @@ // Prepare the player configuration const playerConfig = { key: this.mkioKey, - ui: false, + ui: true, theme: "dark", playback: { muted: false, @@ -845,13 +845,13 @@ box-shadow: 0 -2px $govuk-focus-highlight-yellow,0 4px $nhsuk-black; } - .video-container { + /*.video-container { height: 0; width: 100%; overflow: hidden; position: relative; - padding-top: 56.25%; /* 16:9 aspect ratio */ - background-color: #000; + padding-top: 56.25%;*/ /* 16:9 aspect ratio */ + /*background-color: #000; } video { @@ -864,5 +864,5 @@ video[id^="bitmovinplayer-video"] { width: 100%; - } + }*/ diff --git a/LearningHub.Nhs.WebUI/Views/ContributeResource/ContributeResource.cshtml b/LearningHub.Nhs.WebUI/Views/ContributeResource/ContributeResource.cshtml index 292cbe141..0c421eb93 100644 --- a/LearningHub.Nhs.WebUI/Views/ContributeResource/ContributeResource.cshtml +++ b/LearningHub.Nhs.WebUI/Views/ContributeResource/ContributeResource.cshtml @@ -2,7 +2,7 @@ ViewData["Title"] = "Contribute a Resource"; } @section styles { - + @* *@ }
@@ -12,5 +12,5 @@ @section Scripts{ - + @* *@ } diff --git a/LearningHub.Nhs.WebUI/Views/CovidTesting/_CovidTestingLayout.cshtml b/LearningHub.Nhs.WebUI/Views/CovidTesting/_CovidTestingLayout.cshtml index 09d7e46cb..2bcdb92f2 100644 --- a/LearningHub.Nhs.WebUI/Views/CovidTesting/_CovidTestingLayout.cshtml +++ b/LearningHub.Nhs.WebUI/Views/CovidTesting/_CovidTestingLayout.cshtml @@ -9,7 +9,7 @@ - + @* *@ @@ -69,7 +69,7 @@ - + @* *@ @RenderSection("Scripts", required: false) diff --git a/LearningHub.Nhs.WebUI/Views/Home/GenericTray.cshtml b/LearningHub.Nhs.WebUI/Views/Home/GenericTray.cshtml index a3ff92079..cae74c3a1 100644 --- a/LearningHub.Nhs.WebUI/Views/Home/GenericTray.cshtml +++ b/LearningHub.Nhs.WebUI/Views/Home/GenericTray.cshtml @@ -3,7 +3,7 @@ } @section styles { - + @* *@ }
@@ -12,7 +12,7 @@ @section Scripts{ - + @* *@ @* @if (Model != null) @@ -50,7 +53,7 @@ } *@
- \ No newline at end of file diff --git a/LearningHub.Nhs.WebUI/Views/Shared/Tenant/LearningHub/_Layout.cshtml b/LearningHub.Nhs.WebUI/Views/Shared/Tenant/LearningHub/_Layout.cshtml index 146164a7e..a0aa46f2a 100644 --- a/LearningHub.Nhs.WebUI/Views/Shared/Tenant/LearningHub/_Layout.cshtml +++ b/LearningHub.Nhs.WebUI/Views/Shared/Tenant/LearningHub/_Layout.cshtml @@ -148,6 +148,7 @@ @RenderSection("Scripts", required: false) + diff --git a/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js b/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js new file mode 100644 index 000000000..78f402919 --- /dev/null +++ b/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js @@ -0,0 +1,75 @@ +/** + * Constructs and configures the control bar for the UI. + * + * This function performs the following tasks: + * 1. Selects the titlebar and controlbar elements from the DOM. + * 2. Creates a playback toggle button with an initial "Play" state and appends it to the controlbar. + * 3. Adds an event listener to the playback toggle button to handle play/pause functionality. + * 4. Retrieves all buttons from the titlebar, aligns them to the right (except for the "Mute" button), and appends them to the controlbar. + * 5. Selects the UI container element and sets up a MutationObserver to monitor changes in the container's class attribute. + * 6. Updates the playback toggle button state based on the player's state (playing or paused) when the container's class changes. + */ + +function buildControlbar(id) { + var mediacontainerId = 'mediaContainer-' + id; + + // Select the titlebar and controlbar elements from the DOM + let titlebar = document.querySelector(`#${mediacontainerId} .bmpui-ui-titlebar`); + let controlbar = document.querySelector(`#${mediacontainerId} .bmpui-ui-controlbar`); + debugger; + // Check if both titlebar and controlbar elements exist + if (titlebar && controlbar) { + + // Create a playback toggle button and set its initial state and appearance + let playbackToggleButton = document.createElement('button'); + playbackToggleButton.classList.add('bmpui-ui-playbacktogglebutton', 'bmpui-off'); + playbackToggleButton.setAttribute('aria-label', 'Play'); + playbackToggleButton.innerHTML = 'Play'; + controlbar.appendChild(playbackToggleButton); + + // Add an event listener to the playback toggle button + playbackToggleButton.addEventListener('click', function () { + // Toggle playback state based on the current state + if (player.isPlaying()) { + player.pause(); + playbackToggleButton.classList.add('bmpui-off'); + playbackToggleButton.classList.remove('bmpui-on'); + playbackToggleButton.innerHTML = 'Play'; + } else { + player.play(); + playbackToggleButton.classList.add('bmpui-on'); + playbackToggleButton.classList.remove('bmpui-off'); + playbackToggleButton.innerHTML = 'Pause'; + } + }); + + // Get all button elements from the titlebar + let buttons = titlebar.querySelectorAll('button'); + + // Reverse the button list and append each button to the controlbar + Array.from(buttons).reverse().forEach(button => { + if (button.textContent != "Mute") { + button.classList.add('control-right'); // Add a class to align buttons to the right + } + controlbar.appendChild(button); // Append the button to the controlbar + }); + + // Select the UI container element + let uiContainerElement = document.querySelector(`#${mediacontainerId} .bmpui-ui-uicontainer`); + + uiContainerElement.addEventListener('click', function () { + // Update the playback toggle button state based on the player's state + if (uiContainerElement.classList.contains('bmpui-player-state-paused')) { + playbackToggleButton.classList.add('bmpui-off'); + playbackToggleButton.classList.remove('bmpui-on'); + } else { + playbackToggleButton.classList.add('bmpui-on'); + playbackToggleButton.classList.remove('bmpui-off'); + } + }); + + } + else { + console.error('UI container element not found'); + } +} From bafb166334d455287f7cc5878c737df8670fe41e Mon Sep 17 00:00:00 2001 From: binon Date: Fri, 13 Sep 2024 10:15:22 +0100 Subject: [PATCH 04/27] New player UI, sorted play pause issuse --- .../Views/Home/_CmsVideo.cshtml | 9 +++++--- .../wwwroot/js/mkplayer-ui-custom.js | 23 ++++++++++--------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/LearningHub.Nhs.WebUI/Views/Home/_CmsVideo.cshtml b/LearningHub.Nhs.WebUI/Views/Home/_CmsVideo.cshtml index 2a6990458..37da5280a 100644 --- a/LearningHub.Nhs.WebUI/Views/Home/_CmsVideo.cshtml +++ b/LearningHub.Nhs.WebUI/Views/Home/_CmsVideo.cshtml @@ -56,7 +56,7 @@ diff --git a/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js b/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js index 78f402919..031e2c705 100644 --- a/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js +++ b/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js @@ -10,13 +10,13 @@ * 6. Updates the playback toggle button state based on the player's state (playing or paused) when the container's class changes. */ -function buildControlbar(id) { +function buildControlbar(id, player) { var mediacontainerId = 'mediaContainer-' + id; // Select the titlebar and controlbar elements from the DOM let titlebar = document.querySelector(`#${mediacontainerId} .bmpui-ui-titlebar`); let controlbar = document.querySelector(`#${mediacontainerId} .bmpui-ui-controlbar`); - debugger; + // Check if both titlebar and controlbar elements exist if (titlebar && controlbar) { @@ -25,6 +25,7 @@ function buildControlbar(id) { playbackToggleButton.classList.add('bmpui-ui-playbacktogglebutton', 'bmpui-off'); playbackToggleButton.setAttribute('aria-label', 'Play'); playbackToggleButton.innerHTML = 'Play'; + playbackToggleButton.id = 'playback-toggle-btn-' + id; controlbar.appendChild(playbackToggleButton); // Add an event listener to the playback toggle button @@ -32,13 +33,13 @@ function buildControlbar(id) { // Toggle playback state based on the current state if (player.isPlaying()) { player.pause(); - playbackToggleButton.classList.add('bmpui-off'); playbackToggleButton.classList.remove('bmpui-on'); + playbackToggleButton.classList.add('bmpui-off'); playbackToggleButton.innerHTML = 'Play'; } else { player.play(); - playbackToggleButton.classList.add('bmpui-on'); playbackToggleButton.classList.remove('bmpui-off'); + playbackToggleButton.classList.add('bmpui-on'); playbackToggleButton.innerHTML = 'Pause'; } }); @@ -55,16 +56,16 @@ function buildControlbar(id) { }); // Select the UI container element - let uiContainerElement = document.querySelector(`#${mediacontainerId} .bmpui-ui-uicontainer`); - - uiContainerElement.addEventListener('click', function () { + let uiOverlayElement = document.querySelector(`#${mediacontainerId} .bmpui-ui-playbacktoggle-overlay`); + uiOverlayElement.addEventListener('click', function () { + let uiContainerElement = document.querySelector(`#${mediacontainerId} .bmpui-ui-uicontainer`); // Update the playback toggle button state based on the player's state if (uiContainerElement.classList.contains('bmpui-player-state-paused')) { - playbackToggleButton.classList.add('bmpui-off'); - playbackToggleButton.classList.remove('bmpui-on'); - } else { - playbackToggleButton.classList.add('bmpui-on'); playbackToggleButton.classList.remove('bmpui-off'); + playbackToggleButton.classList.add('bmpui-on'); + } else { + playbackToggleButton.classList.remove('bmpui-on'); + playbackToggleButton.classList.add('bmpui-off'); } }); From 05e2515603d9d2760b5e0b2c7c89c093919605cd Mon Sep 17 00:00:00 2001 From: binon Date: Fri, 13 Sep 2024 23:09:27 +0100 Subject: [PATCH 05/27] MKPLayer implementation in Admin page --- .../Scripts/vuesrc/content/cmsPageRow.vue | 54 ++++++++++++- .../Scripts/vuesrc/mkioplayer-controlbar.ts | 77 +++++++++++++++++++ 2 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/mkioplayer-controlbar.ts diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue index dd02810f7..ae3ee9e39 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue +++ b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue @@ -71,6 +71,8 @@ import { AzureMediaAssetModel } from '../models/content/videoAssetModel'; import { MKPlayer } from '@mediakind/mkplayer'; import { MKPlayerType, MKStreamType } from '../MKPlayerConfigEnum'; + //import { getPlayerConfig, getSourceConfig, initializePlayer } from '../mkiomediaplayer'; + import { buildControlbar } from '../mkioplayer-controlbar'; export default Vue.extend({ props: { @@ -91,7 +93,7 @@ mkioKey: '', }; }, - async created(): Promise { + async created(): Promise { await this.getMKIOPlayerKey(); this.load(); this.getDisplayAVFlag(); @@ -168,11 +170,36 @@ this.audioVideoUnavailableView = response; }); }, + onSubtitleAdded() { + this.player.subtitles.enable("subtitle" + this.section.id.toString()); + }, onPlayerReady() { const videoElement = document.getElementById("bitmovinplayer-video-" + this.getPlayerUniqueId) as HTMLVideoElement; if (videoElement) { videoElement.controls = true; } + + var subtitleTrack; + //if (this.pageSectionDetail.videoAsset.azureMediaAsset && this.pageSectionDetail.videoAsset.closedCaptionsFile) { + // const captionsInfo = this.pageSectionDetail.videoAsset.closedCaptionsFile; + // var srcPath = "file/download/" + captionsInfo.filePath + "/" + captionsInfo.fileName; + // //srcPath = '@requestURL' + srcPath; + // srcPath = "https://bitdash-a.akamaihd.net/content/sintel/subtitles/subtitles_en.vtt"; + + // subtitleTrack = { + // id: "subtitle" + this.section.id.toString(), + // lang: "en", + // label: "english", + // url: srcPath, + // kind: "subtitle" + // }; + //}; + + //this.player.addSubtitle(subtitleTrack); + + var contanierId = this.section.id.toString();; + var uniquePlayer = this.player;// (player_@Model.Id); + buildControlbar(contanierId, uniquePlayer); }, async getMKIOPlayerKey(): Promise { this.mkioKey = await contentData.getMKPlayerKey(); @@ -189,7 +216,7 @@ // Grab the video container this.videoContainer = document.getElementById(this.getPlayerUniqueId); - if(!this.mkioKey) { + if (!this.mkioKey) { this.getMKIOPlayerKey(); } @@ -205,15 +232,34 @@ theme: "dark", events: { ready: this.onPlayerReady, + subtitleadded: this.onSubtitleAdded, } }; // Initialize the player with video container and player configuration this.player = new MKPlayer(this.videoContainer, playerConfig); + //var subtitleTrack; + //debugger; + //if (this.pageSectionDetail.videoAsset.azureMediaAsset && this.pageSectionDetail.videoAsset.closedCaptionsFile) { + // const captionsInfo = this.pageSectionDetail.videoAsset.closedCaptionsFile; + // var srcPath = "file/download/" + captionsInfo.filePath + "/" + captionsInfo.fileName; + // //srcPath = '@requestURL' + srcPath; + // srcPath = "https://bitdash-a.akamaihd.net/content/sintel/subtitles/subtitles_en.vtt"; + + // subtitleTrack = { + // id: "subtitle" + this.section.id.toString(), + // lang: "en", + // label: "english", + // url: srcPath, + // kind: "subtitle" + // }; + //}; + // Load source const sourceConfig = { hls: this.getMediaPlayUrl(this.pageSectionDetail.videoAsset.azureMediaAsset.locatorUri), + //subtitleTracks: subtitleTrack, drm: { clearkey: { LA_URL: "HLS_AES", @@ -318,4 +364,8 @@ video[id^="bitmovinplayer-video"] { width: 100%; } + + .bmpui-ui-controlbar .control-right { + float: right; + } \ No newline at end of file diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/mkioplayer-controlbar.ts b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/mkioplayer-controlbar.ts new file mode 100644 index 000000000..a9db5fb13 --- /dev/null +++ b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/mkioplayer-controlbar.ts @@ -0,0 +1,77 @@ +/** + * Constructs and configures the control bar for the UI. + * + * This function performs the following tasks: + * 1. Selects the titlebar and controlbar elements from the DOM. + * 2. Creates a playback toggle button with an initial "Play" state and appends it to the controlbar. + * 3. Adds an event listener to the playback toggle button to handle play/pause functionality. + * 4. Retrieves all buttons from the titlebar, aligns them to the right (except for the "Mute" button), and appends them to the controlbar. + * 5. Selects the UI container element and sets up a MutationObserver to monitor changes in the container's class attribute. + * 6. Updates the playback toggle button state based on the player's state (playing or paused) when the container's class changes. + */ + +function buildControlbar(id: string, player: { isPlaying: () => boolean; pause: () => void; play: () => void; }): void { + const mediacontainerId = 'videoContainer_' + id; + + // Select the titlebar and controlbar elements from the DOM + const titlebar = document.querySelector(`#${mediacontainerId} .bmpui-ui-titlebar`) as HTMLElement; + const controlbar = document.querySelector(`#${mediacontainerId} .bmpui-ui-controlbar`) as HTMLElement; + + // Check if both titlebar and controlbar elements exist + if (titlebar && controlbar) { + + // Create a playback toggle button and set its initial state and appearance + const playbackToggleButton = document.createElement('button'); + playbackToggleButton.classList.add('bmpui-ui-playbacktogglebutton', 'bmpui-off'); + playbackToggleButton.setAttribute('aria-label', 'Play'); + playbackToggleButton.innerHTML = 'Play'; + playbackToggleButton.id = 'playback-toggle-btn-' + id; + controlbar.appendChild(playbackToggleButton); + + // Add an event listener to the playback toggle button + playbackToggleButton.addEventListener('click', function () { + // Toggle playback state based on the current state + if (player.isPlaying()) { + player.pause(); + playbackToggleButton.classList.remove('bmpui-on'); + playbackToggleButton.classList.add('bmpui-off'); + playbackToggleButton.innerHTML = 'Play'; + } else { + player.play(); + playbackToggleButton.classList.remove('bmpui-off'); + playbackToggleButton.classList.add('bmpui-on'); + playbackToggleButton.innerHTML = 'Pause'; + } + }); + + // Get all button elements from the titlebar + const buttons = titlebar.querySelectorAll('button'); + + // Reverse the button list and append each button to the controlbar + Array.from(buttons).reverse().forEach(button => { + if (button.textContent !== "Mute") { + button.classList.add('control-right'); // Add a class to align buttons to the right + } + controlbar.appendChild(button); // Append the button to the controlbar + }); + + // Select the UI container element + const uiOverlayElement = document.querySelector(`#${mediacontainerId} .bmpui-ui-playbacktoggle-overlay`) as HTMLElement; + uiOverlayElement.addEventListener('click', function () { + const uiContainerElement = document.querySelector(`#${mediacontainerId} .bmpui-ui-uicontainer`) as HTMLElement; + // Update the playback toggle button state based on the player's state + if (uiContainerElement.classList.contains('bmpui-player-state-playing')) { + playbackToggleButton.classList.remove('bmpui-on'); + playbackToggleButton.classList.add('bmpui-off'); + } else { + playbackToggleButton.classList.remove('bmpui-off'); + playbackToggleButton.classList.add('bmpui-on'); + } + }); + + } else { + console.error('UI container element not found'); + } +} + +export { buildControlbar }; \ No newline at end of file From ca95e97572a66d39a9a60a5241b5d4b44973e509 Mon Sep 17 00:00:00 2001 From: binon Date: Sat, 14 Sep 2024 02:06:10 +0100 Subject: [PATCH 06/27] New MKPlayer Changes in Resource page --- .../Scripts/vuesrc/mkioplayer-controlbar.ts | 75 +++++++++++++++++++ .../vuesrc/resource/ResourceContent.vue | 8 +- .../wwwroot/js/mkplayer-ui-custom.js | 2 +- 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 LearningHub.Nhs.WebUI/Scripts/vuesrc/mkioplayer-controlbar.ts diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkioplayer-controlbar.ts b/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkioplayer-controlbar.ts new file mode 100644 index 000000000..68cecf3f5 --- /dev/null +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkioplayer-controlbar.ts @@ -0,0 +1,75 @@ +/** + * Constructs and configures the control bar for the UI. + * + * This function performs the following tasks: + * 1. Selects the titlebar and controlbar elements from the DOM. + * 2. Creates a playback toggle button with an initial "Play" state and appends it to the controlbar. + * 3. Adds an event listener to the playback toggle button to handle play/pause functionality. + * 4. Retrieves all buttons from the titlebar, aligns them to the right (except for the "Mute" button), and appends them to the controlbar. + * 5. Selects the UI container element and sets up a MutationObserver to monitor changes in the container's class attribute. + * 6. Updates the playback toggle button state based on the player's state (playing or paused) when the container's class changes. + */ + +function MKPlayerControlbar(playerContainerId: string, player: { isPlaying: () => boolean; pause: () => void; play: () => void; }): void { + // Select the titlebar and controlbar elements from the DOM + const titlebar = document.querySelector(`#${playerContainerId} .bmpui-ui-titlebar`) as HTMLElement; + const controlbar = document.querySelector(`#${playerContainerId} .bmpui-ui-controlbar`) as HTMLElement; + + // Check if both titlebar and controlbar elements exist + if (titlebar && controlbar) { + + // Create a playback toggle button and set its initial state and appearance + const playbackToggleButton = document.createElement('button'); + playbackToggleButton.classList.add('bmpui-ui-playbacktogglebutton', 'bmpui-off'); + playbackToggleButton.setAttribute('aria-label', 'Play'); + playbackToggleButton.innerHTML = 'Play'; + playbackToggleButton.id = 'playback-toggle-btn-' + playerContainerId; + controlbar.appendChild(playbackToggleButton); + + // Add an event listener to the playback toggle button + playbackToggleButton.addEventListener('click', function () { + // Toggle playback state based on the current state + if (player.isPlaying()) { + player.pause(); + playbackToggleButton.classList.remove('bmpui-on'); + playbackToggleButton.classList.add('bmpui-off'); + playbackToggleButton.innerHTML = 'Play'; + } else { + player.play(); + playbackToggleButton.classList.remove('bmpui-off'); + playbackToggleButton.classList.add('bmpui-on'); + playbackToggleButton.innerHTML = 'Pause'; + } + }); + + // Get all button elements from the titlebar + const buttons = titlebar.querySelectorAll('button'); + + // Reverse the button list and append each button to the controlbar + Array.from(buttons).reverse().forEach(button => { + if (button.textContent !== "Mute") { + button.classList.add('control-right'); // Add a class to align buttons to the right + } + controlbar.appendChild(button); // Append the button to the controlbar + }); + + // Select the UI container element + const uiOverlayElement = document.querySelector(`#${playerContainerId} .bmpui-ui-playbacktoggle-overlay`) as HTMLElement; + uiOverlayElement.addEventListener('click', function () { + const uiContainerElement = document.querySelector(`#${playerContainerId} .bmpui-ui-uicontainer`) as HTMLElement; + // Update the playback toggle button state based on the player's state + if (uiContainerElement.classList.contains('bmpui-player-state-playing')) { + playbackToggleButton.classList.remove('bmpui-on'); + playbackToggleButton.classList.add('bmpui-off'); + } else { + playbackToggleButton.classList.remove('bmpui-off'); + playbackToggleButton.classList.add('bmpui-on'); + } + }); + + } else { + console.error('UI container element not found'); + } +} + +export { MKPlayerControlbar }; \ No newline at end of file diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue index 73dc8e5c1..00e382b47 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue @@ -101,6 +101,7 @@ import { setResourceCetificateLink } from './helpers/resourceCertificateHelper'; import { MKPlayer } from '@mediakind/mkplayer'; import { MKPlayerType, MKStreamType } from '../MKPlayerConfigEnum'; + import { MKPlayerControlbar } from '../mkioplayer-controlbar'; Vue.use(Vuelidate as any); @@ -255,6 +256,8 @@ // } //} + MKPlayerControlbar("mediacontainer", this.player); + this.checkForAutoplay(this.player); }, onpause() { @@ -837,6 +840,9 @@ // NOTE: Not `scoped` because we want this section to apply to children @use '../../../Styles/abstracts/all' as *; + .bmpui-ui-controlbar .control-right { + float: right; + } .accessible-link:focus { outline: none; text-decoration: none; @@ -851,7 +857,7 @@ overflow: hidden; position: relative; padding-top: 56.25%;*/ /* 16:9 aspect ratio */ - /*background-color: #000; + /*background-color: #000; } video { diff --git a/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js b/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js index 031e2c705..6fe5871a8 100644 --- a/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js +++ b/LearningHub.Nhs.WebUI/wwwroot/js/mkplayer-ui-custom.js @@ -60,7 +60,7 @@ function buildControlbar(id, player) { uiOverlayElement.addEventListener('click', function () { let uiContainerElement = document.querySelector(`#${mediacontainerId} .bmpui-ui-uicontainer`); // Update the playback toggle button state based on the player's state - if (uiContainerElement.classList.contains('bmpui-player-state-paused')) { + if (uiContainerElement.classList.contains('bmpui-player-state-playing')) { playbackToggleButton.classList.remove('bmpui-off'); playbackToggleButton.classList.add('bmpui-on'); } else { From 47663a9061690901b3e3876c1923f653287761fa Mon Sep 17 00:00:00 2001 From: binon Date: Mon, 16 Sep 2024 08:58:23 +0100 Subject: [PATCH 07/27] New Player update in case/assement page --- .../components/MKIOVideoPlayer.vue | 65 ++++++++++++++++++- .../Scripts/vuesrc/mkioplayer-controlbar.ts | 5 +- .../vuesrc/resource/ResourceContent.vue | 2 +- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/components/MKIOVideoPlayer.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/components/MKIOVideoPlayer.vue index fe5b69ba3..94fce13e8 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/components/MKIOVideoPlayer.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/components/MKIOVideoPlayer.vue @@ -34,6 +34,7 @@ import { MKPlayer } from '@mediakind/mkplayer'; import { resourceData } from '../../data/resource'; import { MKPlayerType, MKStreamType } from '../../MKPlayerConfigEnum'; + import { MKPlayerControlbar } from '../../mkioplayer-controlbar'; //import { MKPlayerType } from '@mediakind/mkplayer/types/enums/MKPlayerType.d'; //import { MKStreamType } from '@mediakind/mkplayer/types/enums/MKStreamType.d'; export default Vue.extend({ @@ -58,6 +59,7 @@ }, methods: { onPlayerReady() { + MKPlayerControlbar(this.player.videoContainer.id, this.player); const videoElement = document.getElementById("bitmovinplayer-video-" + this.getPlayerUniqueId) as HTMLVideoElement; if (videoElement) { videoElement.controls = true; @@ -94,7 +96,6 @@ // Grab the video container this.videoContainer = document.getElementById(this.getPlayerUniqueId); - if (!this.mkioKey) { this.getMKIOPlayerKey(); } @@ -102,7 +103,7 @@ // Prepare the player configuration const playerConfig = { key: this.mkioKey, - ui: false, + ui: true, theme: "dark", playback: { muted: false, @@ -196,4 +197,64 @@ video[id^="bitmovinplayer-video"] { width: 100%; } + + .bmpui-ui-controlbar .control-right { + float: right; + } + + /* Base styles for video container */ + .video-container { + width: 100%; + margin: auto; + position: relative; + --min-width: 0px; /* default value */ + } + + /* Media queries to set different min-width values */ + @media (min-width: 576px) { + .video-container { + --min-width: 576px; + } + } + + @media (min-width: 768px) { + .video-container { + --min-width: 768px; + } + } + + @media (min-width: 992px) { + .video-container { + --min-width: 992px; + } + } + + @media (min-width: 1024px) { + .video-container { + --min-width: 1024px; + } + } + + /* Applying min-width to the video container using the CSS variable */ + .video-container { + min-width: var(--min-width) !important; + } + + /* Targeting specific div with dynamic ID pattern */ + [id^="videoContainer_"] { + min-width: var(--min-width) !important; /* Inheriting min-width */ + } + + /* Example child element inheriting min-width from video container */ + .video-container .child-element { + min-width: var(--min-width) !important; + padding: 10px; + text-align: center; + } + + /* Style for the video element */ + .video-container video { + width: 100%; + height: auto; + } diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkioplayer-controlbar.ts b/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkioplayer-controlbar.ts index 68cecf3f5..d1e0223e5 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkioplayer-controlbar.ts +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/mkioplayer-controlbar.ts @@ -9,9 +9,10 @@ * 5. Selects the UI container element and sets up a MutationObserver to monitor changes in the container's class attribute. * 6. Updates the playback toggle button state based on the player's state (playing or paused) when the container's class changes. */ - -function MKPlayerControlbar(playerContainerId: string, player: { isPlaying: () => boolean; pause: () => void; play: () => void; }): void { +import { MKPlayer, MKPlayerConfig } from '@mediakind/mkplayer'; +function MKPlayerControlbar(playerContainerId: string, player: MKPlayer): void { // Select the titlebar and controlbar elements from the DOM + const titlebar = document.querySelector(`#${playerContainerId} .bmpui-ui-titlebar`) as HTMLElement; const controlbar = document.querySelector(`#${playerContainerId} .bmpui-ui-controlbar`) as HTMLElement; diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue index 00e382b47..29dc93a98 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue @@ -256,7 +256,7 @@ // } //} - MKPlayerControlbar("mediacontainer", this.player); + MKPlayerControlbar(this.player.videoContainer.id, this.player); this.checkForAutoplay(this.player); }, From 2fae38d3115ffae7340b551cc5a5ed875d3c2606 Mon Sep 17 00:00:00 2001 From: binon Date: Mon, 16 Sep 2024 15:08:54 +0100 Subject: [PATCH 08/27] Fixed some of the resolution issues --- .../Scripts/vuesrc/content/cmsPageRow.vue | 49 ++++++++++--------- .../vuesrc/resource/ResourceContent.vue | 43 +++++++--------- 2 files changed, 45 insertions(+), 47 deletions(-) diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue index ae3ee9e39..ae0ea6c25 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue +++ b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue @@ -91,6 +91,7 @@ player: null, videoContainer: null, mkioKey: '', + requestURL: '' }; }, async created(): Promise { @@ -99,6 +100,9 @@ this.getDisplayAVFlag(); this.getAudioVideoUnavailableView(); }, + mounted() { + this.requestURL = window.location.origin; + }, computed: { getStyle() { console.log("getLinkStyle", (this.pageSectionDetail || {}).draftHidden); @@ -170,16 +174,16 @@ this.audioVideoUnavailableView = response; }); }, - onSubtitleAdded() { - this.player.subtitles.enable("subtitle" + this.section.id.toString()); - }, + //onSubtitleAdded() { + // this.player.subtitles.enable("subtitle" + this.section.id.toString()); + //}, onPlayerReady() { const videoElement = document.getElementById("bitmovinplayer-video-" + this.getPlayerUniqueId) as HTMLVideoElement; if (videoElement) { videoElement.controls = true; } - var subtitleTrack; + // var subtitleTrack; //if (this.pageSectionDetail.videoAsset.azureMediaAsset && this.pageSectionDetail.videoAsset.closedCaptionsFile) { // const captionsInfo = this.pageSectionDetail.videoAsset.closedCaptionsFile; // var srcPath = "file/download/" + captionsInfo.filePath + "/" + captionsInfo.fileName; @@ -197,7 +201,7 @@ //this.player.addSubtitle(subtitleTrack); - var contanierId = this.section.id.toString();; + var contanierId = this.section.id.toString(); var uniquePlayer = this.player;// (player_@Model.Id); buildControlbar(contanierId, uniquePlayer); }, @@ -232,34 +236,33 @@ theme: "dark", events: { ready: this.onPlayerReady, - subtitleadded: this.onSubtitleAdded, + //subtitleadded: this.onSubtitleAdded, } }; // Initialize the player with video container and player configuration this.player = new MKPlayer(this.videoContainer, playerConfig); - //var subtitleTrack; - //debugger; - //if (this.pageSectionDetail.videoAsset.azureMediaAsset && this.pageSectionDetail.videoAsset.closedCaptionsFile) { - // const captionsInfo = this.pageSectionDetail.videoAsset.closedCaptionsFile; - // var srcPath = "file/download/" + captionsInfo.filePath + "/" + captionsInfo.fileName; - // //srcPath = '@requestURL' + srcPath; - // srcPath = "https://bitdash-a.akamaihd.net/content/sintel/subtitles/subtitles_en.vtt"; - - // subtitleTrack = { - // id: "subtitle" + this.section.id.toString(), - // lang: "en", - // label: "english", - // url: srcPath, - // kind: "subtitle" - // }; - //}; + var subtitleTrack = null; + var sectionId = this.section.id.toString(); + if (this.pageSectionDetail.videoAsset.azureMediaAsset && this.pageSectionDetail.videoAsset.closedCaptionsFile) { + var captionsInfo = this.pageSectionDetail.videoAsset.closedCaptionsFile;; + if (captionsInfo) { + var srcPath = "/file/download/" + captionsInfo.filePath + "/" + captionsInfo.fileName; + subtitleTrack = { + id: "subtitle" + sectionId, + lang: "en", + label: "english", + url: this.requestURL + srcPath, + kind: "subtitle" + }; + } + } // Load source const sourceConfig = { hls: this.getMediaPlayUrl(this.pageSectionDetail.videoAsset.azureMediaAsset.locatorUri), - //subtitleTracks: subtitleTrack, + subtitleTracks: [subtitleTrack], drm: { clearkey: { LA_URL: "HLS_AES", diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue index 29dc93a98..484d0b09d 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/resource/ResourceContent.vue @@ -146,7 +146,8 @@ playBackDashUrl: '', sourceLoaded: true, playerConfig: { - } + }, + requestURL: '' } }, computed: { @@ -231,8 +232,8 @@ beforeDestroy(): void { window.clearInterval(this.mediaPlayingTimer); }, - mounted() { - + mounted() { + this.requestURL =window.location.origin; }, methods: { onPlayerReady() { @@ -312,10 +313,25 @@ } }; + var subtitleTrack = null; + var captionsInfo = this.resourceItem.videoDetails.closedCaptionsFile; + + if (captionsInfo) { + var srcPath = this.getFileLink(captionsInfo.filePath, captionsInfo.fileName); + subtitleTrack = { + id: "subtitle", + lang: "en", + label: "english", + url: this.requestURL + srcPath, + kind: "subtitle" + }; + } + // Load source const sourceConfig = { hls: this.playBackUrl, //dash: this.playBackDashUrl, + subtitleTracks: [subtitleTrack], drm: { clearkey: clearKeyConfig } @@ -850,25 +866,4 @@ background-color: $govuk-focus-highlight-yellow; box-shadow: 0 -2px $govuk-focus-highlight-yellow,0 4px $nhsuk-black; } - - /*.video-container { - height: 0; - width: 100%; - overflow: hidden; - position: relative; - padding-top: 56.25%;*/ /* 16:9 aspect ratio */ - /*background-color: #000; - } - - video { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - } - - video[id^="bitmovinplayer-video"] { - width: 100%; - }*/ From 9f054c7b4194857706fe22238f06235fc6d7c142 Mon Sep 17 00:00:00 2001 From: binon Date: Tue, 17 Sep 2024 09:35:07 +0100 Subject: [PATCH 09/27] Firefox fix --- .../Scripts/vuesrc/content/cmsPageRow.vue | 17 ++++---- .../components/MKIOVideoPlayer.vue | 41 +++++++++++-------- .../wwwroot/js/mkplayer-ui-custom.js | 6 +-- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue index ae0ea6c25..cb5971ad4 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue +++ b/AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/content/cmsPageRow.vue @@ -178,10 +178,15 @@ // this.player.subtitles.enable("subtitle" + this.section.id.toString()); //}, onPlayerReady() { - const videoElement = document.getElementById("bitmovinplayer-video-" + this.getPlayerUniqueId) as HTMLVideoElement; - if (videoElement) { - videoElement.controls = true; - } + var contanierId = this.section.id.toString(); + var uniquePlayer = this.player;// (player_@Model.Id); + buildControlbar(contanierId, uniquePlayer); + + // [BY] When we set UI to false we need to manually add the controls to the video element + //const videoElement = document.getElementById("bitmovinplayer-video-" + this.getPlayerUniqueId) as HTMLVideoElement; + //if (videoElement) { + // videoElement.controls = true; + //} // var subtitleTrack; //if (this.pageSectionDetail.videoAsset.azureMediaAsset && this.pageSectionDetail.videoAsset.closedCaptionsFile) { @@ -200,10 +205,6 @@ //}; //this.player.addSubtitle(subtitleTrack); - - var contanierId = this.section.id.toString(); - var uniquePlayer = this.player;// (player_@Model.Id); - buildControlbar(contanierId, uniquePlayer); }, async getMKIOPlayerKey(): Promise { this.mkioKey = await contentData.getMKPlayerKey(); diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/components/MKIOVideoPlayer.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/components/MKIOVideoPlayer.vue index 94fce13e8..9e39e343a 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/components/MKIOVideoPlayer.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/components/MKIOVideoPlayer.vue @@ -60,24 +60,27 @@ methods: { onPlayerReady() { MKPlayerControlbar(this.player.videoContainer.id, this.player); - const videoElement = document.getElementById("bitmovinplayer-video-" + this.getPlayerUniqueId) as HTMLVideoElement; - if (videoElement) { - videoElement.controls = true; - // Add the track element - var captionsInfo = this.captionsTrackAvailable; - if (captionsInfo) { - const trackElement = document.createElement('track'); - var srcPath = this.captionsUrl; - trackElement.kind = 'captions'; - trackElement.label = 'english'; - trackElement.srclang = 'en'; - trackElement.src = srcPath; + // [BY] When we set UI to false we need to manually add the controls to the video element + //const videoElement = document.getElementById("bitmovinplayer-video-" + this.getPlayerUniqueId) as HTMLVideoElement; - // Append the track to the video element - videoElement.appendChild(trackElement); - } - } + //if (videoElement) { + // videoElement.controls = true; + + // // Add the track element + // var captionsInfo = this.captionsTrackAvailable; + // if (captionsInfo) { + // const trackElement = document.createElement('track'); + // var srcPath = this.captionsUrl; + // trackElement.kind = 'captions'; + // trackElement.label = 'english'; + // trackElement.srclang = 'en'; + // trackElement.src = srcPath; + + // // Append the track to the video element + // videoElement.appendChild(trackElement); + // } + //} }, onSubtitleAdded() { @@ -201,7 +204,9 @@ .bmpui-ui-controlbar .control-right { float: right; } + +