2015-06-07 20:16:42 -07:00
|
|
|
|
(function () {
|
|
|
|
|
|
2015-06-13 07:46:59 -07:00
|
|
|
|
var supportsTextTracks;
|
2015-07-03 09:49:49 -07:00
|
|
|
|
var isViblastStarted;
|
2015-07-13 14:26:11 -07:00
|
|
|
|
var requiresSettingStartTimeOnStart;
|
2015-06-13 07:46:59 -07:00
|
|
|
|
|
2015-07-03 09:49:49 -07:00
|
|
|
|
function htmlMediaRenderer(options) {
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
|
|
|
|
var mediaElement;
|
|
|
|
|
var self = this;
|
|
|
|
|
|
2015-09-08 07:35:52 -07:00
|
|
|
|
function hideStatusBar() {
|
|
|
|
|
if (options.type == 'video' && window.StatusBar) {
|
2015-09-23 19:31:40 -07:00
|
|
|
|
//StatusBar.backgroundColorByName("black");
|
2015-09-21 08:43:10 -07:00
|
|
|
|
//StatusBar.overlaysWebView(true);
|
2015-09-08 07:35:52 -07:00
|
|
|
|
StatusBar.hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showStatusBar() {
|
|
|
|
|
if (options.type == 'video' && window.StatusBar) {
|
|
|
|
|
StatusBar.show();
|
2015-09-21 08:43:10 -07:00
|
|
|
|
//StatusBar.overlaysWebView(false);
|
2015-09-08 07:35:52 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-07 20:16:42 -07:00
|
|
|
|
function onEnded() {
|
2015-09-08 07:35:52 -07:00
|
|
|
|
showStatusBar();
|
2015-06-07 20:16:42 -07:00
|
|
|
|
$(self).trigger('ended');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onTimeUpdate() {
|
2015-07-13 14:26:11 -07:00
|
|
|
|
|
|
|
|
|
if (isViblastStarted) {
|
|
|
|
|
|
|
|
|
|
// This is a workaround for viblast not stopping playback at the end
|
|
|
|
|
var time = this.currentTime;
|
|
|
|
|
var duration = this.duration;
|
|
|
|
|
|
|
|
|
|
if (duration) {
|
2015-07-15 04:26:47 -07:00
|
|
|
|
if (time >= (duration - 1)) {
|
|
|
|
|
|
2015-09-24 10:08:10 -07:00
|
|
|
|
//onEnded();
|
2015-07-13 14:26:11 -07:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-07 20:16:42 -07:00
|
|
|
|
$(self).trigger('timeupdate');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onVolumeChange() {
|
|
|
|
|
$(self).trigger('volumechange');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onOneAudioPlaying() {
|
|
|
|
|
$('.mediaPlayerAudioContainer').hide();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onPlaying() {
|
|
|
|
|
$(self).trigger('playing');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onPlay() {
|
|
|
|
|
$(self).trigger('play');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onPause() {
|
|
|
|
|
$(self).trigger('pause');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onClick() {
|
|
|
|
|
$(self).trigger('click');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onDblClick() {
|
|
|
|
|
$(self).trigger('dblclick');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onError() {
|
|
|
|
|
|
|
|
|
|
var errorCode = this.error ? this.error.code : '';
|
2015-06-26 20:27:38 -07:00
|
|
|
|
Logger.log('Media element error code: ' + errorCode);
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
2015-09-08 07:35:52 -07:00
|
|
|
|
showStatusBar();
|
2015-06-07 20:16:42 -07:00
|
|
|
|
$(self).trigger('error');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onLoadedMetadata() {
|
|
|
|
|
|
2015-07-13 14:26:11 -07:00
|
|
|
|
if (!isViblastStarted) {
|
2015-06-07 20:16:42 -07:00
|
|
|
|
this.play();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 20:00:03 -07:00
|
|
|
|
function requireViblast(callback) {
|
|
|
|
|
require(['thirdparty/viblast/viblast.js'], function () {
|
|
|
|
|
|
|
|
|
|
if (htmlMediaRenderer.customViblastKey) {
|
|
|
|
|
callback();
|
|
|
|
|
} else {
|
|
|
|
|
downloadViblastKey(callback);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function downloadViblastKey(callback) {
|
|
|
|
|
|
2015-07-19 20:43:13 -07:00
|
|
|
|
var savedKeyPropertyName = 'vbk';
|
2015-07-18 12:32:59 -07:00
|
|
|
|
var savedKey = appStorage.getItem(savedKeyPropertyName);
|
2015-07-23 07:58:27 -07:00
|
|
|
|
|
2015-07-18 12:32:59 -07:00
|
|
|
|
if (savedKey) {
|
2015-07-23 07:58:27 -07:00
|
|
|
|
htmlMediaRenderer.customViblastKey = savedKey;
|
|
|
|
|
callback();
|
|
|
|
|
return;
|
2015-07-18 12:32:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 20:00:03 -07:00
|
|
|
|
var headers = {};
|
|
|
|
|
headers['X-Emby-Token'] = 'EMBY_SERVER';
|
|
|
|
|
|
|
|
|
|
HttpClient.send({
|
|
|
|
|
type: 'GET',
|
|
|
|
|
url: 'https://mb3admin.com/admin/service/registration/getViBlastKey',
|
|
|
|
|
headers: headers
|
|
|
|
|
|
|
|
|
|
}).done(function (key) {
|
|
|
|
|
|
2015-07-18 12:32:59 -07:00
|
|
|
|
appStorage.setItem(savedKeyPropertyName, key);
|
2015-07-09 20:00:03 -07:00
|
|
|
|
htmlMediaRenderer.customViblastKey = key;
|
|
|
|
|
callback();
|
|
|
|
|
}).fail(function () {
|
|
|
|
|
callback();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getViblastKey() {
|
2015-07-19 20:43:13 -07:00
|
|
|
|
|
|
|
|
|
return htmlMediaRenderer.customViblastKey || 'N8FjNTQ3NDdhZqZhNGI5NWU5ZTI=';
|
2015-07-09 20:00:03 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-13 14:26:11 -07:00
|
|
|
|
function getStartTime(url) {
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
2015-07-13 14:26:11 -07:00
|
|
|
|
var src = url;
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
var parts = src.split('#');
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
|
|
|
|
if (parts.length > 1) {
|
|
|
|
|
|
|
|
|
|
parts = parts[parts.length - 1].split('=');
|
|
|
|
|
|
|
|
|
|
if (parts.length == 2) {
|
|
|
|
|
|
2015-07-13 14:26:11 -07:00
|
|
|
|
return parseFloat(parts[1]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
2015-07-13 14:26:11 -07:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onOneVideoPlaying() {
|
|
|
|
|
|
2015-09-08 07:35:52 -07:00
|
|
|
|
hideStatusBar();
|
|
|
|
|
|
2015-07-13 14:26:11 -07:00
|
|
|
|
var requiresNativeControls = !self.enableCustomVideoControls();
|
|
|
|
|
|
|
|
|
|
if (requiresNativeControls) {
|
|
|
|
|
$(this).attr('controls', 'controls');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (requiresSettingStartTimeOnStart) {
|
|
|
|
|
var src = (self.currentSrc() || '').toLowerCase();
|
|
|
|
|
|
|
|
|
|
var startPositionInSeekParam = getStartTime(src);
|
|
|
|
|
|
|
|
|
|
// Appending #t=xxx to the query string doesn't seem to work with HLS
|
|
|
|
|
if (startPositionInSeekParam && src.indexOf('.m3u8') != -1) {
|
|
|
|
|
var element = this;
|
|
|
|
|
setTimeout(function () {
|
|
|
|
|
element.currentTime = startPositionInSeekParam;
|
|
|
|
|
}, 2500);
|
2015-06-07 20:16:42 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createAudioElement() {
|
|
|
|
|
|
|
|
|
|
var elem = $('.mediaPlayerAudio');
|
|
|
|
|
|
|
|
|
|
if (!elem.length) {
|
|
|
|
|
var html = '';
|
|
|
|
|
|
|
|
|
|
var requiresControls = !MediaPlayer.canAutoPlayAudio();
|
|
|
|
|
|
|
|
|
|
if (requiresControls) {
|
|
|
|
|
html += '<div class="mediaPlayerAudioContainer"><div class="mediaPlayerAudioContainerInner">';;
|
|
|
|
|
} else {
|
|
|
|
|
html += '<div class="mediaPlayerAudioContainer" style="display:none;"><div class="mediaPlayerAudioContainerInner">';;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html += '<audio class="mediaPlayerAudio" crossorigin="anonymous" controls>';
|
|
|
|
|
html += '</audio></div></div>';
|
|
|
|
|
|
|
|
|
|
$(document.body).append(html);
|
|
|
|
|
|
|
|
|
|
elem = $('.mediaPlayerAudio');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $(elem)
|
|
|
|
|
.on('timeupdate', onTimeUpdate)
|
|
|
|
|
.on('ended', onEnded)
|
|
|
|
|
.on('volumechange', onVolumeChange)
|
|
|
|
|
.one('playing', onOneAudioPlaying)
|
|
|
|
|
.on('play', onPlay)
|
|
|
|
|
.on('pause', onPause)
|
|
|
|
|
.on('playing', onPlaying)
|
|
|
|
|
.on('error', onError)[0];
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-05 11:34:52 -07:00
|
|
|
|
function enableViblast(src) {
|
|
|
|
|
|
|
|
|
|
if (src) {
|
|
|
|
|
if (src.indexOf('.m3u8') == -1) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-03 04:51:45 -07:00
|
|
|
|
|
|
|
|
|
return MediaPlayer.canPlayHls() && !MediaPlayer.canPlayNativeHls();
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-07 20:16:42 -07:00
|
|
|
|
function createVideoElement() {
|
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
var html = '';
|
|
|
|
|
|
|
|
|
|
var requiresNativeControls = !self.enableCustomVideoControls();
|
|
|
|
|
|
2015-09-09 20:22:52 -07:00
|
|
|
|
// Safari often displays the poster under the video and it doesn't look good
|
|
|
|
|
var poster = !$.browser.safari && options.poster ? (' poster="' + options.poster + '"') : '';
|
2015-07-03 09:49:49 -07:00
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
// Can't autoplay in these browsers so we need to use the full controls
|
|
|
|
|
if (requiresNativeControls && AppInfo.isNativeApp && $.browser.android) {
|
2015-07-03 09:49:49 -07:00
|
|
|
|
html += '<video class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous"' + poster + ' webkit-playsinline>';
|
2015-07-03 04:51:45 -07:00
|
|
|
|
}
|
|
|
|
|
else if (requiresNativeControls) {
|
2015-07-03 09:49:49 -07:00
|
|
|
|
html += '<video class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous"' + poster + ' controls="controls" webkit-playsinline>';
|
2015-07-03 04:51:45 -07:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
// Chrome 35 won't play with preload none
|
2015-07-03 09:49:49 -07:00
|
|
|
|
html += '<video class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous"' + poster + ' webkit-playsinline>';
|
2015-07-03 04:51:45 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html += '</video>';
|
|
|
|
|
|
|
|
|
|
var elem = $('#videoElement', '#mediaPlayer').prepend(html);
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
return $('.itemVideo', elem)
|
2015-06-29 11:45:42 -07:00
|
|
|
|
.one('.loadedmetadata', onLoadedMetadata)
|
2015-06-07 20:16:42 -07:00
|
|
|
|
.one('playing', onOneVideoPlaying)
|
|
|
|
|
.on('timeupdate', onTimeUpdate)
|
|
|
|
|
.on('ended', onEnded)
|
|
|
|
|
.on('volumechange', onVolumeChange)
|
|
|
|
|
.on('play', onPlay)
|
|
|
|
|
.on('pause', onPause)
|
|
|
|
|
.on('playing', onPlaying)
|
2015-06-11 10:57:59 -07:00
|
|
|
|
.on('click', onClick)
|
|
|
|
|
.on('dblclick', onDblClick)
|
2015-06-07 20:16:42 -07:00
|
|
|
|
.on('error', onError)[0];
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 20:00:03 -07:00
|
|
|
|
// Save this for when playback stops, because querying the time at that point might return 0
|
|
|
|
|
var _currentTime;
|
2015-06-07 20:16:42 -07:00
|
|
|
|
self.currentTime = function (val) {
|
|
|
|
|
|
|
|
|
|
if (mediaElement) {
|
|
|
|
|
if (val != null) {
|
2015-06-25 14:50:56 -07:00
|
|
|
|
mediaElement.currentTime = val / 1000;
|
2015-06-07 20:16:42 -07:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 20:00:03 -07:00
|
|
|
|
if (_currentTime) {
|
|
|
|
|
return _currentTime * 1000;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-25 14:50:56 -07:00
|
|
|
|
return (mediaElement.currentTime || 0) * 1000;
|
2015-06-07 20:16:42 -07:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.duration = function (val) {
|
|
|
|
|
|
|
|
|
|
if (mediaElement) {
|
|
|
|
|
return mediaElement.duration;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
};
|
|
|
|
|
|
2015-06-10 20:01:41 -07:00
|
|
|
|
self.stop = function () {
|
|
|
|
|
if (mediaElement) {
|
|
|
|
|
mediaElement.pause();
|
2015-07-03 04:51:45 -07:00
|
|
|
|
|
2015-07-03 09:49:49 -07:00
|
|
|
|
if (isViblastStarted) {
|
2015-07-09 20:00:03 -07:00
|
|
|
|
_currentTime = mediaElement.currentTime;
|
2015-07-03 09:49:49 -07:00
|
|
|
|
|
2015-10-26 09:21:00 -07:00
|
|
|
|
// Sometimes this fails
|
|
|
|
|
try {
|
|
|
|
|
viblast('#' + mediaElement.id).stop();
|
|
|
|
|
}
|
|
|
|
|
catch (err) {
|
|
|
|
|
Logger.log(err);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 20:00:03 -07:00
|
|
|
|
isViblastStarted = false;
|
2015-07-03 04:51:45 -07:00
|
|
|
|
}
|
2015-06-10 20:01:41 -07:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2015-06-07 20:16:42 -07:00
|
|
|
|
self.pause = function () {
|
|
|
|
|
if (mediaElement) {
|
|
|
|
|
mediaElement.pause();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.unpause = function () {
|
|
|
|
|
if (mediaElement) {
|
|
|
|
|
mediaElement.play();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.volume = function (val) {
|
|
|
|
|
if (mediaElement) {
|
|
|
|
|
if (val != null) {
|
|
|
|
|
mediaElement.volume = val;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mediaElement.volume;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
var currentSrc;
|
2015-09-15 11:09:44 -07:00
|
|
|
|
self.setCurrentSrc = function (streamInfo, item, mediaSource, tracks) {
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
|
|
|
|
var elem = mediaElement;
|
|
|
|
|
|
|
|
|
|
if (!elem) {
|
2015-07-03 04:51:45 -07:00
|
|
|
|
currentSrc = null;
|
2015-06-07 20:16:42 -07:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-15 11:09:44 -07:00
|
|
|
|
if (!streamInfo) {
|
2015-07-03 04:51:45 -07:00
|
|
|
|
currentSrc = null;
|
2015-06-07 20:16:42 -07:00
|
|
|
|
elem.src = null;
|
|
|
|
|
elem.src = "";
|
|
|
|
|
|
|
|
|
|
// When the browser regains focus it may start auto-playing the last video
|
|
|
|
|
if ($.browser.safari) {
|
|
|
|
|
elem.src = 'files/dummy.mp4';
|
|
|
|
|
elem.play();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-15 11:09:44 -07:00
|
|
|
|
var val = streamInfo.url;
|
2015-09-21 08:43:10 -07:00
|
|
|
|
|
|
|
|
|
if (AppInfo.isNativeApp && $.browser.safari) {
|
|
|
|
|
val = val.replace('file://', '');
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-13 14:26:11 -07:00
|
|
|
|
requiresSettingStartTimeOnStart = false;
|
|
|
|
|
var startTime = getStartTime(val);
|
2015-08-24 13:37:34 -07:00
|
|
|
|
var playNow = false;
|
2015-07-13 14:26:11 -07:00
|
|
|
|
|
2015-06-07 20:16:42 -07:00
|
|
|
|
if (elem.tagName.toLowerCase() == 'audio') {
|
2015-07-03 04:51:45 -07:00
|
|
|
|
|
|
|
|
|
elem.src = val;
|
2015-08-24 13:37:34 -07:00
|
|
|
|
playNow = true;
|
2015-07-03 04:51:45 -07:00
|
|
|
|
|
2015-06-07 20:16:42 -07:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
|
2015-07-16 05:56:38 -07:00
|
|
|
|
if (isViblastStarted) {
|
2015-08-25 19:31:33 -07:00
|
|
|
|
viblast('#' + elem.id).stop();
|
2015-07-16 05:56:38 -07:00
|
|
|
|
isViblastStarted = false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-13 14:26:11 -07:00
|
|
|
|
if (startTime) {
|
2015-07-16 05:56:38 -07:00
|
|
|
|
|
2015-07-13 14:26:11 -07:00
|
|
|
|
try {
|
|
|
|
|
elem.currentTime = startTime;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
// IE will throw an invalid state exception when trying to set currentTime before starting playback
|
|
|
|
|
}
|
|
|
|
|
requiresSettingStartTimeOnStart = elem.currentTime == 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-15 14:58:52 -07:00
|
|
|
|
tracks = tracks || [];
|
|
|
|
|
|
2015-07-05 11:34:52 -07:00
|
|
|
|
if (enableViblast(val)) {
|
2015-07-03 04:51:45 -07:00
|
|
|
|
|
2015-08-15 14:58:52 -07:00
|
|
|
|
setTracks(elem, tracks);
|
2015-07-06 00:06:09 -07:00
|
|
|
|
|
2015-08-25 19:31:33 -07:00
|
|
|
|
viblast('#' + elem.id).setup({
|
2015-07-09 20:00:03 -07:00
|
|
|
|
key: getViblastKey(),
|
2015-07-03 04:51:45 -07:00
|
|
|
|
stream: val
|
|
|
|
|
});
|
|
|
|
|
|
2015-07-03 09:49:49 -07:00
|
|
|
|
isViblastStarted = true;
|
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
} else {
|
2015-07-13 14:26:11 -07:00
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
elem.src = val;
|
2015-08-24 13:37:34 -07:00
|
|
|
|
elem.autoplay = true;
|
2015-07-06 00:06:09 -07:00
|
|
|
|
|
2015-08-15 14:58:52 -07:00
|
|
|
|
setTracks(elem, tracks);
|
2015-07-06 00:06:09 -07:00
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
$(elem).one("loadedmetadata", onLoadedMetadata);
|
2015-08-24 13:37:34 -07:00
|
|
|
|
playNow = true;
|
2015-07-03 04:51:45 -07:00
|
|
|
|
}
|
2015-08-15 14:58:52 -07:00
|
|
|
|
|
|
|
|
|
var currentTrackIndex = -1;
|
|
|
|
|
for (var i = 0, length = tracks.length; i < length; i++) {
|
|
|
|
|
if (tracks[i].isDefault) {
|
|
|
|
|
currentTrackIndex = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.setCurrentTrackElement(currentTrackIndex);
|
2015-07-03 04:51:45 -07:00
|
|
|
|
}
|
2015-07-03 08:59:12 -07:00
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
currentSrc = val;
|
2015-08-24 13:37:34 -07:00
|
|
|
|
|
|
|
|
|
if (playNow) {
|
|
|
|
|
elem.play();
|
|
|
|
|
}
|
2015-07-03 04:51:45 -07:00
|
|
|
|
};
|
|
|
|
|
|
2015-07-06 00:06:09 -07:00
|
|
|
|
function setTracks(elem, tracks) {
|
2015-07-03 04:51:45 -07:00
|
|
|
|
var html = tracks.map(function (t) {
|
|
|
|
|
|
|
|
|
|
var defaultAttribute = t.isDefault ? ' default' : '';
|
|
|
|
|
|
|
|
|
|
return '<track kind="subtitles" src="' + t.url + '" srclang="' + t.language + '"' + defaultAttribute + '></track>';
|
|
|
|
|
|
|
|
|
|
}).join('');
|
|
|
|
|
|
|
|
|
|
if (html) {
|
2015-07-06 00:06:09 -07:00
|
|
|
|
elem.innerHTML = html;
|
2015-06-07 20:16:42 -07:00
|
|
|
|
}
|
2015-07-06 00:06:09 -07:00
|
|
|
|
}
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
|
|
|
|
self.currentSrc = function () {
|
|
|
|
|
if (mediaElement) {
|
2015-07-03 04:51:45 -07:00
|
|
|
|
// We have to use this cached value because viblast will muck with the url
|
|
|
|
|
return currentSrc;
|
|
|
|
|
//return mediaElement.currentSrc;
|
2015-06-07 20:16:42 -07:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.paused = function () {
|
|
|
|
|
|
|
|
|
|
if (mediaElement) {
|
|
|
|
|
return mediaElement.paused;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
|
2015-06-25 14:50:56 -07:00
|
|
|
|
self.cleanup = function (destroyRenderer) {
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
|
|
|
|
self.setCurrentSrc(null);
|
2015-07-09 20:00:03 -07:00
|
|
|
|
_currentTime = null;
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
|
|
|
|
var elem = mediaElement;
|
|
|
|
|
|
|
|
|
|
if (elem) {
|
|
|
|
|
|
2015-06-29 11:45:42 -07:00
|
|
|
|
if (elem.tagName == 'AUDIO') {
|
|
|
|
|
|
|
|
|
|
Events.off(elem, 'timeupdate', onTimeUpdate);
|
|
|
|
|
Events.off(elem, 'ended', onEnded);
|
|
|
|
|
Events.off(elem, 'volumechange', onVolumeChange);
|
|
|
|
|
Events.off(elem, 'playing', onOneAudioPlaying);
|
|
|
|
|
Events.off(elem, 'play', onPlay);
|
|
|
|
|
Events.off(elem, 'pause', onPause);
|
|
|
|
|
Events.off(elem, 'playing', onPlaying);
|
|
|
|
|
Events.off(elem, 'error', onError);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
Events.off(elem, 'loadedmetadata', onLoadedMetadata);
|
|
|
|
|
Events.off(elem, 'playing', onOneVideoPlaying);
|
|
|
|
|
Events.off(elem, 'timeupdate', onTimeUpdate);
|
|
|
|
|
Events.off(elem, 'ended', onEnded);
|
|
|
|
|
Events.off(elem, 'volumechange', onVolumeChange);
|
|
|
|
|
Events.off(elem, 'play', onPlay);
|
|
|
|
|
Events.off(elem, 'pause', onPause);
|
|
|
|
|
Events.off(elem, 'playing', onPlaying);
|
|
|
|
|
Events.off(elem, 'click', onClick);
|
|
|
|
|
Events.off(elem, 'dblclick', onDblClick);
|
|
|
|
|
Events.off(elem, 'error', onError);
|
|
|
|
|
}
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
|
|
|
|
if (elem.tagName.toLowerCase() != 'audio') {
|
|
|
|
|
$(elem).remove();
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-09-08 10:08:17 -07:00
|
|
|
|
|
|
|
|
|
showStatusBar();
|
2015-06-07 20:16:42 -07:00
|
|
|
|
};
|
|
|
|
|
|
2015-06-13 07:46:59 -07:00
|
|
|
|
self.supportsTextTracks = function () {
|
|
|
|
|
|
|
|
|
|
if (supportsTextTracks == null) {
|
|
|
|
|
supportsTextTracks = document.createElement('video').textTracks != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For now, until ready
|
|
|
|
|
return supportsTextTracks;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.setCurrentTrackElement = function (trackIndex) {
|
|
|
|
|
|
2015-06-26 20:27:38 -07:00
|
|
|
|
Logger.log('Setting new text track index to: ' + trackIndex);
|
2015-06-13 07:46:59 -07:00
|
|
|
|
|
|
|
|
|
var allTracks = mediaElement.textTracks; // get list of tracks
|
|
|
|
|
|
|
|
|
|
var modes = ['disabled', 'showing', 'hidden'];
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < allTracks.length; i++) {
|
|
|
|
|
|
|
|
|
|
var mode;
|
|
|
|
|
|
|
|
|
|
if (trackIndex == i) {
|
|
|
|
|
mode = 1; // show this track
|
|
|
|
|
} else {
|
|
|
|
|
mode = 0; // hide all other tracks
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-26 20:27:38 -07:00
|
|
|
|
Logger.log('Setting track ' + i + ' mode to: ' + mode);
|
2015-06-13 07:46:59 -07:00
|
|
|
|
|
|
|
|
|
// Safari uses integers for the mode property
|
|
|
|
|
// http://www.jwplayer.com/html5/scripting/
|
|
|
|
|
var useNumericMode = false;
|
|
|
|
|
|
|
|
|
|
if (!isNaN(allTracks[i].mode)) {
|
|
|
|
|
useNumericMode = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (useNumericMode) {
|
|
|
|
|
allTracks[i].mode = mode;
|
|
|
|
|
} else {
|
|
|
|
|
allTracks[i].mode = modes[mode];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.updateTextStreamUrls = function (startPositionTicks) {
|
|
|
|
|
|
|
|
|
|
if (!self.supportsTextTracks()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var allTracks = mediaElement.textTracks; // get list of tracks
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < allTracks.length; i++) {
|
|
|
|
|
|
|
|
|
|
var track = allTracks[i];
|
|
|
|
|
|
|
|
|
|
// This throws an error in IE, but is fine in chrome
|
|
|
|
|
// In IE it's not necessary anyway because changing the src seems to be enough
|
|
|
|
|
try {
|
|
|
|
|
while (track.cues.length) {
|
|
|
|
|
track.removeCue(track.cues[0]);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
2015-06-26 20:27:38 -07:00
|
|
|
|
Logger.log('Error removing cue from textTrack');
|
2015-06-13 07:46:59 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$('track', mediaElement).each(function () {
|
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
this.src = replaceQueryString(this.src, 'startPositionTicks', startPositionTicks);
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.enableCustomVideoControls = function () {
|
2015-06-13 07:46:59 -07:00
|
|
|
|
|
2015-09-08 07:35:52 -07:00
|
|
|
|
if (AppInfo.isNativeApp && $.browser.safari) {
|
2015-09-27 14:02:39 -07:00
|
|
|
|
|
|
|
|
|
if (navigator.userAgent.toLowerCase().indexOf('iphone') != -1) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Need to disable it in order to support picture in picture
|
|
|
|
|
return false;
|
2015-09-08 07:35:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
return self.canAutoPlayVideo() && !$.browser.mobile;
|
|
|
|
|
};
|
2015-06-13 07:46:59 -07:00
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
self.canAutoPlayVideo = function () {
|
2015-06-13 07:46:59 -07:00
|
|
|
|
|
2015-07-03 04:51:45 -07:00
|
|
|
|
if (AppInfo.isNativeApp) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($.browser.mobile) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.init = function () {
|
|
|
|
|
|
|
|
|
|
var deferred = DeferredBuilder.Deferred();
|
|
|
|
|
|
2015-07-03 09:49:49 -07:00
|
|
|
|
if (options.type == 'video' && enableViblast()) {
|
2015-07-03 04:51:45 -07:00
|
|
|
|
|
2015-07-09 20:00:03 -07:00
|
|
|
|
requireViblast(function () {
|
2015-07-03 04:51:45 -07:00
|
|
|
|
|
|
|
|
|
deferred.resolve();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
deferred.resolve();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return deferred.promise();
|
2015-06-13 07:46:59 -07:00
|
|
|
|
};
|
|
|
|
|
|
2015-07-03 09:49:49 -07:00
|
|
|
|
if (options.type == 'audio') {
|
2015-06-07 20:16:42 -07:00
|
|
|
|
mediaElement = createAudioElement();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mediaElement = createVideoElement();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-10 06:37:07 -07:00
|
|
|
|
if (!window.AudioRenderer) {
|
2015-07-03 09:49:49 -07:00
|
|
|
|
window.AudioRenderer = function (options) {
|
|
|
|
|
options = options || {};
|
|
|
|
|
options.type = 'audio';
|
|
|
|
|
|
|
|
|
|
return new htmlMediaRenderer(options);
|
|
|
|
|
};
|
2015-06-10 06:37:07 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!window.VideoRenderer) {
|
2015-07-03 09:49:49 -07:00
|
|
|
|
window.VideoRenderer = function (options) {
|
|
|
|
|
options = options || {};
|
|
|
|
|
options.type = 'video';
|
|
|
|
|
|
|
|
|
|
return new htmlMediaRenderer(options);
|
|
|
|
|
};
|
2015-06-10 06:37:07 -07:00
|
|
|
|
}
|
2015-06-07 20:16:42 -07:00
|
|
|
|
|
|
|
|
|
})();
|