/* global Vimeo */
import $ from 'jquery';
function addVimeoFunctions(AblePlayer) {
AblePlayer.prototype.initVimeoPlayer = function () {
var thisObj, deferred, promise, containerId, vimeoId, options;
thisObj = this;
deferred = new this.defer();
promise = deferred.promise();
containerId = this.mediaId + '_vimeo';
// add container to which Vimeo player iframe will be appended
this.$mediaContainer.prepend($('
').attr('id', containerId));
// if a described version is available && user prefers description
// init player using the described version
vimeoId = (this.vimeoDescId && this.prefDesc) ? this.vimeoDescId : this.vimeoId;
this.activeVimeoId = vimeoId;
// Notes re. Vimeo Embed Options:
// If a video is owned by a user with a paid Plus, PRO, or Business account,
// setting the "controls" option to "false" will hide the default controls, without hiding captions.
// This is a new option from Vimeo; previously used "background:true" to hide the controller,
// but that had unwanted side effects:
// - In addition to hiding the controls, it also hides captions
// - It automatically autoplays (initializing the player with autoplay:false does not override this)
// - It automatically loops (but this can be overridden by initializing the player with loop:false)
// - It automatically sets volume to 0 (not sure if this can be overridden, since no longer using the background option)
if (this.playerWidth) {
if (this.vimeoUrlHasParams) {
// use url param, not id
options = {
url: vimeoId,
width: this.playerWidth,
controls: false
}
} else {
options = {
id: vimeoId,
width: this.playerWidth,
controls: false
}
}
} else {
// initialize without width & set width later
if (this.vimeoUrlHasParams) {
options = {
url: vimeoId,
controls: false
}
} else {
options = {
id: vimeoId,
controls: false
}
}
}
this.vimeoPlayer = new Vimeo.Player(containerId, options);
this.vimeoPlayer.ready().then(function() {
// add tabindex -1 on iframe so vimeo frame cannot be focused on
$('#'+containerId).children('iframe').attr({
'tabindex': '-1',
'aria-hidden': true
});
// get video's intrinsic size and initiate player dimensions
thisObj.vimeoPlayer.getVideoWidth().then(function(width) {
if (width) {
// also get height
thisObj.vimeoPlayer.getVideoHeight().then(function(height) {
if (height) {
thisObj.resizePlayer(width,height);
}
});
}
}).catch(function(error) {
// an error occurred getting height or width
// TODO: Test this to see how gracefully it organically recovers
});
if (!thisObj.hasPlaylist) {
// remove the media element, since Vimeo replaces that with its own element in an iframe
// this is handled differently for playlists. See buildplayer.js > cuePlaylistItem()
thisObj.$media.remove();
// define variables that will impact player setup
// vimeoSupportsPlaybackRateChange
// changing playbackRate is only supported if the video is hosted on a Pro or Business account
// unfortunately there is no direct way to query for that information.
// this.vimeoPlayer.getPlaybackRate() returns a value, regardless of account type
// This is a hack:
// Attempt to change the playbackRate. If it results in an error, assume changing playbackRate is not supported.
// Supported playbackRate values are 0.5 to 2.
thisObj.vimeoPlaybackRate = 1;
thisObj.vimeoPlayer.setPlaybackRate(thisObj.vimeoPlaybackRate).then(function(playbackRate) {
// playback rate was set
thisObj.vimeoSupportsPlaybackRateChange = true;
}).catch(function(error) {
thisObj.vimeoSupportsPlaybackRateChange = false;
});
deferred.resolve();
}
});
return promise;
};
AblePlayer.prototype.getVimeoPaused = function () {
var deferred, promise;
deferred = new this.defer();
promise = deferred.promise();
this.vimeoPlayer.getPaused().then(function (paused) {
// paused is Boolean
deferred.resolve(paused);
});
return promise;
}
AblePlayer.prototype.getVimeoEnded = function () {
var deferred, promise;
deferred = new this.defer();
promise = deferred.promise();
this.vimeoPlayer.getEnded().then(function (ended) {
// ended is Boolean
deferred.resolve(ended);
});
return promise;
}
AblePlayer.prototype.getVimeoState = function () {
var deferred, promise, promises, gettingPausedPromise, gettingEndedPromise;
deferred = new this.defer();
promise = deferred.promise();
promises = [];
gettingPausedPromise = this.vimeoPlayer.getPaused();
gettingEndedPromise = this.vimeoPlayer.getEnded();
promises.push(gettingPausedPromise);
promises.push(gettingEndedPromise);
gettingPausedPromise.then(function (paused) {
deferred.resolve(paused);
});
gettingEndedPromise.then(function (ended) {
deferred.resolve(ended);
});
$.when.apply($, promises).then(function () {
deferred.resolve();
});
return promise;
}
AblePlayer.prototype.getVimeoCaptionTracks = function () {
// get data via Vimeo Player API, and push data to this.captions
// Note: Vimeo doesn't expose the caption cues themselves
// so this.captions will only include metadata about caption tracks; not cues
var deferred = new this.defer();
var promise = deferred.promise();
var thisObj, i, isDefaultTrack;
thisObj = this;
this.vimeoPlayer.getTextTracks().then(function(tracks) {
// each Vimeo track includes the following:
// label (local name of the language)
// language (2-character code)
// kind (captions or subtitles, as declared by video owner)
// mode ('disabled' or 'showing')
if (tracks.length) {
// create a new button for each caption track
for (i=0; i {
return response.json();
})
.then( json => {
imageUrl = json.thumbnail_url;
})
.catch( error => {
if (thisObj.debug) {
console.log( 'Vimeo API query: ' + error );
}
});
return imageUrl;
};
AblePlayer.prototype.getVimeoId = function (url) {
// return a Vimeo ID, extracted from a full Vimeo URL
// Supported URL patterns are anything containing 'vimeo.com'
// and ending with a '/' followed by the ID.
// (Vimeo IDs do not have predicatable lengths)
// Update: If URL contains parameters, return the full url
// This will need to be passed to the Vimeo Player API
// as a url parameter, not as an id parameter
this.vimeoUrlHasParams = false;
let urlObject;
if (typeof url === 'number') {
// this is likely already a vimeo ID
return url;
} else {
// Try to parse as a URL. If that fails, return the string as-is. It's probably an ID.
try {
urlObject = new URL(url);
} catch (e) {
return url;
}
}
if ( 'vimeo.com' === urlObject.hostname || 'player.vimeo.com' === urlObject.hostname ) {
// this is a full Vimeo URL
if ( '' !== urlObject.search ) {
// URL contains parameters
this.vimeoUrlHasParams = true;
return url;
} else {
if ( 'player.vimeo.com' === urlObject.hostname ) {
return urlObject.pathname.replace( '/video/', '' );
} else {
return urlObject.pathname.replace( '/', '' );
}
}
} else {
return url;
}
};
}
export default addVimeoFunctions;