/*******************************************************************************
* Copyright (c) 2017 Genialist Software Ltd.
* All rights reserved.
******************************************************************************/
var m_choose_subtitles_text = "Choose the Sub-Titles:";
var m_none_text = "None";
var m_resume_text_before = "Resume from ";
var m_resume_text_after = "";
var m_begining_text = "Play from beginning";
var m_choose_lang_text = "Choose the Language:";
var record_fullscreen = true;
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
const pPlaylistUtil = new (function () {
this.playTimeCookieName = function(p_media) {
return 'p-'+pLocation.path(p_media.doc_url || ((p_media.media)? p_media.media.doc_url : null) || p_media.request_url).substring(url_prefix.length);
};
this.highlight = function(p_element_id, p_set) {
if (p_set===true)
pElement.addClassName(p_element_id, 'playlist-highlight');
else
pElement.removeClassName(p_element_id, 'playlist-highlight-error playlist-highlight');
};
this.highlightError = function(p_element_id) {
pElement.addClassName(p_element_id, 'playlist-highlight-error');
};
this.options = {
OPTION_CHAPTERS: pROSE.newStringProp('pl-chapters', [ 'auto', '1', '0' ]),
OPTION_AUDIO_TRACKS: pROSE.newStringProp('pl-audioTracks', [ 'auto', '1', '0' ]),
OPTION_YOUTUBE_SHOW_RELATED: pROSE.newBooleanProp('youtube-show-related'),
OPTION_DEVICE_LOCAL: pROSE.newStringProp('device-local', (pLocation.isLocalhost())? 'auto' : 'never'),
OPTION_DEVICE_TRANSCODE: pROSE.newStringProp('device-transcode', [ 'auto', '1', '0' ]),
OPTION_PLUGIN_HLS_ENABLED: pROSE.newBooleanProp('plugin-hlsjs-enabled', true),
//OPTION_PLUGIN_VLC_ENABLED: { name: 'plugin-vlc-enabled', type: 'boolean', vdefault: false },//pDevice.isFirefox() },
//OPTION_PLUGIN_WMP_ENABLED: pROSE.newBooleanProp('plugin-wmp-enabled'),
OPTION_REPORT_TIME: pROSE.newBooleanProp('sync-report-time-videos', pDevice.isFirefox() || pDevice.isChrome()),
OPTION_DEVICE_SCALE_VIDEOS: pROSE.newBooleanProp('scale-videos', true),
OPTION_VIDEO_NOHTTPS: pROSE.newBooleanProp('videos-nohttps', pDevice.isIOS()),
OPTION_WEBVTT: pROSE.newBooleanProp('webvtt'),
OPTION_LOOP_PLAYLIST: pROSE.newBooleanProp('playlist-loop-playlist', true),
OPTION_LOOP_TRACK: pROSE.newBooleanProp('playlist-loop-track'),
OPTION_SHOW_VIDEOS: pROSE.newBooleanProp('playlist-show-video'),
OPTION_SHUFFLE: pROSE.newBooleanProp('playlist-shuffle'),
OPTION_NOSLEEP: pROSE.newBooleanProp('nosleep', pDevice.isAndroid() || pDevice.isIOS()),
OPTION_CANPLAY_PLAY: pROSE.newBooleanProp('canplay-play'),
OPTION_PREFER_VO: pROSE.newBooleanProp('prefer-vo', true),
OPTION_ONERROR_NEXT: pROSE.newBooleanProp('playlist-onerror-next', true),
OPTION_FULLSCREEN: pROSE.newBooleanProp('fs'),
OPTION_CHANGE_DOCTITLE: pROSE.newBooleanProp('change-doctitle', true),
OPTION_MAX_VIDEO_BITRATE: { name: 'vbitrate', type: 'int', vdefault: 1000 },
OPTION_MOVIE_TRAILERS: pROSE.newBooleanProp('trailers'),// !pDevice.isMobile())
OPTION_PREFER_STREAMING: pROSE.newBooleanProp('prefer-streaming', true)
};
//*** INIT OPTIONS
for(var i_option in this.options) {
var p = this.options[i_option];
pROSE.getProp(p);
p.get = (function() { return pROSE.getProp(this); }).bind(p);
p.set = (function(s) { pROSE.setProp(this, s); }).bind(p);
Object.defineProperty(this, i_option, { get: p.get, set: p.set });
}
});
//keep for vlc
pPlaylistUtil.options_controls = [ pPlaylistUtil.options.OPTION_LOOP_PLAYLIST, pPlaylistUtil.options.OPTION_LOOP_TRACK, pPlaylistUtil.options.OPTION_SHOW_VIDEOS, pPlaylistUtil.options.OPTION_SHUFFLE ];
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
const noSleep_media = 'data:video/mp4;base64,AAAAIGZ0eXBtcDQyAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAACKBtZGF0AAAC8wYF///v3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0MiByMjQ3OSBkZDc5YTYxIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0wIHRocmVhZHM9NiBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MSBrZXlpbnQ9MzAwIGtleWludF9taW49MzAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD0xMCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIwLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IHZidl9tYXhyYXRlPTIwMDAwIHZidl9idWZzaXplPTI1MDAwIGNyZl9tYXg9MC4wIG5hbF9ocmQ9bm9uZSBmaWxsZXI9MCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAOWWIhAA3//p+C7v8tDDSTjf97w55i3SbRPO4ZY+hkjD5hbkAkL3zpJ6h/LR1CAABzgB1kqqzUorlhQAAAAxBmiQYhn/+qZYADLgAAAAJQZ5CQhX/AAj5IQAD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';
//Detect iOS browsers < version 10
const oldIOS = typeof navigator !== 'undefined' && parseFloat(
('' + (/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0, ''])[1])
.replace('undefined', '3_2').replace('_', '.').replace('_', '')
) < 10 && !window.MSStream
const noSleep = new (function() {
var that = this, noSleepTimer, noSleepVideo;
if (oldIOS) {
//this.noSleepTimer = null
} else {
// Set up no sleep video element
noSleepVideo = document.createElement('video')
noSleepVideo.setAttribute('playsinline', '')
noSleepVideo.setAttribute('src', noSleep_media)
noSleepVideo.addEventListener('timeupdate', function (e) {
if (noSleepVideo.currentTime > 0.5) {
noSleepVideo.currentTime = Math.random()
}
});
}
this.enable = function() {
if (oldIOS) {
that.disable()
noSleepTimer = window.setInterval(function () {
window.location.href = '/'
window.setTimeout(window.stop, 0)
}, 15000)
} else {
noSleepVideo.play()
}
};
this.disable = function() {
if (oldIOS) {
if (noSleepTimer) {
window.clearInterval(noSleepTimer)
noSleepTimer = null
}
} else {
noSleepVideo.pause()
}
};
});
function enableNoSleep() {
noSleep.enable();
document.removeEventListener('click', enableNoSleep, false);
}
function disableNoSleep() {
noSleep.disable();
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
const pMedia = new (function() {
this.externalPlay = function(m) {
if (m && m.provided===true)
if (!m.metadata_provider || ![ 'youtube', '(Unknown)', '(Radio)' ].includes(m.metadata_provider))
return m.url && pLocation.path(m.url).indexOf(url_prefix)<0;
};
});
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
const pTrackListUtil = new (function () {
var that = this;
function f_isVideo(t) { return t.type == 'v'; }
function f_isAudio(t) { return t.type == 'a'; }
function f_isExternalSubtitle(t) { return t.type == 's' && t.filename; }
this.isSubtitle = function(t) {
return t.type == 's';
};
this.isSupportedSubtitle = function(t) {
var c = t.metadata_format.toLowerCase();
return c.indexOf('vobsub')<0 && c.indexOf('dvdsub')<0 && c.indexOf('mp4s')<0;
};
this.tracks = function(media) {
return (media.tracks && media.tracks != "null")? media.tracks : [];
};
this.getVideoCodec = function(l, p_default) {
var t = (l || []).find(f_isVideo);
return t? pString.substring_after(t.metadata_format, 'V_') : p_default;
};
this.getAudioCodec = function(l, p_default) {
var t = (l || []).find(f_isAudio);
return t? pString.substring_after(t.metadata_format, 'A_') : p_default;
};
this.countAudioTracks = function(l) {
return l? l.filter(f_isAudio).length : 0;
};
this.countSubtitleTracks = function(l, s) {
if (s) return l? l.filter(that.isSubtitle).filter(that.isSupportedSubtitle).length : 0;
return l? l.filter(that.isSubtitle).length : 0;
};
this.countVideoTracks = function(l) {
return l? l.filter(f_isVideo).length : 0;
};
this.countExternalSubtitleTracks = function(l) {
return l? l.filter(f_isExternalSubtitle).length : 0;
};
this.shortName = function(t, d) {
var r = "";
if (t.name && t.name.toLowerCase() != "null")
r += t.name;
return r.length<1? (d || '(Unknown)') : r;
};
this.longName = function(t, l, d) {
var r = that.shortName(t, d), sn = (l || []).find(function(tt) { return tt != t && tt.type == t.type && that.shortName(tt, d) == r})
if (sn && t.metadata_lang) {
var l = pLang.display(t.metadata_lang);
if (l != r) {
r += ((r != "")? " - ":"");
r += l;
}
//r += ((r != "")? " - ":"");
//r += pLang.display(t.metadata_lang) + ((t.forced === true)? " (forced)":"");
}
return r.length<1? '(Unknown)' : r;
};
this.longLangName = function(t) {
if (t && t.metadata_lang)
return pLang.display(t.metadata_lang);// + ((t.forced === true)? " (forced)":"");
};
/** @param ht Video or Audio track from <video> or <audio> element */
this.displayAudioTrack = function(ht, i, m) {
var t = that.tracks(m).filter(f_isAudio), a = (i>=0 && i<t.length)? t[i] : null;
if (pString.v(ht.label)) {
var l = pLang.display(pString.sv(ht.language, that.longLangName(a)))
return ht.label + (pString.v(l)? ' - '+l:'');
}
return a? that.longName(a, t, '') : '(Unknown)';
};
});
/******************************************************************************/
/*** Media Player for <video> elements ***/
/******************************************************************************/
pConst.f_enable_fadeout_video_controls = function() {
pElement.addClassName(pElement.x('vlc-foreground', true), 'fadeout');
/*
pElement.addClassName(pElement.x('vlc-fullscreen-close', true), 'fadeout');
pElement.addClassName(pElement.x('vlc-fullscreen-title', true), 'fadeout');
pElement.addClassName(pElement.x('video-controls', true), 'fadeout');*/
};
pConst.f_disable_fadeout_video_controls = function() {
pElement.removeClassName(pElement.x('vlc-foreground', true), 'fadeout');
/*
pElement.removeClassName(pElement.x('vlc-fullscreen-close', true), 'fadeout');
pElement.removeClassName(pElement.x('vlc-fullscreen-title', true), 'fadeout');
pElement.removeClassName(pElement.x('video-controls', true), 'fadeout');*/
};
function pMediaPlayer(x) {
var that = this, eh = new pEventHandler(), m_options = new pMap(), m_enabled = true, m_element = pElement.x(x), m_temp_hls,
m_controls;
this.tracePrefix = 'VideoPlayer';
/*** Indicates if HLS is enabled and supported or not. */
function hls() {
return pROSE.getProp(pPlaylistUtil.options.OPTION_PLUGIN_HLS_ENABLED) && Hls.isSupported();
}
var f = function() {
pConst.f_disable_fadeout_video_controls();
if (!m_element.paused)
pDocument.setTimeout('video-controls', pConst.f_enable_fadeout_video_controls, 2000);
};
pElement.x('div-vlc-main').addEventListener('mousemove', f);
pElement.x('div-vlc-main').addEventListener('touch', f);
pElement.x(m_element).addEventListener('mousemove', f);
pElement.x(m_element).addEventListener('touch', f);
// "id" property
Object.defineProperty(this, "id", { get: function() { return m_element.id; }});
// "element" property
Object.defineProperty(this, "element", { get: function() { return m_element; }});
// "audioTracks" property
Object.defineProperty(this, "audioTracks", { get: function() { return m_element.audioTracks; }});
// "textTracks" property
Object.defineProperty(this, "textTracks", { get: function() { return m_element.textTracks; }});
// "videoTracks" property
Object.defineProperty(this, "videoTracks", { get: function() { return m_element.videoTracks; }});
//*** EXPOSE EVENT HANDLER
function f_event(e) {
//if (e_id == "ended")
//alert(e.type);
//console.log(e);
if (e.type == "error") {
if (e.srcElement && e.srcElement.error && e.srcElement.error.code == 4) {
//pApplicationUI.errorDialog({ text: 'Failed to play audio media...' });//, icon: { src: '/resources/html/images/32x32/picture_error.png' } });
eh.fireEvent("error", that, { id: 'error', msg: 'Failed to play video media', orgError: e.srcElement.error.code, src: that.source });//this);
return;
}
}
if (e.type == "timeupdate") {
//*** RESUME
var r = parseInt(m_options.getValue("resume-time", 0)) / 1000;
if (r > 0) {
//var i_start = i_resume_time;// / 1000;
if (m_element.currentTime < r)
m_element.currentTime = r;
m_options.remove("resume-time");
}
var s = parseInt(m_options.getValue("start-time", 0)) / 1000;
if (s > 0) {
//var i_start = i_start_time;// / 1000;
if (m_element.currentTime < s)
m_element.currentTime = s;
}
s = parseInt(m_options.getValue("stop-time", 0)) / 1000;
if (s > 0) {
//var i_stop = i_stop_time;// / 1000;
if (m_element.currentTime >= s)
eh.fireEvent("ended", that);
//this.doEnd(p);
}
}
eh.fireEvent(e.type, that);
};
this.addEventListener = function(eid, f) {
if (eid != "timeupdate")
if (eh.countListeners(eid)==0)
m_element.addEventListener(eid, f_event, false);
eh.addEventListener(eid, f);
};
this.removeEventListener = function(eid, f) {
eh.removeEventListener(eid, f);
if (eid != "timeupdate")
if (eh.countListeners(eid)==0)
m_element.removeEventListener(eid, f_event, false);
};
// listen for timeupdate events
m_element.addEventListener("timeupdate", f_event, false);
// "currentTime" property (time in ms)
Object.defineProperty(this, "currentTime", {
get: function() { return m_element.currentTime; },
set: function(v) { m_element.currentTime = v; }
});
m_controls = new pVideoControls(m_element, { play: 'v0-play' });
this.play = function() {
m_element.play();
pConst.f_enable_fadeout_video_controls();
};
m_element.addEventListener('play', pConst.f_enable_fadeout_video_controls);
m_element.addEventListener('canplay', pConst.f_enable_fadeout_video_controls);
this.pause = function() {
pConsole.info(that, "Pause...");
m_element.pause();
};
m_element.addEventListener('pause', pConst.f_disable_fadeout_video_controls);
this.togglePause = function() {
if (m_element.paused)
m_element.play();
else
m_element.pause();
};
this.load = function() {
m_element.load();
};
// "source" property
Object.defineProperty(this, "source", { get: function() { return m_element.src; }, set: function(p_src) {
//*** SETUP NOSLEEP
if (pPlaylistUtil.OPTION_NOSLEEP) {
if (p_src) enableNoSleep(); else disableNoSleep();
}
//*** SETUP CONTROLS
if (p_src) {
var p = pLocation.path(p_src.url);
if (p.endsWith("/play.mp3"))
p_src.url = p.substring(0, p.length-"/play.mp3".length);
m_controls.start_time = parseInt(p_src.start_time || -1);
m_controls.stop_time = parseInt(p_src.stop_time || -1);
m_controls.time_range.enabled = true;
m_controls.volume_range.enabled = true;
//m_controls.resetTime();
//alert(p_src.url);
}
else {
m_controls.time_range.enabled = false;
m_controls.volume_range.enabled = false;
}
m_controls.resetTime();
//m_controls.time_range.value = 0;
//*** SETUP SRC
if (m_temp_hls)
m_temp_hls.destroy();
if (hls() === true) {
if (p_src && p_src.hls === true) {
pHTTPRequest.get(p_src.url).then(function() {
m_temp_hls = new Hls();
m_temp_hls.loadSource(p_src.url);
m_temp_hls.attachMedia(m_element);
//m_temp_hls.on(Hls.Events.MANIFEST_PARSED, m_play);
});
}
else
pElement.setSrc(m_element, p_src? p_src.url : null);
}
else
pElement.setSrc(m_element, p_src? p_src.url : null);
//*** SETUP OPTIONS
m_options.clear();
if (p_src)
(p_src.options || []).forEach(function(o) {
var pos = o.indexOf('=');
if (pos>0)
m_options.put(o.substring(0, pos), o.substring(pos+1));
});
//*** SETUP TITLE
if (pDevice.isMobile())
m_element.title = p_src? p_src.title : null;
}});
this.canTranscode = function() {
return pDevice.isIOS() || hls();
};
this.canPlayLocalFiles = function() {
return false;
};
this.capture = function() {
var canvas = document.createElement('canvas');
canvas.width = 640;
canvas.height = 480;
var ctx = canvas.getContext('2d');
//draw image to canvas. scale to target dimensions
ctx.drawImage(m_element, 0, 0, canvas.width, canvas.height);
//convert to desired file format
return canvas.toDataURL('image/jpeg'); // can also use 'image/png'
};
// "enabled" property
Object.defineProperty(this, "enabled", { get: function() { return m_enabled; }, set: function(s) { if (typeof s == "boolean") m_enabled = s; }});
// "type" property
Object.defineProperty(this, "type", { get: function() { return "video" }});
// "fullscreen" property
Object.defineProperty(this, "fullscreen", { get: pDocument.isFullScreen, set: function(s) {
if (typeof s == "boolean") {
if (s === false)
pDocument.exitFullScreen();//m_element);
else
pDocument.fullScreen('div-vlc-main');//m_element);
}
}});
this.show = function() {
pElement.addClassName('video-controls', 'visible');
pDocument.show(m_element);
};
this.hide = function() {
pElement.removeClassName('video-controls', 'visible');
pDocument.hide(m_element);
m_controls.time_range.enabled = false;
m_controls.volume_range.enabled = false;
};
};
/******************************************************************************/
/*** Media Player for <audio> elements ***/
/******************************************************************************/
function pMediaPlayer_Audio(x) {
var that = this, eh = new pEventHandler(), m_options = new pMap(), m_enabled = true,
element_next, element_prev, m_element = pElement.x(x), element_curr = m_element, element_next_curr,
m_controls, m_time_range, m_volume_range;
this.tracePrefix = 'AudioPlayer';
// "id" property
Object.defineProperty(this, "id", { get: function() { return m_element.id; }});
// "element" property
Object.defineProperty(this, "element", { get: function() { return element_curr; }});
if (pROSE.getProp('audio-cache-next')) {
element_next = pElement.x(that.id + '-next');
element_next_curr = element_next;
element_prev = pElement.x(that.id + '-prev');
}
//*** EXPOSE EVENT HANDLER
function f_event(e) {
//console.log(e);
//if (e.type == "ended")
// console.log(e.type);
//alert(e.type);
if (e.type == "error") {
if (e.srcElement && e.srcElement.error && e.srcElement.error.code == 4) {
//pApplicationUI.errorDialog({ text: 'Failed to play audio media...' });//, icon: { src: '/resources/html/images/32x32/picture_error.png' } });
eh.fireEvent("error", that, { id: 'error', msg: 'Failed to play audio media', orgError: e.srcElement.error.code, src: that.source });//this);
return;
}
}
if (e.type == "timeupdate") {
//*** RESUME
var r = parseInt(m_options.getValue("resume-time", 0)) / 1000;
if (r > 0) {
//var i_start = r;// / 1000;
if (element_curr.currentTime < r)
element_curr.currentTime = r;
m_options.remove("resume-time");
}
var s = parseInt(m_options.getValue("start-time", 0)) / 1000;
if (s > 0) {
//var i_start = i_start_time;// / 1000;
//pConsole.debug('MediaPlayerAudio', "start: " + i_start + " - " + p.currentTime);
if (element_curr.currentTime < s)
element_curr.currentTime = s;
}
s = parseInt(m_options.getValue("stop-time", 0)) / 1000;
if (s > 0) {
//var i_stop = i_stop_time;// / 1000;
//pConsole.info('MediaPlayerAudio', "start: " + i_stop + " - " + p.currentTime);
if (element_curr.currentTime >= s)
eh.fireEvent("ended", that);
//this.doEnd(p);
}
}
if (element_next)
if (e.type == "error")
if (that.id == element_next.id && element_curr != element_next)
return;
eh.fireEvent(e.type, that);
}
this.addEventListener = function(eid, f) {
if (eid != "timeupdate")
if (eh.countListeners(eid)==0) {
m_element.addEventListener(eid, f_event, false);
if (element_next)
element_next.addEventListener(eid, f_event, false);
if (element_prev)
element_prev.addEventListener(eid, f_event, false);
}
eh.addEventListener(eid, f);
};
this.removeEventListener = function(eid, f) {
eh.removeEventListener(eid, f);
if (eid != "timeupdate")
if (eh.countListeners(eid)==0) {
m_element.removeEventListener(eid, f_event, false);
if (element_next)
element_next.removeEventListener(eid, f_event, false);
if (element_prev)
element_prev.removeEventListener(eid, f_event, false);
}
};
// listen for timeupdate events
m_element.addEventListener("timeupdate", f_event, false);
if (element_next)
element_next.addEventListener("timeupdate", f_event, false);
if (element_prev)
element_prev.addEventListener("timeupdate", f_event, false);
// "muted" property
Object.defineProperty(this, "muted", {
get: function() { return element_curr.muted; },
set: function(v) { m_element.muted = v;
if (element_next)
element_next.muted = v;
if (element_prev)
element_prev.muted = v;
}
});
// "volume" property
Object.defineProperty(this, "volume", {
get: function() { return element_curr.volume; },
set: function(v) { m_element.volume = v;
if (element_next)
element_next.volume = v;
if (element_prev)
element_prev.volume = v;
}
});
// other properties (currentTime and duration in seconds, as for audio and video HTML elements)
[ "buffered", "currentTime", "duration", "paused", "seekable" ].forEach(function(i) {
Object.defineProperty(that, i, { get: function() { return element_curr[i]; }, set: function(v) { element_curr[i] = v; }});
});
this.play = function() {
element_curr.play();
}
this.pause = function() {
element_curr.pause();
};
this.togglePause = function() {
if (element_curr.paused)
element_curr.play();
else
element_curr.pause();
};
this.load = function() {
element_curr.load();
};
function f_update_controls(p_src) {
m_controls.start_time = p_src? parseInt(p_src.start_time || -1) : -1;
m_stop_time = p_src? parseInt(p_src.stop_time || -1) : -1;
m_time_range.value = 0;
m_time_range.enabled = p_src != null;
m_volume_range.enabled = p_src != null;
if (p_src)
pElement.removeClassName(m_controls.playButton, 'disabled');
else {
pElement.removeClassName(m_controls.playButton, 'paused');
pElement.addClassName(m_controls.playButton, 'disabled');
}
};
// "source" property
var element_next_src;
Object.defineProperty(this, "source", { get: function() { return m_element.src; }, set: function(p_src) {
// after...
if (!m_controls) {
m_controls = new pVideoControls(that, { play: 'a0-play', time1: 'a0-time1', time2: 'a0-time2', volume: 'a0-volume-bar', seek: 'a0-seek-bar', mute: 'a0-mute' }),
m_time_range = m_controls.time_range, m_volume_range = m_controls.volume_range;
}
if (pPlaylistUtil.OPTION_NOSLEEP) {
if (p_src) enableNoSleep(); else disableNoSleep();
}
if (element_next && p_src) {
if (element_curr == m_element) {
if ((element_next_src == p_src.url || element_next_src + '?undefined' == p_src.url)) {
m_element.pause();
element_curr = element_next;
element_next_curr = m_element;
//if (!pDevice.isIOS() && !pDevice.isAndroid())
// pDocument.show(element_next);
//pDocument.hide(m_element);
//element_curr.src = p_src.url;
f_setOptions(p_src);
element_curr.title = p_src.title;
f_update_controls(p_src);
return;
}
}
if (element_curr == element_next) {
if ((element_next_src == p_src.url || element_next_src + '?undefined' == p_src.url)) {
element_next.pause();
element_curr = m_element;
element_next_curr = element_next;
//if (!pDevice.isIOS() && !pDevice.isAndroid())
// pDocument.show(m_element);
//pDocument.hide(element_next);
//element_curr.src = p_src.url;
f_setOptions(p_src);
element_curr.title = p_src.title;
f_update_controls(p_src);
return;
}
}
}
f_update_controls(p_src);
setTimeout(function() {
pElement.setSrc(element_curr, p_src? p_src.url : null);
f_setOptions(p_src);
element_curr.title = p_src? p_src.title : null;
}, 1);
}});
function f_setOptions(p_src) {
m_options.clear();
if (p_src)
(p_src.options || []).forEach(function(o) {
var pos = o.indexOf('=');
if (pos>0)
m_options.put(o.substring(0, pos), o.substring(pos+1));
});
};
this.canTranscode = function() {
return false;
};
this.canPlayLocalFiles = function() {
return false;
};
// "enabled" property
Object.defineProperty(this, "enabled", { get: function() { return m_enabled; }, set: function(s) { if (typeof s == "boolean") m_enabled = s; }});
// "type" property
Object.defineProperty(this, "type", { get: function() { return "audio" }});
// "fullscreen" property
Object.defineProperty(this, "fullscreen", { get: function() { return false; }, set: function(value) { }});
this.setNextSource = function(p_src_current, p_src) {
if (p_src_current.url == p_src.url || p_src_current.url == p_src.url+'?undefined')
return;
pConsole.info(that, "SetNextSource: " + p_src.url);
if (element_next) {
element_next_src = p_src.url;
element_next_curr.src = p_src.url;
element_next_curr.load();
}
};
this.show = function() {
//pDocument.show(element_curr);
};
this.hide = function() {
if (m_controls) {
m_controls.time_range.value = 0;
m_controls.time_range.enabled = false;
m_controls.volume_range.enabled = false;
pElement.removeClassName(m_controls.playButton, 'paused');
pElement.addClassName(m_controls.playButton, 'disabled');
//pDocument.hide(element_curr);
}
};
};
/******************************************************************************/
/*** List of Medias (including current position, shuffling, length, ...) ***/
/******************************************************************************/
function pMediaList() {
var that = this, m_medias_play_count = 0; // after medias are cleared, this indicates how many have been played
var m_shuffle = false, m_medias = [ "" ], m_shuffled = []; // shuffled list of media indexes (from m_medias list), eg [ 2, 4, 1, 3, ... ]
var m_index = 0; // index of media being played (from m_medias list)
function f_error(m) { return m.error; }
this.clear = function() {
m_medias = [ "" ];
m_shuffled = [];
m_index = 0;
m_medias_play_count = 0;
};
this.add = function(p_item) {
m_medias.push(p_item);
//set position (starts with 1)
p_item.position = m_medias.length-1;
m_shuffled.push(that.length);
if (m_shuffle === true)
reshuffle();
};
this.getValue = function(n) {
return m_medias[n];
};
this.findIndex = function(p_function) {
return m_medias.findIndex(p_function);
};
this.error = function() {
return m_medias.slice(1).every(f_error);
};
// "current" property
Object.defineProperty(this, "current", { get: function() {
if (m_index>0 && m_medias.length>1)
return m_medias[m_index];
//return null;
}});
this.reshuffle = function() {
m_shuffled = pArray.shuffle(m_shuffled);
};
this.firstMediaIndex = function() {
return m_shuffle? m_shuffled[0] : 1;
};
this.lastMediaIndex = function() {
return m_shuffle? m_shuffled[m_shuffled.length-1] : m_medias.length-1;
};
this.nextMediaIndex = function() {
return m_shuffle? m_shuffled[m_shuffled.indexOf(m_index)+1] : m_index+1;
};
this.previousMediaIndex = function() {
return m_shuffle? m_shuffled[m_shuffled.indexOf(m_index)-1] : m_index-1;
};
// position of media being played in playing order (0: nothing, 1: first, "length": last)
this.currentMediaPlayingPosition = function() {
return m_shuffle? m_shuffled.indexOf(m_index)+1 : m_index;
};
// "index" property
Object.defineProperty(this, "index", { get: function() { return m_index; }, set: function(n) { m_index = n; }});
// "shuffle" property
Object.defineProperty(this, "shuffle", {
get: function() { return m_shuffle; },
set: function(v) { m_shuffle = v; if (v) that.reshuffle(); }
});
// "length" property
Object.defineProperty(this, "length", { get: function() { return m_medias.length-1 }});
// "playCount" property
Object.defineProperty(this, "playCount", { get: function() { return m_medias_play_count; }, set: function(n) { m_medias_play_count = n; } });
}
/******************************************************************************/
/*** Playlist Instance ***/
/******************************************************************************/
function pPlaylistInstance(p_id, p_players, p_controls) {
var that = this, m_id = p_id, eh = new pEventHandler(), doc_title_new, play_by_user;
this.medias = new pMediaList();
this.controls = p_controls;
this.tracePrefix = 'Playlist';
this.doc_title_old = null;
// "id" property
Object.defineProperty(this, "id", { get: function() { return m_id; }});
//*** EXPOSE EVENT HANDLER
this.addEventListener = function(eid, f) {
eh.addEventListener(eid, f);
};
this.removeEventListener = function(eid, f) {
eh.removeEventListener(eid, f);
};
this.addMedia = function(p_item) {
that.medias.add(p_item);
};
// "index" property
Object.defineProperty(this, "index", { get: function() { return that.medias.index; }, set: function(n) { that.medias.index = n; }});
// "shuffle" property
Object.defineProperty(this, "shuffle", { get: function() { return that.medias.shuffle; }, set: function(p_set) { that.medias.shuffle = p_set; }});
// "length" property
Object.defineProperty(this, "length", { get: function() { return that.medias.length }});
// "currentTime" property
Object.defineProperty(this, "currentTime", {
get: function() { return that.getPlayer().currentTime },
set: function(v) { try { that.getPlayer().currentTime = v; } catch(e) { pConsole.error('Playlist', 'Failed to set time: ' + v, e); }}
});
var m_video = false;
function f_ended() {
if (pString.v(that.doc_title_old))
document.title = that.doc_title_old;
pConsole.info(that, "player event: ended...");
var p = that.getPlayer();
if (p)
p.pause();
//i_player.currentTime = 0;
/** Report current time back to server **/
f_reportTime();
f_reportEnded();
if (that.loopTrack === true)
try {
that.play();
return;
}
catch (e) {
console.log(e);
}
if (that.medias.currentMediaPlayingPosition()==that.medias.length) {
if (that.loop === true)
that.play(that.medias.firstMediaIndex());
else {
pConsole.info(that, 'Ended...');
eh.fireEvent("ended", that);
}
}
else
that.next();
}
/** Report current time back to server **/
var disable_reportTime
function f_reportTime(p_time) {
if (p_time==null) p_time = -1;
if (disable_reportTime) {
//pConsole.info(this, "Disabled Report Time: " + pDate.toLocaleString(new Date()));
return;
}
var i_time = (p_time>=0)? p_time : ((that.getPlayer())? that.getPlayer().currentTime * 1000 : -1);
if (i_time >= 0) {
var m = that.medias.current;
if (m) {
//pConsole.info(this, "i_time: " + i_media.play_time);
if (!m.play_time || m.play_time<=0 || Math.floor(m.play_time)!=Math.floor(i_time)) {
var u = m.play_updated_url;
if (u) {
pConsole.debug(that, "Report Time: " + pDate.toLocaleString(new Date()) + ': ' + i_time);
pHTTPRequest.post(u + "?action=play-update&time=" + i_time);
}
}
m.play_time = i_time;
//alert(pJSON.pretty(JSON.stringify(i_media)));
if (!m.media || pMediaLibrary.getLIDfromURL(m.media.doc_url) != 'music.medias')
pCookieManager.set(pPlaylistUtil.playTimeCookieName(m), ""+i_time);
}
}
};
/** Report end of media back to server **/
function f_reportEnded() {
var m = that.medias.current;
if (m && m.play_ended_url)
pHTTPRequest.get({ url: m.play_ended_url, responseType: "arraybuffer" });
}
var last_time, m_paused;
function f_timed() {
m_paused = false;
//i_playlist.doControlTime(i_playlist.getPlayer());
eh.fireEvent("timeupdate", that);
/** Report current time back to server **/
if (pROSE.getProp(pPlaylistUtil.options.OPTION_REPORT_TIME) != 'false') {
var i_player = that.getPlayer()
if (i_player) {
var i_time = i_player.currentTime * 1000;
if (null==last_time || 0 == last_time || (i_time - last_time) >= 3000) {
last_time = i_time;
f_reportTime(i_time);
}
}
}
//pConsole.debug('Playlist', "Timeupdate: " + i_playlist.getPlayer().currentTime);
}
this.doControlTime = function(i_player) {
var i_media = that.medias.current;
if (null==i_media)
return;
if (i_media.start_time > 0) {
var i_start = i_media.start_time / 1000;
if (i_player.currentTime < i_start)
i_player.currentTime = i_start;
}
if (i_media.stop_time > 0) {
var i_stop = i_media.stop_time / 1000;
if (i_player.currentTime >= i_stop)
f_ended(i_player);
}
};
var m_player;
this.getPlayer = function() {
if (!m_player)
pConsole.debug(that, 'No player chosen yet...');
return m_player;
};
this.capture = function() {
var i_player = that.getPlayer();
if (i_player && i_player.capture)
return i_player.capture();
//return null;
};
function f_show(i_player) {
if (i_player.show)
i_player.show();
else
pDocument.show(i_player.element);
}
function f_hide(i_player) {
if (i_player.hide)
i_player.hide();
else
pDocument.hide(i_player.element);
}
function f_showPlayer(i_player, i_player_audio, i_player_video, i_media, i_show) {
//*** NOTIFY
if (i_show === true)
eh.fireEvent("show-before", this);
if (null==i_player_audio || (i_media.hasVideo===true && m_showVideos)) {
if (i_player!=i_player_video) {
if (null!=i_player) {
i_player.pause();
i_player.currentTime = 0;
//if (i_player.fullscreen)
record_fullscreen = false;
i_player.fullscreen = false;
f_hide(i_player);
}
if (i_show === true) {
this.m_players.forEach(function(player) {
if (player != i_player_video)
f_hide(player);
});
f_show(i_player_video);
eh.fireEvent("show-video", this);
}
}
i_player = m_player = i_player_video;
m_video = true;
}
else {
if (i_player!=i_player_audio) {
if (null!=i_player) {
i_player.pause();
i_player.currentTime = 0;
//if (i_player.fullscreen)
record_fullscreen = false;
i_player.fullscreen = false;
eh.fireEvent("hide-video", this);
f_hide(i_player);
}
if (i_show === true) {
this.m_players.forEach(function(player) {
if (player != i_player_audio)
f_hide(player);
});
if (!pDevice.isIPhone() && !pDevice.isAndroid() && !pDevice.isIPod()) //TODO: use screen size instead...
f_show(i_player_audio);
}
}
i_player = m_player = i_player_audio;//this.m_audio_player;
m_video = false;
}
//*** NOTIFY
if (i_show === true)
eh.fireEvent("show-after", this);
return i_player;
};
function f_checkPlayer(i_player, i_player_audio, i_player_video, i_media) {
if (null==i_player_audio || (i_media.has_video===true && m_showVideos))
return i_player_video;
else
return i_player_audio;
};
this.check = function(i_media) {
//*** SELECT AUDIO PLAYER
var i_player_audio = that.selectPlayer(i_media, 'audio');
//*** SELECT VIDEO PLAYER
var i_player_video = that.selectPlayer(i_media, 'video');
if (null==i_player_audio && null==i_player_video)
return null;//pConsole.warn('Playlist', "No enabled player...");
//*** SHOW PLAYER
var i_player = f_checkPlayer(that.getPlayer(), i_player_audio, i_player_video, i_media);
//*** GET URL
var i_mrl = f_createURL(i_media.url, server_nossl_port);// + "mode=web);
var i_transcode = false;
var i_mrl_done = false;
var i_mime = null;
if (i_media.mime) i_mime = i_media.mime.toLowerCase();
var i_webvtt =pROSE.getProp(pPlaylistUtil.options.OPTION_WEBVTT);
//pConsole.info(that, "Video Bit Rate: " + i_media.metadata_bitrate_video);
//*** PLAY LOCAL FILE
if (i_media.mrl_local && i_player.canPlayLocalFiles()) {
i_mrl = i_media.mrl_local;
if (that.autoscale===true) {
if (i_media.width && i_media.height && (screen.width<i_media.width || screen.height<i_media.height))
if (i_media.scaled && i_media.scaled.length>1 && i_media.scaled[0].mrl_local)
i_mrl = i_media.scaled[0].mrl_local;
}
i_mrl = f_createURL(i_mrl, server_nossl_port);
i_mrl_done = true;
}
//*** OR TRY TRANSCODING
if (i_mrl_done === false)
return that.m_do_transcode(i_player, i_media);
};
function f_createURL(p_url, p_port) {
if (p_url.indexOf('file:')==0)
return p_url;
if (p_url.indexOf('http:')==0)
return p_url;
if (p_url.indexOf('https:')==0)
return p_url;
//if (pPlaylistUtil.OPTION_DEVICE_HTTPS_VIDEOS)
// return 'https://' + window.location.hostname + ":" + server_ssl_port + p_url;
if (pPlaylistUtil.OPTION_VIDEO_NOHTTPS)
return "http://" + window.location.hostname + ":" + server_nossl_port + p_url;
return p_url;
}
function f_createTranscodeURL(media) {
const i_webvtt = pPlaylistUtil.OPTION_WEBVTT;
return f_createURL(media.url_transcode + ((i_webvtt === true)? "?subtitles=webvtt":""), server_nossl_port);
}
//*** Decides if transcoding is required and return appropriate URL
var IOS_MIMES = [ 'video/mp2t', 'video/quicktime', 'video/mp4', 'video/x-m4v', 'video/3gpp' ];
var WEB_MIMES = [ 'video/mp4', 'video/x-m4v', 'video/webm' ];
this.m_do_transcode = function(i_player, i_media) {
var i_transcode = that.transcode, r = { transcode: i_transcode, info: [], reason: [], player: true }, vbitrate = pPlaylistUtil.OPTION_MAX_VIDEO_BITRATE;
r.info.push("Transcoding: " + i_transcode);
//*** NEVER
if (i_transcode === '0')
return r;
if (null!=i_media.canTranscode && i_media.canTranscode === false) {
r.player = false;
return r;
}
r.info.push("Video Bit Rate: " + i_media.metadata_bitrate_video);
if (i_transcode === 'auto') {
if (i_player.canTranscode()===true) {
//0.9.11
if (pTrackListUtil.countAudioTracks(i_media.tracks)>1) {
r.reason.push("audio tracks: " + pTrackListUtil.countAudioTracks(i_media.tracks) + ">1");
r.url = f_createTranscodeURL(i_media);
return r;
}
if (pTrackListUtil.countExternalSubtitleTracks(i_media.tracks)>0) {
r.reason.push("subtitle tracks: " + pTrackListUtil.countExternalSubtitleTracks(i_media.tracks) + ">0");
r.url = f_createTranscodeURL(i_media);
return r;
}
var t = pTrackListUtil.tracks(i_media);
var i_vcodec = pTrackListUtil.getVideoCodec(t, '');
r.info.push("Video Codec: " + i_vcodec);
var i_acodec = pTrackListUtil.getAudioCodec(t, '');
r.info.push("Audio Codec: " + i_acodec);
var i_mime = (i_media.mime || '').toLowerCase();
r.info.push("Mime: " + i_mime);
if (pDevice.isIOS()) {
if (IOS_MIMES.includes(i_mime))
if (i_media.height && parseInt(i_media.height)<=1080) {
if (i_media.metadata_bitrate_video && i_media.metadata_bitrate_video>0 && i_media.metadata_bitrate_video < vbitrate) {
r.reason.push('mime is device compatible' + (pConsole.debugging()? ' (' + IOS_MIMES.join(', ') + ')':'')+': ' + i_mime);
r.reason.push("video height is " + i_media.height + " (<=1080)");
r.reason.push("bitrate video is " + i_media.metadata_bitrate_video + " (<"+vbitrate+")");
return r;
}
}
if (i_media.url_transcode != undefined) {
r.url = f_createTranscodeURL(i_media);
return r;
}
}
var i_v = pVideoUtil.supports(i_mime + '; codecs="' + i_vcodec + '"'), i_a = pTrackListUtil.countAudioTracks(t)==0 || pAudioUtil.supports(i_mime.replace('video', 'audio') + '; codecs="'+i_acodec+'"');
//r.reason.push('player '+(i_v? 'supports':'does not support')+' ' + i_mime + '; video codec="' + i_vcodec + '"');
//r.reason.push('player '+(i_a? 'supports':'does not support')+' ' + i_mime.replace('video', 'audio') + '; audio codec="' + i_acodec + '"');
if (i_v && i_a) {
if (pLocation.isLocalhost()) {
r.reason.push('player supports ' + i_mime + '; video codec="' + i_vcodec + '"');
r.reason.push('player supports ' + i_mime.replace('video', 'audio') + '; audio codec="' + i_acodec + '"');
r.reason.push("media is on localhost");// ("+window.location.hostname+")");
return r;
}
if (i_media.height && parseInt(i_media.height)<=1080) {
if (i_media.metadata_bitrate_video && i_media.metadata_bitrate_video>0 && i_media.metadata_bitrate_video < vbitrate) {
r.reason.push('player supports ' + i_mime + '; video codec="' + i_vcodec + '"');
r.reason.push('player supports ' + i_mime.replace('video', 'audio') + '; audio codec="' + i_acodec + '"');
r.reason.push("video height is " + i_media.height + " (<=1080)");
r.reason.push("bitrate video is " + i_media.metadata_bitrate_video + " (>0 && <"+vbitrate+")");
return r;
}
}
}
/*else if (WEB_MIMES.includes(i_mime)) {
r.reason.push('mime is device compatible' + (pConsole.debugging()? ' (' + WEB_MIMES.join(', ') + ')':'') + ': ' + i_mime);
if (i_vcodec.indexOf('AVC')<0 && i_vcodec.indexOf('H264')<0) {
r.reason.push('player '+(i_v? 'supports':'does not support')+' ' + i_mime + '; video codec="' + i_vcodec + '"');
r.reason.push('player '+(i_a? 'supports':'does not support')+' ' + i_mime.replace('video', 'audio') + '; audio codec="' + i_acodec + '"');
r.reason.push("video codec does not contain AVC abd H264: " + i_vcodec);
r.url = f_createTranscodeURL(i_media);
return r;
}
if (pLocation.isLocalhost) {
r.reason.push("media is on localhost");
return r;
}
if (i_media.height && parseInt(i_media.height)<=1080) {
if (i_media.metadata_bitrate_video && i_media.metadata_bitrate_video>0 && i_media.metadata_bitrate_video < vbitrate) {
r.reason.push("video height is " + i_media.height + " (<=1080)");
r.reason.push("bitrate video is " + i_media.metadata_bitrate_video + " (>0 && <"+vbitrate+")");
return r;
}
}
}*/
r.reason.push('player '+(i_v? 'supports':'does not support')+' ' + i_mime + '; video codec="' + i_vcodec + '"');
r.reason.push('player '+(i_a? 'supports':'does not support')+' ' + i_mime.replace('video', 'audio') + '; audio codec="' + i_acodec + '"');
if (i_media.url_transcode != undefined) {
r.url = f_createTranscodeURL(i_media);
return r;
}
}
}
// ALWAYS
else if (i_transcode === '1') {
if (i_player.canTranscode()===true)
if (i_media.url_transcode != undefined) {
r.url = f_createTranscodeURL(i_media);
return r;
}
}
return r;
};
this.selectPlayer = function(i_media, type) {
if (i_media.metadata_provider) {
const i_provider = i_media.metadata_provider.toLowerCase(), p = this.m_players.find(function(p) {
if (p.enabled === true && p.type === type && p.providers)
if (p.providers.includes(i_provider))
return true;
});
if (p)
return p;
/*for(var i=0 ; i<this.m_players.length ; i++)
if (this.m_players[i].enabled === true && this.m_players[i].type === type && this.m_players[i].providers)
if (this.m_players[i].providers.indexOf(i_provider)>=0)
return this.m_players[i];*/
}
/*if (i_media.mrl_local) {
var i_local = this.local;
for(var i=0 ; i<this.m_players.length ; i++)
if (this.m_players[i].enabled === true && this.m_players[i].type === type) {
if (i_local === "always" || i_local === "auto" || i_local === "true")
if (this.m_players[i].canPlayLocalFiles() === true)
return this.m_players[i];
}
}*/
/*for(var i=0 ; i<this.m_players.length ; i++)
if (this.m_players[i].enabled === true && this.m_players[i].type === type) {
if (this.transcode === "always" || this.local === "auto" || this.local === "true")
if (this.m_players[i].canPlayLocalFiles() === true)
return this.m_players[i];
}
*/
return this.m_players.find(function(p) {
if (p.enabled === true && p.type === type)
return true;
});
/*
for(var i=0 ; i<this.m_players.length ; i++)
if (this.m_players[i].enabled === true && this.m_players[i].type === type)
return this.m_players[i];
return null;*/
};
this.canResume = function(i_media, p_askResume) {
var i_play_time = null;
// ask to resume...
if (i_media.ms && (p_askResume === true || (p_askResume==null && this.askResume===true))) {
i_play_time = pCookieManager.getCookie(pPlaylistUtil.playTimeCookieName(i_media));
if (i_play_time)
i_play_time = parseInt(i_play_time);
else
i_play_time = i_media.play_time;
}
if (i_play_time && i_play_time > 60000) {
var r = i_play_time - (i_media.start_time || 0); //resume time
if (r > 60000)
return true;
}
};
var m_mrl_options, m_asked = false, m_temp;
this.play = function(n, p_incr, p_askResume, p_user, p_static) {
if (n && n.doc_url)
n = this.medias.findIndex(function(p_media) { return p_media.doc_url == n.doc_url || (p_media.media && p_media.media.doc_url == n.doc_url); });
//console.log('n: ' + n);
try {
n = parseInt(n);
}
catch(exception) {
n = this.index;
}
if (isNaN(n) || n<1 || n>this.medias.length)
n = this.index;
if (null == n)
n = 1;
//*** NO CHANGE...
if (this.index == parseInt(n)) {
this.getPlayer().play();
this.updateMediaControlsPlay(n);
return;
}
play_by_user = p_user;
//*** DISABLE SOME FEATURES
disable_reportTime = true;
//*** SELECT MEDIA
var i_media = this.medias.getValue(parseInt(n));
if (null==i_media)
return;
if (i_media.media) {
if (i_media.media.url && !i_media.media.url.startsWith('/'))
i_media = i_media.media;
}
//*** SELECT AUDIO PLAYER
var i_player_audio = this.selectPlayer(i_media, 'audio');
//*** SELECT VIDEO PLAYER
var i_player_video = this.selectPlayer(i_media, 'video');
if (null==i_player_audio && null==i_player_video)
pConsole.warn(this, "No enabled player...");
//*** MOVE INDEX
this.index = parseInt(n);
//*** SHOW PLAYER
var i_player = f_showPlayer.call(this, this.getPlayer(), i_player_audio, i_player_video, i_media, true);//false);
pConsole.info(this, "Media Player: " + (i_player? i_player.tracePrefix : i_player));
//*** GET URL
var i_mrl = f_createURL(i_media.url, server_nossl_port), i_transcode = false, i_mrl_done = false, i_mime = (i_media.mime || '').toLowerCase(), i_webvtt =pROSE.getProp(pPlaylistUtil.options.OPTION_WEBVTT);
//pConsole.info(this, "Video Bit Rate: " + i_media.metadata_bitrate_video);
//*** PLAY LOCAL FILE
if (i_media.mrl_local && i_player.canPlayLocalFiles()) {
i_mrl = i_media.mrl_local;
if (this.autoscale===true) {
if (i_media.width && i_media.height && (screen.width<i_media.width || screen.height<i_media.height))
if (i_media.scaled && i_media.scaled.length>1 && i_media.scaled[0].mrl_local)
i_mrl = i_media.scaled[0].mrl_local;
}
i_mrl = f_createURL(i_mrl, server_nossl_port);
i_mrl_done = true;
}
//*** OR TRY TRANSCODING
if (i_mrl_done === false) {
var r = this.m_do_transcode(i_player, i_media.media || i_media);
if (r) {
(r.info || []).forEach(function(i) { pConsole.info(that, i) });
(r.reason || []).forEach(function(i) { pConsole.info(that, "Transcode: " + i) });
if (r.url) {
i_transcode = true;
i_mrl = r.url;
i_mrl_done = true;
}
}
}
if (pConsole.debugging())
alert('To Play...\nvideo: ' + m_video + '\nautoscale: ' + this.autoscale + '\ntranscode: ' + this.transcode + '\nurl: ' + i_mrl + '\nurl (decoded): ' + decodeURIComponent(i_mrl));
pConsole.info(this, "Play " + i_mrl + ((i_transcode===true)? " (transcode)":" ") + "...");
if (i_transcode===false && pDevice.isIOS()) {
if (i_media.mime) {
//alert(i_media.mime);
if (null!=i_mime && i_mime.indexOf('video/')==0 && i_mime!='"video/mp2t' && i_mime!='video/quicktime' && i_mime!='video/mp4' && i_mime!='video/x-m4v' && i_mime!='video/3gpp') {
pDocument.stopwait();
location.href = i_mrl;
}
}
}
if (i_transcode === true)
eh.fireEvent("transcode", this);
var i_dialog = { id: 'playlist-resume', options: [] }, i_play_time = null, i_ask_options = this.askOptions;
if (i_ask_options===true && i_media.askOptions)
i_ask_options = i_media.askOptions;
if (i_ask_options===true && (i_media.has_video && i_media.has_video === true) || (i_media.hasVideo && i_media.hasVideo === true)) {
// ask to resume...
if (i_media.ms && (p_askResume === true || (p_askResume==null && this.askResume===true))) {
i_play_time = pCookieManager.getCookie(pPlaylistUtil.playTimeCookieName(i_media));
if (i_play_time)
i_play_time = parseInt(i_play_time);
else
i_play_time = i_media.play_time;
}
if (i_play_time && i_play_time > 60000) {
var r = i_play_time - (i_media.start_time || 0); //resume time
if (r > 60000) {
i_dialog.options.push({ id: "resume", text: m_resume_text_before + pTime.display(r) + m_resume_text_after, value: "resume-true", vdefault: true });
i_dialog.options.push({ id: "restart", text: m_begining_text, value: "resume-false" });
}
}
pPlaylistControls.addDialogLangOptions(i_dialog, i_media, i_transcode, i_webvtt);
}
//0.9.9
if (i_dialog.i_audio_done ==0 && i_dialog.i_subtitles_done == 0 && i_transcode===true)
pHTTPRequest.get(i_mrl);
if (i_dialog.options.length > 0 ) {
//*** auto select audio and substitles
//if (i_audio_done >0 || i_subtitles_done > 0)
// this.autoSelectLangs(i_dialog, i_option_snone, i_media);
if (i_dialog.radio && i_dialog.radio === true)
i_dialog.options.push('ok');
i_dialog.options.push({ id: "cancel", value: "-1" });
i_dialog.fcall = function(p_dialog, value) {
if (value === "-1") {
pDocument.stopwait(); m_vlc.close();
return;
}
var i_options = pPlaylistControls.createLangOptions(p_dialog, value);//'';
var i_resume = p_dialog.radio===true? value.includes('resume-true') : value === "resume-true";
if (p_static===true)
i_options = pURL.addBodyParameter(i_options, 'static', 1);
m_mrl_options = i_options;
var req = { player: m_temp.player, player_audio: m_temp.player_audio,
player_video: m_temp.player_video,
media: m_temp.media, play_time: m_temp.play_time,
mrl: pURL.addQueryParameters(m_temp.mrl, i_options),
resume: i_resume,
transcode: m_temp.transcode,
incr: m_temp.incr };
that.playImpl(req);
};
m_temp = { player: i_player, player_audio: i_player_audio, player_video: i_player_video, media: i_media, play_time: i_play_time, mrl: i_mrl, transcode: i_transcode, incr: p_incr };
m_asked = true;
pDialog.dialogQuestion(i_dialog);
}
else
this.playImpl({ player: i_player, player_audio: i_player_audio, player_video: i_player_video, media: i_media, play_time: i_play_time,
mrl: pURL.addQueryParameters(i_mrl, m_mrl_options), resume: false, transcode: i_transcode, incr: p_incr });
};
this.playImpl = function(r) {//i_player, i_player_audio, i_player_video, i_media, i_play_time, i_mrl, i_resume, i_transcode, p_incr) {
var p = r.player, m = r.media;
try {
m.error = false;
var i_src = {
url: r.mrl,
options: [],
title: (m.title)? m.title + ((r.transcode===true)? ' (transcoded)':'') : null ,
hls: r.transcode && pLocation.param(r.mrl, 'type', 'hls')=='hls'
};
if (this.medias.length>1)
if (i_src.title && !i_src.title.match(/[0-9]+\/[0-9]+ - .+/g))
i_src.title = m.position+'/'+this.medias.length+' - ' + i_src.title;
this.title = i_src.title;
//*** CHANGE DOC TITLE
if (pPlaylistUtil.OPTION_CHANGE_DOCTITLE) {
that.doc_title_old = that.doc_title_old || document.title; // save title only first time... TODO: if title changes after renaming playlist, this will fail...
document.title = doc_title_new = 'Playing: ' + i_src.title;
}
else {
that.doc_title_old = null;
doc_title_new = null;
}
if (r.resume) {
i_src.options[i_src.options.length] = "resume-time=" + r.play_time;
i_src.resume_time = r.play_time;
}
if (m.start_time && m.start_time > 0) {
i_src.options[i_src.options.length] = "start-time=" + m.start_time;
i_src.start_time = m.start_time;
}
if (m.stop_time && m.stop_time > 0) {
i_src.options[i_src.options.length] = "stop-time=" + m.stop_time;
i_src.stop_time = m.stop_time;
}
p.source = i_src;
//setTimeout(function() {
if (p.setNextSource && this.index>0) {
if (this.medias.currentMediaPlayingPosition()!=this.medias.length) {
var n = this.medias.getValue(this.medias.nextMediaIndex());
if (n)
p.setNextSource(i_src, { url: f_createURL(n.url, server_nossl_port) });
}
}
eh.fireEvent("title", this);
//doRewind(p);
//p.preload = "auto";
//*** ENABLE SOME FEATURES
disable_reportTime = false;
that.medias.playCount = that.medias.playCount + 1;
last_time = 0;
p.load();
p.play();
if (pPlaylistUtil.OPTION_FULLSCREEN) {
record_fullscreen = false;
p.fullscreen = true;
}
for(var i=1;i<this.length+1;i++) {
if (i!=this.index)
this.updateMediaControlsPlayUnselected(i);
//else
// updateMediaControlsPlay(i);
}
pPlaylistControls.updateChapters(m, p);
pPlaylistControls.updateTracks(m, p);
if (this.autoscroll===true)
if (null!=m.controls && null!=m.controls.scrollTo)
pDocument.scrollTo(m.controls.scrollTo);//'tr.'+this.index);
// in case play event is not fired...
this.updateMediaControlsPlay(this.index);
//eh.fireEvent("play", i_playlist);
//*** CALL PLAY INCR URL
if (r.incr === true || this.callIncrPlayURL === true)
if (m.url_incr)
pHTTPRequest.post(m.url_incr);
}
catch (er) {
console.log(er);
alert("Failed: " + er + " " + er.stack);
}
};
this.updateMediaControlsError = function(p_media_index) {
var m = that.medias.getValue(p_media_index);
if (m)
if (m.controls) {
pPlaylistUtil.highlightError(m.controls.scrollTo);
pPlaylistUtil.highlightError(m.controls.highlight);
}
};
// Handles error events from player
this.f_error = function(e) {
//console.log(e);
var s = e.source || this;
pConsole.info(that, pConsole.prefix(s, 'player') + " event: error...");
//"this" is media player...
if (!pString.v(this.source))
return;
//if (!pDocument.isShown(this))
// return;
var p = pPlaylistManager.getValue(this.id);
if (p) {
if (p.m_player == this) {
p.updateMediaControlsError(p.index);
eh.fireEvent("error", p);
var m = p.medias.current;
m.error = true;
if (pPlaylistUtil.OPTION_ONERROR_NEXT && p.medias.length>1)// && !play_by_user)
p.next(p.medias.error!=true); //loop=false
else if (e.msg && (e.src || this.source)) {
pHTTPRequest.head({
url: e.src || this.source,
onerror: function() { pApplicationUI.errorDialog({ text: 'Failed to load media: network unavailable...' }); },
f404: [ function() { pApplicationUI.errorDialog({ text: 'Failed to load media: media unavailable...' }) } ]
});
}
else if (e.msg) {
pApplicationUI.errorDialog({ text: e.msg });//, icon: { src: '/resources/html/images/32x32/picture_error.png' } });
}
}
}
};
this.togglePause = function() {
var p = that.getPlayer();
if (p)
p.togglePause();
};
this.pause = function() {
var p = that.getPlayer();
if (p)
p.pause();
};
// Handler pause events from player
this.f_pause = function() {
that.updateMediaControlsPause(that.index);
eh.fireEvent("pause", that);
m_paused = true;
//*** CHANGE DOC TITLE
if (doc_title_new && document.title == doc_title_new)
document.title = doc_title_new + ' (Paused)';
},
this.updateMediaControlsPause = function(p_media_index) {
var m = that.medias.getValue(p_media_index);
if (m) {
if (m.controls) {
pDocument.show(m.controls.play);
pDocument.hide(m.controls.play_unselected);
pDocument.hide(m.controls.pause);
}
if (that.controls) {
pDocument.enable(that.controls.play);
pDocument.disable(that.controls.pause);
}
}
};
this.f_play = function() {
that.updateMediaControlsPlay(that.index);
eh.fireEvent("play", that);
//*** CHANGE DOC TITLE
if (doc_title_new)
document.title = doc_title_new;
};
this.updateMediaControlsPlay = function(p_media_index) {
var m = that.medias.getValue(p_media_index);
if (m) {
if (m.controls) {
pDocument.hide(m.controls.play);
pDocument.hide(m.controls.play_unselected);
pDocument.show(m.controls.pause);
pPlaylistUtil.highlight(m.controls.scrollTo, true);
pPlaylistUtil.highlight(m.controls.highlight, true);
}
if (that.controls) {
pDocument.enable(that.controls.previous)
pDocument.enable(that.controls.next, that.length > 1 || eh.countListeners('unhandled-next')>0)
pDocument.disable(that.controls.play);
pDocument.enable(that.controls.pause);
var p = that.getPlayer();
if (that.controls.capture)
that.controls.capture.forEach(function(c) {
pDocument.enable(c, p.capture);
});
}
}
};
this.updateMediaControlsPlayUnselected = function(p_media_index) {
var m = that.medias.getValue(p_media_index);
if (m)
if (m.controls) {
pDocument.hide(m.controls.play);
pDocument.show(m.controls.play_unselected);
pDocument.hide(m.controls.pause);
pPlaylistUtil.highlight(m.controls.scrollTo, false);
pPlaylistUtil.highlight(m.controls.highlight, false);
}
};
this.captureArtwork = function() {
var t = that.currentTime, m = that.medias.current;
if (m && m.doc_url)
pMediaLibrary.setArtworkImage(m.doc_url, { ms: t * 1000 }, null, true);
};
this.nextChapter = function() {
var p = that.getPlayer(), m = that.medias.current;
if (m) {
const c = m.chapters;
if (c && c.length>0) {
//console.log('searching chapter...');
for(var i=0 ; i<c.length-1; i++) {
var i_time = p.currentTime * 1000;
//console.log('time: ' + i_time);
//console.log('chapter: ' + i + ' time: ' + i_time + ' - ' + i_chapters[i].startms + ' ' + i_chapters[i+1].startms);
if (c[i].startms < i_time && i_time < c[i+1].startms) {
//console.log('ok - chapter: ' + i + ' time: ' + i_time + ' - ' + i_chapters[i].startms + ' ' + i_chapters[i+1].startms);
this.currentTime = c[i+1].startms / 1000;
return true;
}
}
}
}
return false;
};
this.next = function(loop) {
// next chapter
if (that.nextChapter())
return;
if (that.index>0) {
if (that.medias.currentMediaPlayingPosition() == that.medias.length) {
if ((null==loop || loop!=false) && that.loop) {
if (that.medias.error())
return;
that.play(that.medias.firstMediaIndex());
}
else if (that.length == 1 && !loop)
eh.fireEvent("unhandled-next", that.getPlayer());
}
else
that.play(that.medias.nextMediaIndex());
}
else
that.play(that.medias.firstMediaIndex());
};
this.previousChapter = function() {
var p = that.getPlayer(), m = that.medias.current;
if (m) {
const c = m.chapters;
if (c && c.length>0) {
//console.log('searching chapter...');
for(var i=0 ; i<c.length-1; i++) {
var i_time = p.currentTime * 1000;
//console.log('time: ' + i_time);
//console.log('chapter: ' + i + ' time: ' + i_time + ' - ' + i_chapters[i].startms + ' ' + i_chapters[i+1].startms);
if (c[i].startms < i_time && i_time < c[i+1].startms) {
//console.log('ok - chapter: ' + i + ' time: ' + i_time + ' - ' + i_chapters[i].startms + ' ' + i_chapters[i+1].startms);
if (i_time > c[i].startms + 5000)
that.currentTime = c[i].startms / 1000;
else if (i>0)
that.currentTime = c[i-1].startms / 1000;
return true;
}
}
}
}
return false;
};
this.previous = function() {
// previous chapter
if (that.previousChapter())
return;
var p = that.getPlayer(), m = that.medias.current;
if (p.currentTime * 1000 < Math.max(0, m.start_time || 0)+5000) {
if (this.medias.currentMediaPlayingPosition()==1) {
if (that.loop === true)
that.play(that.medias.lastMediaIndex());
else if (that.length == 1 && !that.loop)
eh.fireEvent("unhandled-previous", that.getPlayer());
}
else
that.play(that.medias.previousMediaIndex());
}
else {
that.doRewind(p);
p.play();
}
};
this.doRewind = function(i_player) {
var m = that.medias.current;
if (m) {
if (m.start_time >=0) {
//alert("1: " + i_media.start_time / 1000 + " - " + i_player.currentTime);
//i_player.preload = "auto";
//i_player.load();
i_player.currentTime = m.start_time / 1000;
//alert("2: " + i_media.start_time / 1000 + " - " + i_player.currentTime);
}
else
i_player.currentTime = 0;
}
};
this.m_canplay = function() {
pConsole.info(that, "player event: can play...");
if (pPlaylistUtil.OPTION_CANPLAY_PLAY)
that.play(); //TODO: ...
pPlaylistControls.updateTracks(that.medias.current, that.getPlayer());
};
this.reset = function() {
this.pause();
var i_player = this.getPlayer();
if (i_player)
i_player.source = null;
for(var i=1 ; i<this.length+1 ; i++) {
var i_media = this.medias.getValue(i);
if (null!=i_media.controls) {
pDocument.hide(i_media.controls.play);
pDocument.show(i_media.controls.play_unselected, 'inline');
pDocument.hide(i_media.controls.pause);
pPlaylistUtil.highlight(i_media.controls.scrollTo, false);
pPlaylistUtil.highlight(i_media.controls.highlight, false);
}
}
if (this.controls) {
pDocument.disable(this.controls.previous);
pDocument.disable(this.controls.next);
pDocument.disable(this.controls.play);
pDocument.disable(this.controls.pause);
if (this.controls.capture)
for(var i=0 ; i<this.controls.capture.length ; i++)
pDocument.disable(this.controls.capture[i]);
}
this.m_player = null;
this.index = null;
if (this.autoclear)
this.medias.clear();
m_asked = false;
m_mrl_options = '';
};
this.close = function() {
try {
//*** NOTIFY
eh.fireEvent("close-before", that);
//*** REPORT TIME TO SERVER
f_reportTime();
f_reportEnded();
that.reset();
//*** NOTIFY
eh.fireEvent("close-after", that);
}
catch (exception) {
alert(exception + ": " + exception.stack);
}
};
this.getMedia = function() {
return that.medias.current;
};
// "local" property
//this.m_local = pCookieManager.getValue("device-local");
this.m_local_user = false;
Object.defineProperty(this, "local", { get: function() { return (this.m_local_user === true)? this.m_local : pROSE.getProp(pPlaylistUtil.options.OPTION_DEVICE_LOCAL); }, set: function(value) { if (typeof value == "string") { this.m_local = value.toLowerCase(); this.m_local_user = true; } } });
// "autoscale" property
this.m_autoscale = pROSE.getProp(pPlaylistUtil.options.OPTION_DEVICE_SCALE_VIDEOS);
this.m_autoscale_user = false;
Object.defineProperty(this, "autoscale", { get: function() { return this.m_autoscale; }, set: function(value) { this.m_autoscale = value; this.m_autoscale_user = true; } });
// "autoscroll" property
this.m_autoscroll = true;
Object.defineProperty(this, "autoscroll", { get: function() { return this.m_autoscroll; }, set: function(value) { this.m_autoscroll = value; } });
// "autoclear" property
this.m_autoclear = true;
Object.defineProperty(this, "autoclear", { get: function() { return this.m_autoclear; }, set: function(value) { this.m_autoclear = value; } });
// "transcode" property
this.m_transcode_user = false;
Object.defineProperty(this, "transcode", { get: function() { return (this.m_transcode_user === true)? this.m_transcode : pPlaylistUtil.OPTION_DEVICE_TRANSCODE; }, set: function(value) { this.m_transcode = value; this.m_transcode_user = true; } });
// "loopTrack" property
this.m_loopTrack = false;
Object.defineProperty(this, "loopTrack", { get: function() { return this.m_loopTrack; }, set: function(value) { this.m_loopTrack = value; } });
// "loop" property
var m_loop = true;
Object.defineProperty(this, "loop", { get: function() { return m_loop; }, set: function(v) { m_loop = v; } });
// "showVideos" property
var m_showVideos = false;
Object.defineProperty(this, "showVideos", { get: function() { return m_showVideos; }, set: function(v) { if (typeof v == "boolean") m_showVideos = v; } });
// "askOptions" property
var m_askOptions = true;
Object.defineProperty(this, "askOptions", { get: function() { return m_askOptions; }, set: function(v) { if (typeof v == "boolean") m_askOptions = v; } });
// "askResume" property
Object.defineProperty(this, "askResume", { get: function() { return this.shuffle === false && this.medias.playCount===0; /*m_true*/ }});
// "paused" property
Object.defineProperty(this, "paused", { get: function() { return m_paused; }});
// "callIncrPlayURL" property
var m_callIncrPlayURL = false;
Object.defineProperty(this, "callIncrPlayURL", { get: function() { return m_callIncrPlayURL }, set: function(v) { if (typeof v == "boolean") m_callIncrPlayURL = v; } });
// Opens an URL and play it.
this.open = function(url, p_askResume, p_title, p_start, p_static) {
//*** NOTIFY
eh.fireEvent("open-before", that);
if (typeof url == "string") {
var i_url = url + "&format=json"/*&urlformat=simple"*/;
pConsole.info(that, 'Open url: ' + i_url);
//alert(i_url);
pHTTPRequest.get(i_url, function(i_request) {
if (pROSE.handleHTTPResponse(i_request)===false)
return;
var i_obj = pJSON.parse(i_request.responseText);
that.reset();
i_obj.forEach(function(i_media) {
if (p_title)
i_media.title = p_title;
that.addMedia(i_media);
});
that.play(p_start || 1, null, p_askResume, null, p_static);
}, false, that);
}
else {
that.reset();
url.forEach(function(u) { that.addMedia(u); });
that.play(p_start || 1, null, p_askResume, null, p_static);
}
//*** NOTIFY
eh.fireEvent("open-after", that);
};
this.m_players = [];
//*** REGISTER PLAYERS
function f_registerPlayer(p) {
/*abort Fires when the loading of an audio/video is aborted
canplay Fires when the browser can start playing the audio/video
canplaythrough Fires when the browser can play through the audio/video without stopping for buffering
durationchange Fires when the duration of the audio/video is changed
emptied Fires when the current playlist is empty
ended Fires when the current playlist is ended
error Fires when an error occurred during the loading of an audio/video
loadeddata Fires when the browser has loaded the current frame of the audio/video
loadedmetadata Fires when the browser has loaded meta data for the audio/video
loadstart Fires when the browser starts looking for the audio/video
pause Fires when the audio/video has been paused
play Fires when the audio/video has been started or is no longer paused
playing Fires when the audio/video is playing after having been paused or stopped for buffering
progress Fires when the browser is downloading the audio/video
ratechange Fires when the playing speed of the audio/video is changed
seeked Fires when the user is finished moving/skipping to a new position in the audio/video
seeking Fires when the user starts moving/skipping to a new position in the audio/video
stalled Fires when the browser is trying to get media data, but data is not available
suspend Fires when the browser is intentionally not getting media data
timeupdate Fires when the current playback position has changed
volumechange Fires when the volume has been changed
waiting Fires when the video stops because it needs to buffer the next frame
*/
var f = function(e){ pConsole.info(that, 'player event: '+e.id+'...'); };
p.addEventListener("abort", f);
p.addEventListener("canplay", that.m_canplay);
p.addEventListener("canplaythrough", that.m_canplay);//function(){ pConsole.info(pPlaylistManager.getValue(this.id), "player event: canPlayThrough..."); });
p.addEventListener("durationchange", f);
p.addEventListener("emptied", f);
p.addEventListener("ended", that.f_ended, null);
p.addEventListener("error", that.f_error, null);
p.addEventListener("loadeddata", that.m_canplay, null);//function(){ pConsole.info(pPlaylistManager.getValue(this.id), "player event: loaded data..."); });
p.addEventListener("loadedmetadata", f);
p.addEventListener("loadstart", f);
p.addEventListener("pause", that.f_pause, null);
p.addEventListener("play", that.f_play, null);
p.addEventListener("playing", f);
//p.addEventListener("progress", f);
p.addEventListener("ratechange", f);
p.addEventListener("seeked", f);
p.addEventListener("seeking", f);
p.addEventListener("stalled", f);
p.addEventListener("suspend", f);
p.addEventListener("timeupdate", f_timed);
p.addEventListener("volumechange", f);
p.addEventListener("waiting", f);
that.m_players.push(p);
//*** Register playlist with player ID so it can be retrieved in event functions
//*** where "this" is the player and not the playlist
pPlaylistManager.add(p.id, that); //???
};
p_players.filter(pObject.isNotNull).forEach(function(p) {
if (typeof p == "string") {
if (p = pElement.x(p))
f_registerPlayer(new pMediaPlayer(p));
}
else
f_registerPlayer(p);
});
// "fullscreen" property
Object.defineProperty(this, "fullscreen", { get: function() {
return (that.getPlayer() || {}).fullscreen;
}, set: function(s) {
record_fullscreen = false;
(that.getPlayer() || {}).fullscreen = s;
if (!that.getPlayer()) {
if (s === true)
pDocument.fullScreen('div-vlc-main');
else
pDocument.exitFullScreen();
}
/*if (typeof s == "boolean") {
var p = this.getPlayer();
if (p)
p.fullscreen = s;
}*/
}});
this.f_chapters_menu = function() {
var m = that.medias.current, c = (m || {}).chapters || [], o = pPlaylistUtil.OPTION_CHAPTERS;
if (o=='1' || (o=='auto' && c.length>1))
pApplicationMenu.menu('chapters',
c.length<1?
[{ id:'none', text: pDocument.getStyleValue('.dq-chapters-none') }]
:
c.map(function(c, i) {
//TODO: support nested chapters (hidden, enabled...)
if (null==c.enabled || c.enabled === true)
if (!c.hidden) {
var n = c.name, r = pPlaylistControls.regex_names.find(function(r) { return r.regex.test(n) });
return { text: pString.encodeHTML(r? r.transform(n, i) : n), fcall: function() { pPlaylistControls.seek(m_vlc, this.startms); }.bind(c) };
}
})
);
};
this.f_audio_menu = function() {
var p = that.getPlayer(), m = that.medias.current, a = []/*(m || {}).audioTracks || []*/, o = pPlaylistUtil.OPTION_AUDIO_TRACKS;
//console.log(m.audioTracks);
if (p && p.audioTracks && p.audioTracks.length>0) {
for(var i=0 ; i<p.audioTracks.length ; i++)
a[a.length] = p.audioTracks[i];
}
if (o=='1' || (o=='auto' && a.length>1))
pApplicationMenu.menu('audio',
a.length<1?
[{ id: 'none', text: pDocument.getStyleValue('.dq-audio-none') }]
:
a.map(function(a, i) {
return {
id: ''+i,
text: pString.encodeHTML(pTrackListUtil.displayAudioTrack(a, i, m)),
fcall: function() {
for(var i=0 ; i<p.audioTracks.length ; i++)
p.audioTracks[i].enabled = i == this.i;
}.bind({ i: i }),
selected: p.audioTracks[i].enabled
};
})
);
};
//*** REPORT TIME BEFORE PAGE IS UNLOADED
pDocument.addOnPageClose(function(e) {
f_reportTime();
});
};
/******************************************************************************/
/*** Registry of all playlists ***/
/******************************************************************************/
const pPlaylistManager = new (function() {
var that = this, m_playlists = new pMap();
this.tracePrefix = 'PlaylistManager';
this.create = function(p_id, p_players, p_controls) {
var p = new pPlaylistInstance(p_id, p_players, p_controls);
that.add(null, p);
//pause after playlists in the same page
p.addEventListener("play", function() {
that.play(p.id);
}, null);
return p;
};
this.add = function(id, p_playlist) {
m_playlists.put(id || p_playlist.id, p_playlist);
};
this.getValue = function(p_id) {
//return this.playlists.getValue(p_id, null);
var p = m_playlists.getValue(p_id);
if (!p)
alert(pConsole.error(that, 'Cannot find playlist: ' + p_id));
return p;
};
this.play = function(p_id) { // pause all playlists or players except the one with the given id
m_playlists.values().forEach(function(p) {
if (p.id != p_id)
p.pause();
});
};
this.start = function() {
return null!=m_playlists.values().find(function(p) {
if (p.medias.length>0) {
if (p.medias.playCount === 0)
p.play(1, true);
else
p.togglePause();
return true;
}
});
};
//*** REGISTER KEYS
pDocumenti.addOnKeyDown(function(e, k) {
if (e.altKey || e.ctrlKey || e.shiftKey)
return;
pConsole.debug(that, 'KeyCode: ' + k);
if (k == 32)
return that.start();
if (k == 40) //DOWN
return null!=m_playlists.values().find(function(p) {
if (p.medias.length>0) {
if (p.medias.playCount === 0)
p.play(1, true);
else
p.next();
return true;
}
});
if (k == 38) //UP
return null!=m_playlists.values().find(function(p) {
if (p.medias.length>0) {
if (p.medias.playCount === 0)
p.play(1, true);
else
p.previous();
return true;
}
});
if (k >= 97 && k <= 105) //1 to 9
return null!=m_playlists.values().find(function(p) {
if (p.medias.length>0) {
p.play(k - 96, true);
return true;
}
});
});
});
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
var pPlaylist = {
sortTableString: function(p_playlist_table_id, title){
pTable.sortString(p_playlist_table_id, columnIndex(p_playlist_table_id, title, 0));
//sortTableString(p_playlist_table_id, columnIndex(p_playlist_table_id, title, 0));
},
sortTableTitle: function(p_playlist_table_id, title){
pTable.sortTitle(p_playlist_table_id, columnIndex(p_playlist_table_id, title, 0));
//sortTableTitle(p_playlist_table_id, columnIndex(p_playlist_table_id, title, 0));
},
sortTableInt: function(p_playlist_table_id, title){
pTable.sortInt(p_playlist_table_id, columnIndex(p_playlist_table_id, title, 0));
//sortTableInt(p_playlist_table_id, columnIndex(p_playlist_table_id, title, 0));
},
sortTableDuration: function(p_playlist_table_id, title){
pTable.sortDuration(p_playlist_table_id, columnIndex(p_playlist_table_id, title, 0));
//sortTableDuration(p_playlist_table_id, columnIndex(p_playlist_table_id, title, 0));
}
};
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
const pPlaylistControls = new (function() {
var that = this;
const m_regex_names = Object.freeze([ { regex: /[a-z][a-z]:Chapter [0-9]+/i, transform: function(i_name) { return 'Chapter ' + i_name.substring(11); } },
{ regex: /Chapter [0-9]+/i, transform: function(i_name) { return 'Chapter ' + i_name.substring(8); } },
{ regex: /[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]/, transform: function(i_name, i) { return 'Chapter ' + (i+1) } }
]);
this.tracePrefix = 'PlaylistControls';
// "regex_names" property
Object.defineProperty(this, "regex_names", { get: function() { return m_regex_names; }});
this.updateChapters = function(m, p) {
pConsole.info(that, "Update Chapters...");
var o = pPlaylistUtil.OPTION_CHAPTERS;
if (o == '1' || (o == 'auto' && m.chapters && m.chapters.length>1))
pDocument.show('v0-chapters', 'auto');
else
pDocument.hide('v0-chapters');
pDocument.onResize();
};
this.updateTracks = function(m, p) {
pConsole.info(that, "Update Audio Tracks...");
var o = pPlaylistUtil.OPTION_AUDIO_TRACKS;
if (o=='1' || (o == 'auto' && pTrackListUtil.countAudioTracks(m.tracks)>1 && p.audioTracks && p.audioTracks.length>1))
pDocument.show('v0-audio', 'auto');
else
pDocument.hide('v0-audio');
pDocument.onResize();
};
this.seek = function(p, t) {
p.currentTime = t / 1000;
pConsole.info(that, "Seek to: " + p.currentTime);
};
this.langOptionText = function(n, l) {
//var nn = pLang.nativex.getValue(l);
//if (l && n.indexOf(nn)<0)
// return n + ' ('+nn+')';
return n;
};
this.addDialogLangOptions = function(i_dialog, i_media, i_transcode, i_webvtt) {
var i_tracks = i_media.tracks, i_langs = pApplicationUI.OPTION_PREFERRED_LANGS, sc = pTrackListUtil.countSubtitleTracks(i_tracks, true);
i_dialog.i_audio_done = 0;
if (i_transcode===true && i_webvtt===false && i_tracks && i_dialog.i_audio_done === 0) {
var ac = pTrackListUtil.countAudioTracks(i_tracks);
if (sc>0 || ac>1) {
i_dialog.radio = true;
i_dialog.options.push(m_choose_lang_text);
var ll = [];
i_tracks.forEach(function(t) {
if (t.type == "a") {
var n = pTrackListUtil.longLangName(t);
if (ll.includes(n)) n = pTrackListUtil.longName(t);
ll[ll.length] = n;
i_dialog.options.push({
audio: true,
lang: t.metadata_lang,
id: "langid-"+t.id, text: '<span class="lang">'+pPlaylistControls.langOptionText(n, t.metadata_lang)+'</span>', value: "langid-"+t.id, disabled: ac < 2, selected: ac < 2 });
i_dialog.i_audio_done++;
}
});
}
}
/*if (i_transcode===true && i_webvtt===false && i_media.metadata_lang && i_audio_done === 0) {
var i_langs = i_media.metadata_lang.split("|");
if (i_langs.length>1) {
//i_dialog.radio = true;
i_dialog.options[i_dialog.options.length] = { sep:true, text: "Language:" };
for(var i=0 ; i<1 ; i++)
i_dialog.options[i_dialog.options.length] = { id: "lang-"+i_langs[i], text: '<span class="lang">'+i_langs[i]+'</span>', value: "lang-"+i_langs[i],
m_enabled: false, selected: true };
i_audio_done++;
}
}*/
i_dialog.i_subtitles_done = 0;
var i_option_snone = null;
if (i_transcode===true && i_webvtt===false && i_tracks && i_dialog.i_subtitles_done === 0) {
if (sc>0) {
i_dialog.radio = true;
i_dialog.options.push(m_choose_subtitles_text);
var ll = [];
i_tracks.forEach(function(t) {
if (t.type == "s") {
var n = pTrackListUtil.longLangName(t);
if (ll.includes(n)) n = pTrackListUtil.longName(t);
ll[ll.length] = n;
i_dialog.options.push({
subtitles: true,
lang: t.metadata_lang,
id: "slangid-"+t.id, text: '<span class="lang">'+pPlaylistControls.langOptionText(n, t.metadata_lang)+'</span>', value: "slangid-"+t.id });
i_dialog.i_subtitles_done++;
}
});
i_option_snone = { id: "slang-none", text: '<span class="lang">'+m_none_text+'</span>', value: "slang-none", selected: true };
i_dialog.options.push(i_option_snone);
}
}
//*** auto select audio and substitles
if (i_dialog.i_audio_done >0 || i_dialog.i_subtitles_done > 0)
that.autoSelectLangs(i_dialog, i_option_snone, i_media);
};
this.createLangOptions = function(p_dialog, value) {
var o = '';
//var i_resume = (p_dialog.radio && p_dialog.radio===true)? value.indexOf('resume') >= 0 : value === "resume-true";
if (p_dialog.radio===true) {
value.forEach(function(v) {
if (v.indexOf('lang-')==0)
o = pURL.addBodyParameter(o, "lang", v.substring('lang-'.length));
if (v.indexOf('langid-')==0)
o = pURL.addBodyParameter(o, "lang-trackID", v.substring('langid-'.length));
if (v.indexOf('slang-')==0)
o = pURL.addBodyParameter(o, "subtitle-lang", v.substring('slang-'.length));
if (v.indexOf('slangid-')==0)
o = pURL.addBodyParameter(o, "subtitle-trackID", v.substring('slangid-'.length));
});
/*for(var i=0 ; i<value.length ; i++) {
if (value[i].indexOf('lang-')==0)
i_options = pURL.addBodyParameter(i_options, "lang", value[i].substring('lang-'.length));
if (value[i].indexOf('langid-')==0)
i_options = pURL.addBodyParameter(i_options, "lang-trackID", value[i].substring('langid-'.length));
if (value[i].indexOf('slang-')==0)
i_options = pURL.addBodyParameter(i_options, "subtitle-lang", value[i].substring('slang-'.length));
if (value[i].indexOf('slangid-')==0)
i_options = pURL.addBodyParameter(i_options, "subtitle-trackID", value[i].substring('slangid-'.length));
}*/
}
return o;
};
this.autoSelectLangs = function(i_dialog, i_option_snone, i_media) {
var i_langs = pApplicationUI.OPTION_PREFERRED_LANGS, o = i_dialog.options.filter(function(o) { return o.audio; });
//*** auto select audio and subtitles
var i_lang_ok = false;
//*** select first audio from media country
if (pPlaylistUtil.OPTION_PREFER_VO === true) {
var i_lang_country = (i_media.country)? pLang.getLanguageByCountry(i_media.country) : null;
if (i_lang_country)
i_dialog.options.find(function(op) {
if (op.audio === true) {
if (op.lang === i_lang_country) {
op.selected = true;
i_lang_ok = true;
return true;
}
}
});
/*
for(var i=0 ; i<i_dialog.options.length && i_lang_ok === false ; i++) {
var i_option = i_dialog.options[i];
if (i_option.audio === true) {
if (i_option.lang === i_lang_country) {
i_option.selected = true;
i_lang_ok = true;
}
}
}*/
}
//*** select first audio from preferred lang
o.forEach(function(o) {
if (!i_lang_ok)
i_langs.forEach(function(l) {
if (pLang.getISOName(o.lang)==l)
o.selected = i_lang_ok = true;
});
});
/*for(var i=0 ; i<i_dialog.options.length && i_lang_ok === false ; i++) {
var i_option = i_dialog.options[i];
if (i_option.audio === true) {
for(var j=0 ; j<i_langs.length && i_lang_ok === false ; j++)
if (i_option.lang === i_langs[j]) {
i_option.selected = true;
i_lang_ok = true;
}
}
}*/
//*** select first audio
if (!i_lang_ok && o.length>0)
o[0].selected = true;
/*i_dialog.options.find(function(op) {
if (op.audio === true) {
op.selected = true;
return true;
}
});*/
/*for(var i=0 ; i<i_dialog.options.length ; i++) {
var i_option = i_dialog.options[i];
if (i_option.audio === true) {
i_option.selected = true;
break;
}
}*/
//*** check if audio if preferred lang
i_lang_ok = false;
o.forEach(function(o) {
if (!i_lang_ok)
i_langs.forEach(function(l) {
if (pLang.getISOName(o.lang)==l && o.selected)
i_lang_ok = true;
});
});
/*for(var i=0 ; i<i_dialog.options.length && i_lang_ok != true ; i++) {
var i_option = i_dialog.options[i];
if (i_option.audio === true)
for(var j=0 ; j<i_langs.length ; j++)
if (i_option.lang === i_langs[j] && i_option.selected === true)
i_lang_ok = true;
}*/
//*** if not
if (i_lang_ok != true) {
var done = false, o = i_dialog.options.filter(function(o) { return o.subtitles });
//*** unselect all
o.forEach(function(o) { o.selected = false; });
if (i_option_snone)
i_option_snone.selected = false;
//*** select one subtitle from preferred langs
o.forEach(function(o) {
if (!done) {
var iso = pLang.getISOName(o.lang);
i_langs.forEach(function(l) {
if (iso == l)
o.selected = done = true;
});
}
});
if (!done && i_option_snone)
i_option_snone.selected = true;
//*** unselect all
/*i_dialog.options.forEach(function(op) {
if (op.subtitles === true)
op.selected = false;
});
if (i_option_snone)
i_option_snone.selected = false;
//*** select one subtitle from preferred langs
for(var i=0 ; i<i_dialog.options.length && i_subtitles_ok === false ; i++) {
var i_option = i_dialog.options[i];
if (i_option.subtitles === true)
for(var j=0 ; j<i_langs.length && i_subtitles_ok === false ; j++)
if (i_option.lang === i_langs[j]) {
i_option.selected = true;
i_subtitles_ok = true;
}
}
if (i_subtitles_ok != true)
if (i_option_snone)
i_option_snone.selected = true;*/
}
};
});
/******************************************************************************/
/*** DETECT FULLSCREEN CHANGES on CHROME/Webkit *****************************/
/******************************************************************************/
var f = function(e) {
if (record_fullscreen != false)
pPlaylistUtil.OPTION_FULLSCREEN = document.webkitFullscreenElement!=null;
else
record_fullscreen = true;
};
document.addEventListener('fullscreenchange', f);
document.addEventListener('webkitfullscreenchange', f);
document.addEventListener('mozfullscreenchange', f);
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
/*
const u_pause = '<i class="fas fa-pause"></i>';//'\u23F8';
const u_play = '<i class="fas fa-play"></i>';//'\u25B6';
const u_fullscreen = '<i class="fas fa-expand"></i>';//'\u25F3';
const u_exit_fullscreen = '<i class="fas fa-compress"></i>';
const u_muted = '<i class="fas fa-volume-off"></i>';//'\uD83D\uDD07';
const u_unmuted = '<i class="fas fa-volume-up"></i>';//'\uD83D\uDD0A';*/
var pVideoControls_img_loaded = false;
function pVideoControls(x, c) {
var that = this, display_remaining_time = false, imgs = {}, video = x;
function seekable() {
var s = video.seekable;
return s && s.length>0 && isFinite(s.end(0));
}
c = c || {};
// Buttons
var playButton = pElement.x(c.play || "play-pause"); pElement.setInnerHTML(playButton, '');
var muteButton = pElement.x(c.mute || "mute"); pElement.setInnerHTML(muteButton, '');
var fullScreenButton = pElement.x(c.fullscreen || "full-screen"); pElement.setInnerHTML(fullScreenButton, '');
// Sliders
var seekBar = pElement.x(c.seek || "seek-bar");
var volumeBar = pElement.x(c.volume || "volume-bar");
var t1 = pElement.x(c.time1 || 'time1');
this.start_time = 0;
this.stop_time = 0;
this.ms = c.ms;
//*** PRELOAD ICONS
if (!pVideoControls_img_loaded) {
pVideoControls_img_loaded = true;
if (pDevice.isMobile()) {
const aa = [ "pause", "mute", "unmute", "exitfullscreen", "play", "fullscreen", "next", "previous", "loop-track", "loop-playlist", "show-video", "shuffled" ];
aa.forEach(function(a) {
var u = pDocument.getStyleValue("btn-player-button-"+a, "background-image");
if (u) {
pHTTPRequest.get(u);
//imgs[a] = new Image();
//imgs[a].src = u;
//pConsole.info(that, "Pre-loading icon for " + a + ': ' + imgs[a].src + "...");
}
});
aa.forEach(function(a) {
var u = pDocument.getStyleValue("btn-player-button-"+a+'.disabled', "background-image");
if (u) {
pHTTPRequest.get(u);
//imgs[a+'d'] = new Image();
//imgs[a+'d'].src = u;
//pConsole.info(that, "Pre-loading icon for " + a + ': ' + imgs[a+'d'].src + "...");
}
});
}
}
//*** PLAY
var timer_interval;
if (playButton) {
var f_video_play = function() {
if (video.paused == true)
video.play();
else
video.pause();
};
playButton.addEventListener("click", f_video_play);
var f_play = function() {
pElement.removeClassName(playButton, 'disabled');
if (video.paused == true) {
pElement.addClassName(playButton, 'paused');
//this.playButton.innerHTML = u_play;
if (timer_interval) {
clearInterval(timer_interval);
timer_interval = null;
}
}
else
pElement.removeClassName(playButton, 'paused');
//this.playButton.innerHTML = u_pause;
};
video.addEventListener('play', f_play);
video.addEventListener('pause', f_play);
}
//this.video.addEventListener('click', this.f_video_play);
//*** FULLSCREEN
if (fullScreenButton) {
//pElement.setInnerHTML(this.fullScreenButton, u_fullscreen);
fullScreenButton.title = 'Full screen';
fullScreenButton.addEventListener("click", function() {
var x = pElement.x('div-vlc-main');//this.video;
if (x) {
if (pDocument.isFullScreen())
pDocument.exitFullScreen(x);
else if (pDevice.isIOS())// && !pDevice.isIOS12())
pDocument.fullScreen(video);
else
pDocument.fullScreen(x);
}
});
var f = function() {
if (pDocument.isFullScreen()) {
pElement.addClassName(fullScreenButton, 'fullscreen');
fullScreenButton.title = pDocument.getStyleValue('btn-exit-fullscreen-tooltip');
}
else {
pElement.removeClassName(fullScreenButton, 'fullscreen');
fullScreenButton.title = pDocument.getStyleValue('btn-fullscreen-tooltip');
}
};
document.addEventListener("fullscreenchange", f);
document.addEventListener("mozfullscreenchange", f);
document.addEventListener("webkitfullscreenchange", f);
pElement.x('div-vlc-header').addEventListener('dblclick', function() { pElement.click(fullScreenButton); });
video.addEventListener('dblclick', function() { pElement.click(fullScreenButton); });
}
this.time_range = new pRange(seekBar);
this.time_range.enabled = false;
this.time_range.addEventListener('move', function(e) {
var t = (that.start_time>=0? that.start_time : 0)/1000 + (e.value / 1000);
if (seekBar) seekBar.title = pTime.display(t * 1000);
});
this.time_range.addEventListener("change", function() {
//Calculate the new time
//var d = this.start_time>=0? (this.stop_time - this.start_time)/1000 : this.video.duration;
var t = ((that.start_time>0? that.start_time : 0) + that.time_range.value)/1000;
// Update the video time
video.currentTime = t;
});
function f_time() {
//console.log(this.video.currentTime);
// Calculate the slider value
var c = video.currentTime * 1000 - (that.start_time>0? that.start_time : 0), d = (that.start_time>0 || that.stop_time>0)? (that.stop_time - that.start_time) : video.duration * 1000, v = c;//(100 / d) * c;
// Update the slider value
if (seekable()) {
//pDocument.show(this.seekBar.parentElement);
pElement.setInnerHTML(t1, pTime.display(c) + (display_remaining_time? ' / -' : ' / ') + pTime.display(display_remaining_time? d - c : d));
}
else {
//pDocument.hide(this.seekBar.parentElement);
pElement.setInnerHTML(t1, pTime.display(c));
}
that.time_range.min = 0;
that.time_range.max = d;
that.time_range.value = v;
var b = video.buffered;
//console.log(b.length + ' ' + (b.length>0? b.end(0) : '0'));
that.time_range.buffered = ((b && b.length>0)? b.end(b.length-1) : 0)*1000 - (that.start_time>0? that.start_time : 0);
if (d<60000) {
if (!timer_interval) {
timer_interval = setInterval(f_time, 10);
//console.log("set interval...");//this.video.currentTime);
}
}
else if (timer_interval) {
clearInterval(timer_interval);
timer_interval = null;
}
};
video.addEventListener("timeupdate", f_time);
f_time();
if (t1)
t1.onclick = function() { display_remaining_time = !display_remaining_time; f_time(); };
this.resetTime = function() {
pElement.setInnerHTML(t1, pTime.display(0) + (display_remaining_time? ' / -' : ' / ') + pTime.display(0));
that.time_range.value = 0;
that.time_range.buffered = 0;
if (seekBar) seekBar.title = pTime.display(0);
};
// Pause the video when the slider handle is being dragged
//seekBar.addEventListener("mousedown", function() { video.pause(); });
// Play the video when the slider handle is dropped
//seekBar.addEventListener("mouseup", function() { video.play(); });
//*** VOLUME
if (muteButton) {
muteButton.onclick = function(e) {
if (video.muted == false)
video.muted = true;
else
video.muted = false;
};
}
this.volume_range = new pRange(volumeBar);
this.volume_range.enabled = false;
this.volume_range.min = 0;
this.volume_range.value = video.volume * 100;
//this.volume_range.max = 1;
this.volume_range.addEventListener('change', function() {
//console.log('volume: ' + this.volume_range.value / 100);
video.volume = that.volume_range.value / 100;
});
function f_volume() {
if (muteButton) {
if (video.muted == false) {
pElement.removeClassName(muteButton, 'muted');
muteButton.title = "Mute";
}
else {
pElement.addClassName(muteButton, 'muted');
muteButton.title = "Unmute";
}
}
volumeBar.value = video.volume * 100;
};
video.addEventListener('volumechange', f_volume);
f_volume();
};
/******************************************************************************/
/*** END OF FILE ************************************************************/
/******************************************************************************/