#63523 Выбор размера плеера
This commit is contained in:
committed by
Юрий Шикин
parent
76209f2c7c
commit
10ef949e9e
@@ -131,4 +131,11 @@ volume: {
|
||||
{
|
||||
selection: true,
|
||||
}
|
||||
```
|
||||
|
||||
**enableDocumentPictureInPicture** - включает картинку в картинке, если она доступна для браузера
|
||||
```js
|
||||
{
|
||||
enableDocumentPictureInPicture: true,
|
||||
}
|
||||
```
|
||||
@@ -15,10 +15,12 @@
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.voka-control .voka-button {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
.voka-button {
|
||||
cursor: pointer;
|
||||
|
||||
&.voka-disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.voka-control .voka-svg-container:hover svg path {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
.vjs-pip-window {
|
||||
margin: 0;
|
||||
background: black;
|
||||
.video-js {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
aspect-ratio: auto;
|
||||
}
|
||||
.voka-selection-wrapper,
|
||||
.voka-bottom-panel {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,8 @@
|
||||
@use "../scss/components/audio";
|
||||
@use "../scss/components/selection";
|
||||
@use "../scss/components/timeline";
|
||||
@use "../scss/components/pip";
|
||||
|
||||
|
||||
::-moz-selection {background: rgba(0,0,0,0);}
|
||||
::selection {background: rgba(0,0,0,0);}
|
||||
|
||||
@@ -10,6 +10,7 @@ import '@/components/control-bar/ZoomButton'
|
||||
import '@/components/control-bar/subtitles/SubtitlesButton'
|
||||
import '@/components/control-bar/quality-control/QualityButton'
|
||||
import '@/components/control-bar/audio-control/AudioButton'
|
||||
import '@/components/control-bar/PictureInPictureToggle'
|
||||
|
||||
/**
|
||||
* Container of main controls.
|
||||
@@ -21,7 +22,7 @@ class BottomPanel extends ClickableComponent {
|
||||
let controls = !!options.playerOptions.controls
|
||||
const _options = {
|
||||
...options,
|
||||
children: ['PlayToggle', 'StartOver', 'VolumePanel', 'ProgressControl', 'PlaybackRateButton', 'ZoomButton', 'SubtitlesButton', 'QualityButton', 'AudioButton', 'FullscreenToggle']
|
||||
children: ['PlayToggle', 'StartOver', 'VolumePanel', 'ProgressControl', 'PlaybackRateButton', 'ZoomButton', 'SubtitlesButton', 'QualityButton', 'AudioButton', 'PictureInPictureToggle', 'FullscreenToggle']
|
||||
}
|
||||
|
||||
super(player, _options)
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
import videojs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js'
|
||||
import document from 'global/document'
|
||||
import window from 'global/window'
|
||||
|
||||
import { SvgType } from '@/constants/VokaSvg'
|
||||
import Button from '@/components/Button.ts'
|
||||
import { TooltipPosition } from '../ClickableComponent'
|
||||
|
||||
const Component = videojs.getComponent('component')
|
||||
const Browser = videojs.browser
|
||||
|
||||
class PictureInPictureToggle extends Button {
|
||||
videoEl: any
|
||||
|
||||
constructor(player: VideoJsPlayer, options: VideoJsPlayerOptions) {
|
||||
const options_ = {
|
||||
...options,
|
||||
svg: SvgType.PICTURE_IN_PICTURE
|
||||
}
|
||||
super(player, options_)
|
||||
|
||||
this.on(player, ['enterpictureinpicture', 'leavepictureinpicture'], (e) =>
|
||||
this.handlePiPEnabledChange(e)
|
||||
)
|
||||
this.on(player, ['disablepictureinpicturechanged', 'loadedmetadata'], (e) =>
|
||||
this.handlePiPEnabledChange(e)
|
||||
)
|
||||
this.on(
|
||||
player,
|
||||
['loadedmetadata', 'audioonlymodechange', 'audiopostermodechange'],
|
||||
() => this.handlePiPAudioModeChange()
|
||||
)
|
||||
this.on(player, ['play'], (e) => this.handlePiPEnabledChange(e))
|
||||
|
||||
this.controlText('Picture-in-Picture', this.el(), TooltipPosition.topLeft)
|
||||
|
||||
this.disable()
|
||||
}
|
||||
|
||||
buildCSSClass() {
|
||||
return `voka-picture-in-picture-control vjs-hidden ${super.buildCSSClass()}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays or hides the button depending on the audio mode detection.
|
||||
* Exits picture-in-picture if it is enabled when switching to audio mode.
|
||||
*/
|
||||
handlePiPAudioModeChange() {
|
||||
// This audio detection will not detect HLS or DASH audio-only streams because there was no reliable way to detect them at the time
|
||||
const isSourceAudio = this.player_.currentType().substring(0, 5) === 'audio'
|
||||
const isAudioMode =
|
||||
isSourceAudio ||
|
||||
this.player_.audioPosterMode() ||
|
||||
this.player_.audioOnlyMode()
|
||||
|
||||
if (!isAudioMode) {
|
||||
this.show()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (this.player_.isInPictureInPicture()) {
|
||||
this.player_.exitPictureInPicture()
|
||||
}
|
||||
|
||||
this.hide()
|
||||
}
|
||||
|
||||
/**
|
||||
* Enabled if
|
||||
* - `player.options().enableDocumentPictureInPicture` is true and
|
||||
* window.documentPictureInPicture is available; or
|
||||
* - `player.disablePictureInPicture()` is false and
|
||||
* element.requestPictureInPicture is available; or
|
||||
* - (for safari) The videoEl contains webkitSupportsPresentationMode,
|
||||
* which supports picture-in-picture mode.
|
||||
*/
|
||||
checkPiPSupport() {
|
||||
this.videoEl = this.player_?.tech({ IWillNotUseThisInPlugins: true })?.el()
|
||||
return (
|
||||
(document.pictureInPictureEnabled &&
|
||||
this.player_.disablePictureInPicture() === false) ||
|
||||
(this.player_.options_.playerOptions.enableDocumentPictureInPicture &&
|
||||
'documentPictureInPicture' in window) ||
|
||||
(this.videoEl &&
|
||||
this.videoEl.webkitSupportsPresentationMode &&
|
||||
this.videoEl.webkitSupportsPresentationMode('picture-in-picture') &&
|
||||
typeof this.videoEl.webkitSetPresentationMode === 'function')
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables button based on availability of a Picture-In-Picture mode.
|
||||
*/
|
||||
handlePiPEnabledChange() {
|
||||
if (this.checkPiPSupport()) {
|
||||
this.enable()
|
||||
} else {
|
||||
this.disable()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called when an `PictureInPictureToggle` is "clicked". See
|
||||
*/
|
||||
handleClick(event) {
|
||||
if (Browser.IS_SAFARI) {
|
||||
this.handleClickForSafari()
|
||||
return
|
||||
}
|
||||
if (!this.player_.isInPictureInPicture()) {
|
||||
this.player_.requestPictureInPicture()
|
||||
} else {
|
||||
this.player_.exitPictureInPicture()
|
||||
}
|
||||
}
|
||||
|
||||
handleClickForSafari() {
|
||||
if (this.checkPiPSupport()) {
|
||||
this.videoEl.webkitSetPresentationMode(
|
||||
this.videoEl.webkitPresentationMode === 'picture-in-picture'
|
||||
? 'inline'
|
||||
: 'picture-in-picture'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the `Component`s element if it is hidden by removing the
|
||||
* 'vjs-hidden' class name from it only in browsers that support the Picture-in-Picture API.
|
||||
*/
|
||||
show() {
|
||||
// Does not allow to display the pictureInPictureToggle in browsers that do not support the Picture-in-Picture API, e.g. Firefox.
|
||||
if (typeof document.exitPictureInPicture !== 'function') {
|
||||
return
|
||||
}
|
||||
|
||||
super.show()
|
||||
}
|
||||
}
|
||||
|
||||
Component.registerComponent('PictureInPictureToggle', PictureInPictureToggle)
|
||||
export default PictureInPictureToggle
|
||||
@@ -17,6 +17,7 @@ export const SvgType = {
|
||||
VOLUME_LOW: 'volume-low',
|
||||
VOLUME_MID: 'volume-mid',
|
||||
VOLUME_HIGH: 'volume-high',
|
||||
PICTURE_IN_PICTURE: 'picture_in_picture',
|
||||
}
|
||||
|
||||
export default class VokaSvg {
|
||||
@@ -58,6 +59,8 @@ export default class VokaSvg {
|
||||
return VokaSvg.volumeMid()
|
||||
case SvgType.VOLUME_HIGH:
|
||||
return VokaSvg.volumeHigh()
|
||||
case SvgType.PICTURE_IN_PICTURE:
|
||||
return VokaSvg.pictureInPictureButton()
|
||||
|
||||
default:
|
||||
console.warn('Unknown SvgType received!')
|
||||
@@ -189,6 +192,12 @@ export default class VokaSvg {
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.1 36C6.8 36 5 34.1 5 31.9V22.9C5 20.7 6.8 18.8 9.1 18.8H15.2L29.4 9.1V45.8L15 36H9.1ZM40 43C39.7 43.3 39.4 43.4 38.9 43.4C38.5 43.4 38.1 43.3 37.8 43C37.2 42.4 37.2 41.5 37.8 40.9C40.8 37.9 43 35.3 43 28.3C43 23 41.2 19.1 37.3 15.1C36.7 14.5 36.7 13.6 37.3 13C37.9 12.4 38.8 12.4 39.4 13C43.9 17.5 46 22.1 46 28.2C46.1 36.4 43.3 39.7 40 43ZM36.1 39.3C35.8 39.6 35.5 39.7 35 39.7C34.6 39.7 34.2 39.6 33.9 39.3C33.3 38.7 33.3 37.8 33.9 37.2C36.9 34.2 37.3 29.9 37.3 28.3C37.3 25.7 36.1 21.8 33.9 19.6C33.3 19 33.3 18.1 33.9 17.5C34.5 16.9 35.4 16.9 36 17.5C38.8 20.3 40.3 25.1 40.3 28.3C40.3 30.3 39.9 35.4 36.1 39.3Z" fill="currentColor"/>
|
||||
<path d="M44.7999 45.1C44.4999 45.4 44.1999 45.5 43.6999 45.5C43.2999 45.5 42.8999 45.4 42.5999 45.1C41.9999 44.5 41.9999 43.6 42.5999 43C45.5999 40 48 35.2 48 28.2C48 22.9 45.3 15.6 41.4 11.6C40.8 11 40.8 10.1 41.4 9.50005C42 8.90005 42.9 8.90005 43.5 9.50005C48 14 51 21.9 51 28C51.1 36.2 48.0999 41.8 44.7999 45.1Z" fill="currentColor"/>
|
||||
</svg>
|
||||
`
|
||||
}
|
||||
static pictureInPictureButton() {
|
||||
return `<svg width="55" height="55" viewBox="0 0 55 55" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M40 25.6667H25.3333V36.6575H40V25.6667ZM47.3333 40.3333V14.63C47.3333 12.6133 45.6833 11 43.6667 11H10.6667C8.65 11 7 12.6133 7 14.63V40.3333C7 42.35 8.65 44 10.6667 44H43.6667C45.6833 44 47.3333 42.35 47.3333 40.3333ZM43.6667 40.37H10.6667V14.6117H43.6667V40.37Z" fill="currentColor"/>
|
||||
</svg>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,6 +280,7 @@ export class VokaPlayerCore {
|
||||
// return `https://streaming.voka.tv/vod_preview/velcom/4W17sRxFu8eCAps3kdTxJrFk7d46DNmum_320x180.jpeg?preview_pos=${percent}`;
|
||||
},
|
||||
},
|
||||
enableDocumentPictureInPicture: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -24,7 +24,8 @@
|
||||
"Zoom": "Кадрирование",
|
||||
"Process Selection": "Обработать выделение",
|
||||
"Selection End": "Конец выделения",
|
||||
"Selection Start": "Начало выделения"
|
||||
"Selection Start": "Начало выделения",
|
||||
"Picture-in-Picture": "Картинка в картинке"
|
||||
},
|
||||
"en": {
|
||||
"Play": "Play",
|
||||
@@ -51,6 +52,7 @@
|
||||
"Zoom": "Zoom",
|
||||
"Process Selection": "Process Selection",
|
||||
"Selection End": "Selection End",
|
||||
"Selection Start": "Selection Start"
|
||||
"Selection Start": "Selection Start",
|
||||
"Picture-in-Picture": "Picture-in-Picture"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user