Skip to content

Instantly share code, notes, and snippets.

@stephenscaff
Created February 21, 2020 23:46
Show Gist options
  • Save stephenscaff/25731b764b65461e4bb6d54f063f8bad to your computer and use it in GitHub Desktop.
Save stephenscaff/25731b764b65461e4bb6d54f063f8bad to your computer and use it in GitHub Desktop.
import Player from '@vimeo/player';
/**
* ViemoPlaylist
* Class for interacting with the Vimeo API
* to create a continous playlist of vids
* @class
* @requires @vimeo/player
* @param {html element id} el - player element passed to Vimeo's imported Player class.
* @param {object} options - plugin options for api and playlist ids
*/
function VimeoPlaylist(el, options) {
options = options || {};
Object.assign(this, VimeoPlaylist.options, options);
this.currentVidIdx = 0
this.vidCount = this.playlist.length,
this.isActive = false;
this.activeClass = 'is-playing';
this.wrapperEl = el;
this.playlistOutput = document.querySelector('.js-playlist')
this.playListItems = ''
this.player = new Player(el, {
id: this.playlist[this.currentVidIdx].id,
width: this.width,
title: this.title,
muted: this.muted,
controls: this.controls,
autoplay: this.autoplay
});
}
/**
* VimeoPlaylist Methods
*/
VimeoPlaylist.prototype = {
constructor : VimeoPlaylist,
/**
* Begin sequence and onEnd listeners
*/
init() {
// Autoplay
this.settings()
this.listeners()
this.buildPlaylist()
},
settings() {
this.player.setVolume(0);
this.player.setAutopause(false)
},
/**
* Listeners
*/
listeners() {
// Click Enter to go Fullscreen
// Nah, this is fake, vimeo fullscreen is not the browser fullscreen
// document.addEventListener("keypress", (e)=> {
// if (e.keyCode === 13) {
// this.toggleFullscreen();
// }
// }, false);
// Progress on Video End
this.onEnd()
},
/**
* LoadVid
* Helper to load vimeo vids by their ID
* No need for this.player['play']() and it
* can cause a browser promise pause() error.
* @param {string} id - vimeo video id
*/
loadVid(id) {
this.player.loadVideo(id)
},
/**
* OnEnd
* Listens for when a vid ends.
*/
onEnd() {
this.player.on('ended', () => {
this.next()
});
},
/**
* Build Playlist
* Constructs playlist markup from this.playlist
*/
buildPlaylist() {
//console.log('playlist', this.playlist)
let counter = 0;
this.playlist.forEach((plist, i) => {
let id = plist.id;
let vidInfo = this.fetchData("https://vimeo.com/api/v2/video/"+ id +".json")
vidInfo.then(obj => {
counter++;
let tmpl = this.plistTemplate(obj[0])
let e = document.createElement('span');
e.innerHTML = tmpl;
this.playlistOutput.appendChild(e);
this.items = document.querySelectorAll('.plist-item__link')
if (counter === this.vidCount) {
this.firstVid()
this.handleClick();
}
})
})
},
/**
* Fetch Data Util
* @return promise
*/
fetchData(url) {
return window.fetch(url)
.then(res => {
return res.json()
})
.then(json => {
return json
})
.catch(ex => console.log('failed', ex))
},
firstVid() {
let items = document.querySelectorAll('.plist-item__link')
items[0].classList.add(this.activeClass)
this.player['play']()
},
handleClick() {
let items = document.querySelectorAll('.plist-item__link')
this.items.forEach((item, i) => {
item.addEventListener('click', (e) => {
e.preventDefault()
let id = item.dataset.vimeoId;
this.currentVidIdx = i
this.loadVid(id)
this.setActiveState(i, e)
})
})
},
playVid(i) {
let track = this.playlist[i]
this.currentVidIdx = i;
},
setActiveState(i, e) {
console.log('setstate', this.playlist[i], e.currentTarget)
let items = document.querySelectorAll('.plist-item__link')
let active = document.querySelector('.is-playing')
if (active) {
active.classList.remove(this.activeClass)
}
this.items[this.currentVidIdx].classList.add(this.activeClass)
},
/**
* Next
* Tracks current video index and progress to next.
*/
next() {
console.log('next vid')
this.currentVidIdx++;
if (this.currentVidIdx < this.vidCount){
this.currentVidIdx+1;
} else {
this.currentVidIdx = 0;
}
this.loadVid(this.playlist[this.currentVidIdx])
},
/**
* Prev
* Not in use yet, but we may want an actual playlist at some point
* Or, at least the ability to go forward and backward.
*/
prev() {},
/**
* Playlist item Template
*/
plistTemplate(data) {
return `
<article class="plist-item">
<a class="plist-item__link" data-vimeo-id="${data.id}">
<figure class="plist-item__thumb">
<div class="plist-item__thumb-color">
<img class="plist-item__thumb-img" src="${data.thumbnail_large}"/>
<svg class="plist-item__icon-play" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#fff" width="50" height="50" viewBox="0 0 36 36">
<path d="M 12,26 18.5,22 18.5,14 12,10 z M 18.5,22 25,18 25,18 18.5,14 z"></path>
</svg>
</div>
</figure>
<div class="plist-item__main">
<span class="plist-item__title">${data.title}</span>
<span class="plist-item__user">${data.user_name}</span>
<span class="plist-item__time-dur">${data.duration}</span>
<div class="equalizer">
<span class="equalizer__item"></span>
<span class="equalizer__item"></span>
<span class="equalizer__item"></span>
</div>
</div>
</a>
</article>
`
},
/**
* Toggle Fullscreen
* This is bs. Looks like vimeo uses a different
* fullscreen than native requestFullscreen.
* Leaving here until I figure that out.
*/
toggleFullscreen() {
let vidWrapper = this.wrapperEl
if (!document.vidWrapper) {
document.documentElement.requestFullscreen();
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
}
}
}
}
/**
* VimeoPlaylist Options
* Default options
*/
VimeoPlaylist.options = {
width: 1200,
loop: false,
title: false,
muted: true,
controls: true,
autoplay: true,
playlist: [
{"id":"229056408"},
{"id":"271357892"},
{"id":"271354428"}
]
}
//let vids = new VimeoPlaylist('js-player').init()
export default VimeoPlaylist
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment