Skip to content

Instantly share code, notes, and snippets.

@valex
Created March 4, 2021 13:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save valex/9c3ca1d31b9ed42da3da178eb8a60b33 to your computer and use it in GitHub Desktop.
Save valex/9c3ca1d31b9ed42da3da178eb8a60b33 to your computer and use it in GitHub Desktop.
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