Created
March 4, 2021 13:43
-
-
Save valex/9c3ca1d31b9ed42da3da178eb8a60b33 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var videoPlayer = { | |
props: { | |
origin:{ | |
type: String, | |
required: true | |
}, | |
video_key:{ | |
type: String, | |
required: true | |
}, | |
aspect_ratio:{ | |
type: Number, | |
required: 169 | |
}, | |
start:{ | |
type: Number, | |
default: 0 | |
}, | |
autoplay:{ | |
type: Number, | |
default: 1 | |
}, | |
mute_audio:{ | |
type: Boolean, | |
default: true // LOW | |
} | |
}, | |
mounted: function() { | |
this.initVideoPlayer(); | |
// We listen for the event on the eventHub | |
EventBus.$on('onYouTubeIframeAPIReady', this.onYouTubeIframeAPIReady); | |
EventBus.$on('seekTo', this.seekTo); | |
EventBus.$on('pausePlayer', this.pause); | |
EventBus.$on('playPlayer', this.play); | |
}, | |
template: '<div><div :class="classEmbedResponsiveObject" class="embed-responsive">' + | |
'<iframe id="player" allowfullscreen="allowfullscreen" mozallowfullscreen="mozallowfullscreen" msallowfullscreen="msallowfullscreen" oallowfullscreen="oallowfullscreen" webkitallowfullscreen="webkitallowfullscreen"' + | |
'class="embed-responsive-item"' + | |
':src="src"' + | |
'></iframe></div>' + | |
'' + | |
'<form class="form-inline">' + | |
'<label class="sr-only" for="">Старт/Пауза</label>' + | |
'<button v-on:click="triggerPlay" type="button" class="btn btn-light pointer border-right-0">' + | |
'<i v-show=" ! playerParams.play" class="fa fa-play" aria-hidden="true"></i>' + | |
'<i v-show="playerParams.play" class="fa fa-pause" aria-hidden="true"></i>' + | |
'</button>' + | |
'' + | |
'<label class="sr-only" for="">Вкл/Выкл звук</label>' + | |
'<button v-on:click="triggerMute" type="button" class="btn btn-light pointer border-right-0">' + | |
'<i v-show=" ! playerParams.mute" class="fa fa-volume-up" aria-hidden="true"></i>' + | |
'<i v-show="playerParams.mute" class="fa fa-volume-off" aria-hidden="true"></i>' + | |
'</button>' + | |
'' + | |
'<button v-on:click="subSeconds(15)" type="button" class="btn btn-light pointer border-right-0">' + | |
'- 15 сек.' + | |
'</button>' + | |
'' + | |
'<button v-on:click="addSeconds(15)" type="button" class="btn btn-light pointer border-right-0">' + | |
'+ 15 сек.' + | |
'</button>' + | |
'' + | |
'<label class="sr-only" for="">Скорость</label>' + | |
'<select style="width: auto;" v-show=" ! _.isEmpty(playerParams.availablePlaybackRates)" v-model="playerParams.playbackRate" class="d-inline-block form-control mb-2 mb-sm-0" >' + | |
'<template v-for="rate in playerParams.availablePlaybackRates">' + | |
'<option :value="rate">{{rate}}x</option>' + | |
'</template>' + | |
'</select>' + | |
'' + | |
'<!--<label class="sr-only" for="">Качество</label>' + | |
'<select ' + | |
'v-show=" ! _.isEmpty(playerParams.availableQualityLevels)" ' + | |
'v-model="playerParams.qualityLevel" class="form-control border-right-0 mb-2 mb-sm-0" >' + | |
'<template v-for="quality in playerParams.availableQualityLevels">' + | |
'<option :value="quality">{{qualityLevelLabels[quality]}}</option>' + | |
'</template>' + | |
'</select>-->' + | |
'' + | |
'<!--<label class="sr-only" for="">Aspect ration</label>' + | |
'<select v-model="playerParams.aspectRatio" class="form-control mb-2 mr-sm-2 mb-sm-0">' + | |
'<option :value="43">4:3</option>' + | |
'<option :value="169">16:9</option>' + | |
'</select>-->' + | |
'' + | |
'</form>' + | |
'</div>', | |
data: function () { | |
return { | |
player:null, | |
playerParams: { | |
aspectRatio: this.aspect_ratio, | |
play: !!this.autoplay, // true - видео проигрывается | |
mute: this.mute_audio, // true - звук выключен | |
availablePlaybackRates: [], | |
playbackRate: 1, | |
availableQualityLevels: [], | |
qualityLevel: 'auto', | |
}, | |
first_playing_launched: true, | |
qualityLevelLabels: { | |
'auto': 'Авто', | |
'tiny': '144p', | |
'small': '240p', | |
'medium': '360p', | |
'large': '480p', | |
'hd720': '720p HD', | |
'hd1080': '1080p HD', | |
} | |
} | |
}, | |
methods: { | |
subSeconds: function(seconds){ | |
this.seekTo(this.currentTime() - seconds); | |
}, | |
addSeconds: function(seconds){ | |
this.seekTo(this.currentTime() + seconds); | |
}, | |
seekTo:function(second){ | |
this.player.seekTo(second, true); | |
}, | |
currentTime: function(){ | |
return this.player.getCurrentTime(); | |
}, | |
triggerPlay: function(){ | |
if( true === this.playerParams.play){ | |
this.pause(); | |
}else{ | |
this.play(); | |
} | |
}, | |
triggerMute: function(){ | |
if(true===this.player.isMuted()){ | |
this.unmute(); | |
}else{ | |
this.mute(); | |
} | |
}, | |
play: function(){ | |
this.player.playVideo(); | |
}, | |
pause: function(){ | |
this.player.pauseVideo(); | |
}, | |
mute: function(){ | |
this.player.mute(); | |
this.playerParams.mute = true; | |
}, | |
unmute: function(){ | |
this.player.unMute(); | |
this.playerParams.mute = false; | |
}, | |
initVideoPlayer: function(){ | |
// 2. This code loads the IFrame Player API code asynchronously. | |
var tag = document.createElement('script'); | |
tag.src = "https://www.youtube.com/iframe_api"; | |
var firstScriptTag = document.getElementsByTagName('script')[0]; | |
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); | |
}, | |
onYouTubeIframeAPIReady: function(){ | |
this.player = new YT.Player('player', { | |
events: { | |
'onReady': this.onPlayerReady, | |
'onStateChange': this.onPlayerStateChange, | |
'onPlaybackRateChange': this.onPlaybackRateChange, | |
'onPlaybackQualityChange': this.onPlaybackQualityChange, | |
} | |
}); | |
var h = document.getElementById('player').offsetHeight; | |
EventBus.$emit('playerHeight', h); | |
}, | |
onPlayerReady: function(event){ | |
// var player = event.target; | |
Vue.set(this.playerParams, 'availablePlaybackRates', this.player.getAvailablePlaybackRates()); | |
Vue.set(this.playerParams, 'playbackRate', this.player.getPlaybackRate()); | |
if(true === this.playerParams.mute){ | |
this.mute(); | |
} | |
}, | |
onPlaybackRateChange: function (event) { | |
Vue.set(this.playerParams, 'playbackRate', event.data); | |
}, | |
onPlaybackQualityChange: function (event) { | |
Vue.set(this.playerParams, 'qualityLevel', event.data); | |
}, | |
onFirstPlay:function(){ | |
Vue.set(this.playerParams, 'availableQualityLevels', this.player.getAvailableQualityLevels()); | |
Vue.set(this.playerParams, 'qualityLevel', this.player.getPlaybackQuality()); | |
}, | |
onPlayerStateChange: function(event){ | |
var state = event.data; | |
/** | |
* | |
player.getPlayerState():Number | |
Возвращает состояние проигрывателя. Возможные значения: | |
-1 – воспроизведение видео не началось | |
0 – воспроизведение видео завершено | |
1 – воспроизведение | |
2 – пауза | |
3 – буферизация | |
5 – видео находится в очереди | |
*/ | |
if( 1 === state){ | |
this.playerParams.play = true; | |
if(this.first_playing_launched === true){ | |
this.first_playing_launched = false; | |
this.onFirstPlay(); | |
} | |
} | |
if( 2 === state){ | |
this.playerParams.play = false; | |
} | |
}, | |
}, | |
computed: { | |
classEmbedResponsiveObject: function () { | |
return { | |
'embed-responsive-4by3': 43===this.playerParams.aspectRatio, | |
'embed-responsive-16by9': 169===this.playerParams.aspectRatio | |
} | |
}, | |
src: function(){ | |
// https://developers.google.com/youtube/player_parameters?hl=ru | |
// iv_load_policy=3 - скрыть аннотации | |
return 'https://www.youtube.com/embed/'+this.video_key+'?autoplay='+this.autoplay+'&start='+this.start+'&origin='+this.origin+'&showinfo=0&fs=1&rel=0&enablejsapi=1'; | |
} | |
}, | |
watch: { | |
'playerParams.playbackRate': function(val, oldVal){ | |
if(val === oldVal) | |
return; | |
this.player.setPlaybackRate(val); | |
}, | |
'playerParams.qualityLevel': function(val, oldVal){ | |
console.log(val, oldVal); | |
if(val === oldVal) | |
return; | |
// https://stackoverflow.com/questions/31697212/youtube-api-cannot-change-video-quality | |
//this.player.stopVideo(); | |
this.player.setPlaybackQuality(val); | |
//this.player.playVideo(); | |
}, | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment