/*see play.js in same dir for source*/
/* Copyright(c)2008-2017 Internet Archive. Software license AGPL version 3. */
'use strict';
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
// Latest variant of video/audio-related playback
// For /details/[IDENTIFIER]
/* global jwplayer */
if (typeof jwplayer !== 'undefined' && jwplayer.version) {
if (parseInt(jwplayer.version, 10) >= 7) jwplayer.key = 'ZV+cHpnETSSMPgD9dAAhnY6l+yhfV818mrpe4Q==';else if (parseInt(jwplayer.version, 10) >= 6) jwplayer.key = 'sZbikYlI/xtW0U/3Tw1DOdjC1EahhtUCJF5KggVdqDY=';
}
(function jquery_no_conflict($) {
// NOTE "getState().toUpperCase()" for case change from jw6 (upper) to jw7 (lower) (see also jwv)
// any methods or vars here are like private-to-outside globals and same for all "Play objects"
var stash = {};
// global config, for all Play objects
var ios = navigator.userAgent.indexOf('iPhone') > 0 || navigator.userAgent.indexOf('iPad') > 0 || navigator.userAgent.indexOf('iPod') > 0;
// playing video size for normal /details/ pages
var VIDEO_HEIGHT = 480;
var VIDEO_WIDTH = 640; // (for 4:3 aspect -- scales for other aspects)
var CONTROLS_HEIGHT = 30;
var AUDIO_WIDTH = 350;
var AUDIO_HEIGHT = CONTROLS_HEIGHT;
var CONTROLS_MAX_WIDTH = 800;
var IA_CLICK_WIDTH = 24;
var PLAYLIST_ENTRY_HEIGHT = 20;
var HEIGHT_ALIST = 370; // NOTE: max height; if few list entries, will be less
var HEIGHT_VLIST = 100; // NOTE: max height; if few list entries, will be less
var METADATA_HEIGHT = 100; // metadata peekaboo min height! (for "responsive")
var Play = function () {
// [playlist] should by an array, something like (ideally) one of:
// [ {"file":"chapter1.mp4"}, {"file":"chapter2.mp4"}, .. ]
// [ {"sources":[{"file":"video.mp4"},{"file":"video.ogv"},{..}]}, .. ]
function Play(jid, playlist) {
var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
_ref$start = _ref.start,
start = _ref$start === undefined ? 0 : _ref$start,
_ref$embed = _ref.embed,
embed = _ref$embed === undefined ? false : _ref$embed,
_ref$flash = _ref.flash,
flash = _ref$flash === undefined ? false : _ref$flash,
_ref$hide_list = _ref.hide_list,
hide_list = _ref$hide_list === undefined ? false : _ref$hide_list,
_ref$autoplay = _ref.autoplay,
autoplay = _ref$autoplay === undefined ? false : _ref$autoplay,
_ref$audio = _ref.audio,
audio = _ref$audio === undefined ? false : _ref$audio,
_ref$width = _ref.width,
width = _ref$width === undefined ? 0 : _ref$width,
_ref$height = _ref.height,
height = _ref$height === undefined ? 0 : _ref$height,
_ref$responsive = _ref.responsive,
responsive = _ref$responsive === undefined ? false : _ref$responsive,
_ref$aspectratio = _ref.aspectratio,
aspectratio = _ref$aspectratio === undefined ? false : _ref$aspectratio,
_ref$noshare = _ref.noshare,
noshare = _ref$noshare === undefined ? false : _ref$noshare,
_ref$nolinks = _ref.nolinks,
nolinks = _ref$nolinks === undefined ? false : _ref$nolinks,
_ref$logo = _ref.logo,
logo = _ref$logo === undefined ? false : _ref$logo,
_ref$so = _ref.so,
so = _ref$so === undefined ? false : _ref$so,
_ref$tv = _ref.tv,
tv = _ref$tv === undefined ? false : _ref$tv,
_ref$tvStart = _ref.tvStart,
tvStart = _ref$tvStart === undefined ? 0 : _ref$tvStart,
_ref$tvEnd = _ref.tvEnd,
tvEnd = _ref$tvEnd === undefined ? 0 : _ref$tvEnd,
_ref$tvContributor = _ref.tvContributor,
tvContributor = _ref$tvContributor === undefined ? false : _ref$tvContributor,
_ref$tvSource = _ref.tvSource,
tvSource = _ref$tvSource === undefined ? false : _ref$tvSource,
_ref$play_just = _ref.play_just1,
play_just1 = _ref$play_just === undefined ? false : _ref$play_just,
_ref$list_height = _ref.list_height,
list_height = _ref$list_height === undefined ? 0 : _ref$list_height,
_ref$skinC = _ref.skinC,
skinC = _ref$skinC === undefined ? false : _ref$skinC,
_ref$skinB = _ref.skinB,
skinB = _ref$skinB === undefined ? false : _ref$skinB,
_ref$identifier = _ref.identifier,
identifier = _ref$identifier === undefined ? false : _ref$identifier,
_ref$onTime = _ref.onTime,
onTime = _ref$onTime === undefined ? false : _ref$onTime,
_ref$onComplete = _ref.onComplete,
onComplete = _ref$onComplete === undefined ? false : _ref$onComplete,
_ref$onDisplayClick = _ref.onDisplayClick,
onDisplayClick = _ref$onDisplayClick === undefined ? false : _ref$onDisplayClick,
_ref$onReady = _ref.onReady,
onReady = _ref$onReady === undefined ? false : _ref$onReady,
_ref$collection = _ref.collection,
collection = _ref$collection === undefined ? false : _ref$collection,
_ref$waveformer = _ref.waveformer,
waveformer = _ref$waveformer === undefined ? false : _ref$waveformer,
_ref$speed = _ref.speed,
speed = _ref$speed === undefined ? 1.0 : _ref$speed,
_ref$details = _ref.details,
details = _ref$details === undefined ? location.href : _ref$details;
_classCallCheck(this, Play);
// xxxx should wrap innards with try/catch
// eslint-disable-next-line no-alert
if (!jid) return alert('please pass in a unique identifier for this object');
if (typeof stash[jid] !== 'undefined') {
if (typeof playlist === 'undefined') return stash[jid]; // return prior created object
delete stash[jid]; // new jwplayer + playlist for prior jid
}
stash[jid] = this; // stash a pointer so that a repeat call to Play(jid) returns prior object
// more (per instance) variables (cant be overridden/changed/seen by caller):
var self = this;
var tvTitle = tv && playlist.length === 1 ? playlist[0].title : '';
var list_2cols = responsive && audio;
var jwv = parseInt(jwplayer.version, 10 // eg: 6 or 7
);var jidsel = '#' + jid;
var jidlist = '#' + jid + '__list';
var readyIA = false;
var DAR = 4 / 3;
var flashAnamorphic = false;
var first_seeked_playlist = false;
var first_onmeta = false;
var jwwidth = 0;
var mousedover = false;
var skin = 'six';
var waveformed = false;
var buttons = false;
var pause_first_seek = embed && !tv && !audio && !autoplay && start;
var update_url_onload = true;
var onCompleteStop = false; // playlists by default keep going to song B when song A is done
// convenient, no? Stateless function, global to all Play objects
// eslint-disable-next-line no-console
var log = location.host.substr(0, 4) !== 'www-' ? function () {} : console.log.bind(console);
// eslint-disable-next-line prefer-rest-params
log('PLAY CONFIG:', arguments[2]
// xxx v6.8 for /details/anamorphic has wrong width in flash mode! so squishface unlike v6.1
);self.adjustVideoWidth = function (player, onMetaSizingIn) {
var onMetaSizing = onMetaSizingIn;
if (player.getRenderingMode() === 'flash') {
// reset in case anamorphic videos mixed in with non...
flashAnamorphic = false;
// jw v6.8 -- ensure list hasnt been filtered down (see "same_len" above)
if (player.getPlaylist().length === playlist.length && player.height === onMetaSizing.height) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = playlist[player.geetPlaylistIndex()].sources[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var src = _step.value;
// find correct playing element in "sources" (bec. we may be in SD/HD toggle state!)
if (src.width > 0 && src.width !== onMetaSizing.width) {
// think we have an anamorphic video on our hands! reset the width...
// eg: /details/anamorphic
log('playing #', 'file:', src.file, '(', src.width, 'x', src.height, ')');
log('likely anamorphic, since metadata.width==', onMetaSizing.width, ', overridding width');
flashAnamorphic = true;
onMetaSizing.width = src.width;
break;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
}
if (onMetaSizing.height && onMetaSizing.width && onMetaSizing.height > 0 && onMetaSizing.width > 0 && parseInt(onMetaSizing.height, 10) > 0) {
DAR = parseInt(onMetaSizing.width, 10) / parseInt(onMetaSizing.height, 10);
log('DAR: ', DAR, onMetaSizing.width, 'x', onMetaSizing.height);
}
if (embed) self.embedResize();
};
self.embedResize = function () {
if (!jwplayer || !jwplayer(jid)) return;
if (audio) {
jwplayer(jid).resize(Math.min(CONTROLS_MAX_WIDTH, $(window).width()) - IA_CLICK_WIDTH, AUDIO_HEIGHT);
return;
}
// window max avail width and height for us
var WW = $(window).width();
var WH = $(window).height() - list_height;
if (!flashAnamorphic || DAR <= 0) {
jwplayer(jid).resize(WW, WH);
return;
}
// First see if we fit inside with max height of avail window
var h2 = $(window).height();
var w2 = Math.round(h2 * DAR);
if (w2 > WW) {
log('FLASH! too big..');
w2 = $(window).width();
h2 = Math.round(w2 / DAR);
}
log('FLASH! Resize to: ', w2, 'x', h2);
jwplayer(jid).resize(w2, h2);
$(jidsel).parent().css({ margin: 'auto' } // re-center
);
};
self.playN = function (idx, onPLI) {
var $rows = $(jidlist).find('.jwrow, .jwrowV2');
$rows.removeClass('playing');
if (!readyIA) return false;
$($rows.get(idx)).addClass('playing');
if (!onPLI) jwplayer(jid).playlistItem(idx);
return false;
};
// xxx suck, ubuntu new firefox re-seeks to start w/o double doing this, etc....
self.seeker_playlist = function () {
if (first_seeked_playlist) return;
first_seeked_playlist = true;
if (pause_first_seek) {
// oh cry/facepalm...
// /embed/ia20thanniversaryevent?start=2150
// is now NOT wanted to autoplay ( unless _also_ has ""&autoplay=1" )
jwplayer(jid).onPlay(function () {
if (!pause_first_seek) return;
log('onPlay()');
pause_first_seek = false;
self.pause();
log('... paused first seek!');
});
}
if (!start) return;
// NOTE: special since phantomJS testing looks for this logging in production
// eslint-disable-next-line no-console
if (typeof console !== 'undefined' && console.log)
// eslint-disable-next-line no-console
console.log('seeker_playlist() to ', start, pause_first_seek ? ' NOSTART' : ' AUTOSTART');
self.pause();
jwplayer(jid).seek(start);
};
self.embed_setup = function () {
$(window).on('resize orientationchange', function () {
// Bind window resize to resize the player
clearTimeout(Play.throttler2);
Play.throttler2 = setTimeout(function () {
// resize/orient flip -- resize and reflow elements
new Play(jid).embedResize();
}, 250);
});
};
self.details_setup = function () {
var startPlaylistIdx = 0;
var re = '^/details/' + identifier + '/([^&?]+)';
var mat = location.pathname.match(re);
if (mat) {
var file = decodeURIComponent(mat[1].replace(/\+/g, '%20'));
log('looking for: ', file
// log(playlist)
// eslint-disable-next-line guard-for-in
);for (var ii in playlist) {
var idx = Number(ii // convert from string!
);if (playlist[idx].orig === file) {
log('player should seek to track #', idx);
startPlaylistIdx = idx;
break;
}
}
}
if (!startPlaylistIdx && !start && !autoplay) update_url_onload = false;
if (!start && !autoplay && !tv && startPlaylistIdx) pause_first_seek = true;
if (!autoplay && (startPlaylistIdx || start)) {
log('seek #', startPlaylistIdx, ' to ', start);
var jw = jwplayer(jid);
jw.playlistItem(startPlaylistIdx);
}
};
self.pause = function () {
var jw = jwplayer(jid);
if (readyIA && jw && jw.getState && jw.getState().toUpperCase() === 'PLAYING') jw.pause();
};
self.remove = function () {
self.pause();
var jw = jwplayer(jid);
if (readyIA && jw && (jwv === 7 ? jw.getConfig() : jw.config)) jw.remove();
delete stash[jid];
};
self.speed = function (valIn) {
var val = valIn;
if (typeof valIn === 'undefined') {
var rate = $('#' + jid + ' video').get(0).playbackRate;
if (rate <= 0.5) val = 1.0;else if (rate >= 3.0) val = 0.5;else val = rate + 1.0;
}
var vid = $('#' + jid + ' video').get(0);
vid.playbackRate = val;
log('speed to ' + val);
return false;
};
self.addClickablePlaylist = function () {
if (hide_list) return; // nothing to do!
var jwlist = jwplayer(jid).getPlaylist();
var same_len = true;
if (jwlist.length !== playlist.length) {
log('NOTE: jw playlist filtered down -- ', playlist.length, '==>', jwlist.length, ' items');
same_len = false;
}
var ialist = '';
var ialistC1 = '';
var ialistC2 = '';
$.each(jwlist, function (idx, val) {
var ttl = typeof val.title === 'undefined' ? '' : val.title.replace(/^\d+\. /, ''); // xxx "1. Camaro" ==> "Camaro""
// In v6.8 flash mode (only), duration no longer is passed back via "getPlaylist()" 8-(
// so try the original list sent to jwplayer config if we can...
var duration = typeof val.duration !== 'undefined' ? val.duration : false;
if (duration === false) {
duration = same_len && typeof playlist[idx] !== 'undefined' && typeof playlist[idx].duration !== 'undefined' ? playlist[idx].duration : 0;
}
if (duration <= 0) duration = false;
if (list_2cols) {
var str = '\n\n \n ' + (idx + 1) + '\n \n ' + ttl + '\n \n -\n \n ' + (duration ? Play.sec2hms(duration) : '') + '\n \n
\n';
if (idx < playlist.length / 2) ialistC1 += str;else ialistC2 += str;
} else {
ialist += '\n\n \n
\n ' + (duration ? Play.sec2hms(duration) : '') + '\n
\n
\n ' + (idx + 1) + '\n
\n
\n ' + ttl + '\n
\n
\n';
}
});
if (list_2cols) {
ialist = '
\n
\n ' + ialistC1 + '\n
\n
\n ' + ialistC2 + '\n
\n
';
}
var css = {};
if (responsive) {
css.width = width;
css.margin = 'auto';
if (audio && skin !== 'five' && skin !== 'bekle') {
// stay as wide as the player is... which has a max-width in this skin...
css['max-width'] = CONTROLS_MAX_WIDTH;
}
if (!audio) $(jidsel).css('margin', 'auto');
}
$(jidlist).addClass(list_2cols ? 'jwlistV2' : 'jwlist').css(css).html(ialist);
log(playlist
// log(JSON.stringify(playlist,undefined,2))
);
};
self.debug = function () {
// eslint-disable-next-line no-debugger
debugger;
};
/* eslint-disable no-param-reassign */
// ^^^ this class was designed _deliberately_ using scoping techniques _outside_ of the
// methods to allow them to be set/manipulated _per instance_ but auto binding closure
// around each instance/object -- so from here for awhile, disabling that eslint rule...
self.responsiveResize = function (first) {
if (!responsive) return;
var playoff = $(jidsel).offset();
var maxH = $(window).height() - playoff.top - METADATA_HEIGHT;
if (audio) {
if (playlist && playlist.length > 0 && playlist[0].image) AUDIO_HEIGHT = 140; // (typically png is 800x140 now)
// OK, so we will be using "maxH" for the **playlist**.
// Reduce by player/waveform height now...
// but make sure at least ~8 rows (or 4 if oldtimeradio item ;-) always show
// (eg: insanely short browser??)
maxH -= AUDIO_HEIGHT;
maxH = Math.max(240, maxH);
if (!embed) {
log('responsiveResize() maxH:', maxH);
list_height = maxH;
log($(jidlist).length);
$(jidlist).css({
'max-height': maxH,
'overflow-x': 'hidden',
'overflow-y': 'auto' });
}
width = '100%';
$('#theatre-controls .fave-share').removeClass('fave-share');
$('#theatre-controls').offset({ top: playoff.top }).css({
visibility: 'visible',
'background-color': 'black' });
} else {
var aspect = DAR;
if (playlist && playlist.length > 0 && playlist[0].sources && playlist[0].sources.length > 0 && playlist[0].sources[0].width && playlist[0].sources[0].height) {
aspect = playlist[0].sources[0].width / playlist[0].sources[0].height;
log('aspect ratio appears to be: ', aspect);
}
var maxW = $('.container-ia:last').width();
log('video max rect avail: ', maxW, 'x', maxH);
var vidW = void 0;
var vidH = void 0;
var _arr = [960, 840, 720, 600, 480, 360, 240, 180];
for (var _i = 0; _i < _arr.length; _i++) {
vidH = _arr[_i];
vidW = Math.round(vidH * aspect);
log('video size try fit: ', vidW, 'x', vidH);
if (vidW <= maxW && vidH <= maxH || vidW <= 320) break;
}
width = vidW; // '100%'
height = vidH;
if (typeof AJS !== 'undefined')
// eslint-disable-next-line no-undef
AJS.theatre_controls_position(false, 0, width, height);
}
if (first) {
// we havent setup the player yet, but want to setup a watcher
// for browser resize or mobile orientation changing
$(window).on('resize orientationchange', function () {
clearTimeout(Play.throttler);
Play.throttler = setTimeout(function () {
// resize/orient flip -- resize and reflow elements
new Play(jid).responsiveResize();
}, 250);
});
} else if (!audio) {
jwplayer(jid).resize(width, height);
}
};
// ---------- START OBJECT CONSTRUCTOR --------
if (nolinks) {
identifier = false;
collection = false;
noshare = true;
}
speed = parseFloat(speed);
if (typeof $.cookie !== 'undefined' && $.cookie('avspeed')) speed = parseFloat($.cookie('avspeed'));
if (!$(jidsel).length) {
log('play.js requires #', jid, ' element on page -- not found');
return false;
}
self.responsiveResize(true);
if (identifier !== false) details = 'https://archive.org/details/' + identifier;
if (tv && tvEnd) details += '/start/' + tvStart + '/end/' + tvEnd;
if (typeof playlist === 'undefined') {
playlist = [{
sources: [{ file: '/download/family-rolled/family-rolled.mp4' }, { file: '/download/family-rolled/family-rolled.ogv' }],
image: '/download/family-rolled/format=Thumbnail&ignore=x.jpg' }];
start = true;
hide_list = true;
}
if (!hide_list) {
if (!list_height) // if user hasn't specified...
list_height = audio ? HEIGHT_ALIST : HEIGHT_VLIST;
// now drop down list_height if there aren't many playlist elements...
list_height = Math.min(list_height, playlist.length * PLAYLIST_ENTRY_HEIGHT);
}
if (!responsive && !(width > 0 && height > 0)) {
if (embed) {
var winw = $(window).width();
var winh = $(window).height();
width = audio ? Math.min(winw, CONTROLS_MAX_WIDTH) : winw;
height = audio ? AUDIO_HEIGHT + list_height : winh - list_height;
} else if (!aspectratio) {
width = audio ? AUDIO_WIDTH : VIDEO_WIDTH;
height = audio ? AUDIO_HEIGHT + list_height : VIDEO_HEIGHT;
}
}
jwwidth = audio ? width - IA_CLICK_WIDTH : width;
if (audio && embed && identifier !== false) {
var audiorow = '\n';
$(audiorow).insertBefore(jidsel);
$('#ia' + jid + ' a').tooltip({});
}
$.each(playlist, function (idx, val) {
// log(val.sources)
if (typeof val.autoplay !== 'undefined') {
// for playlist: A B C D; if C has autoplay=false
// it means play A and (auto)play B -- but stop when B is done
if (!onCompleteStop) onCompleteStop = [];
onCompleteStop[idx - 1] = !val.autoplay;
}
if (typeof val.sources === 'undefined') {
if (typeof val.file !== 'undefined') val.sources = [{ file: val.file, height: 480 }];
}
if (typeof val.sources === 'undefined') {
// eslint-disable-next-line no-alert
alert(idx + ': sources undefined!' // xxx
);
}
// log(val.sources)
});
if (!hide_list) {
var sty = list_2cols ? '' : 'style="height:' + list_height + 'px"';
var ialist = '
';
$(ialist).insertAfter(jidsel);
}
if (tvTitle) {
// remove the end time (for brevity) for the "click to play" center button
playlist[0].title = playlist[0].title.replace(/( \d+:\d+[amp]+)-\d+:\d+[amp]+ /, '$1 ');
}
if (jwv === 7 && playlist[0].image) playlist[0].image = playlist[0].image.replace(/%2F/g, '/' // for jwplayer v7+
);var jwcfg = {
// *could* consider this if we think jwplayer playlists are reasonble in v6.8 now....
// "listbar":{layout:'basic',position:'bottom',size:list_height},
playlist: JSON.parse(JSON.stringify(playlist)), // deep copy; jw v6.8 _changes_ our list!
analytics: { enabled: false, cookies: false }, // dont track our users xxx
abouttext: 'this item, formats, and more at Internet Archive',
aboutlink: details,
startparam: 'start',
logo: {},
sharing: {},
autostart: autoplay, // || (start && !ios) ? true : false),
fallback: so,
width: isNaN(jwwidth) ? '100%' : jwwidth,
height: audio ? 30 : height
// + list_height // *could* consider this if we think jw playlists are reasonble in v6.8 now
// alert(width+' x '+height+'/'+list_height)
};if (responsive && !embed) {
jwcfg.displaytitle = false; // dont show title of 1st track next to big PLAY button
} else if (aspectratio) {
jwcfg.width = '100%';
jwcfg.aspectratio = aspectratio;
delete jwcfg.height;
}
if (responsive && audio && !embed) {
jwcfg.displaytitle = false; // dont show title of 1st track next to big PLAY button
skin = 'bekle';
// allow user (for now) to pick 1 of 8 skins (six.xml is builtin default)
var skinarg = location.search.match(/\?skin=(\d+)/);
if (skinarg && skinarg.length) {
var skins = ['beelden', 'bekle', 'five', 'glow', 'roundster', 'stormtrooper', 'vapor'];
skin = skins[skinarg[1] % skins.length];
}
if (skin === 'bekle') jwcfg.skin = '/jw/6.8/bekleA.xml';else jwcfg.skin = '/jw/6.8/skins/' + skin + '.xml';
log('TRYING SKIN: ', jwcfg.skin);
if (skin === 'five' || skin === 'bekle') jwcfg.stretching = 'exactFit';
}
if (identifier !== false) {
var startend = tv && tvEnd ? '?start=' + tvStart + '&end=' + tvEnd : '';
// xxx check if multiple identifiers:
// xxx *SHOULD* be able to just encode "embedcode" like iatest.js does, WTF?!?!!
var embedcode = ('').replace(/embed\/MEDIAID/, 'embed/' + identifier + startend).replace(/\s+/g, ' ');
var embedcodeWP = '[archiveorg ' + identifier + startend + ' width=640 height=' + (audio ? AUDIO_HEIGHT : VIDEO_HEIGHT) + ' frameborder=0 webkitallowfullscreen=true mozallowfullscreen=true]';
jwcfg.mediaid = identifier;
if (!noshare && !audio) jwcfg.sharing.code = encodeURI(embedcode);
if (audio) jwcfg.embedcode = embedcode; // (IA extension used by play.js)
// IFF these exist, fill them in!
$('#embedcodehere').text(embedcode);
$('#embedcodehereWP').text(embedcodeWP);
}
if (!noshare && !audio) {
// xxx check if multiple identifiers....
// xxx _SHOULD_ be able to just use "jwplayer().getConfig().sharing.code" (iatest.js) WTF?!
jwcfg.sharing.link = details;
}
if (jwv !== 7 && responsive && !embed || typeof jwcfg.sharing.link === 'undefined' && typeof jwcfg.sharing.code === 'undefined') delete jwcfg.sharing;
if (jwcfg.sharing) {
buttons = true;
if (jwv === 7) jwcfg.sharing.sites = ['facebook', 'twitter', 'pinterest', 'tumblr', 'reddit', 'googleplus', 'email'];
}
if (!audio && collection && !tv) jwcfg.related = { file: '/services/collection-rss.php?collection=' + collection };
if (ios && audio) jwcfg.mobilecontrols = true; // turn of iOS native controls and go w/ JW controls xxx
if (flash) jwcfg.primary = 'flash';
if (skinB) jwcfg.skin = '/jw/6.8/bekleB.xml';
if (skinC) jwcfg.skin = '/jw/6.8/bekleC.xml';
if (embed && !audio && !nolinks || logo) {
jwcfg.logo = {
file: '//archive.org/jw/6.8/glogo-ghost.png',
link: details,
position: 'bottom-right',
margin: 2,
hide: false
};
}
if (!audio && !embed) {
// later, if playing in flash mode *and* we determine the video is anamorphic,
// we need to set this now so we stretch "disproportionally" to our correctly figured W/H.
// Would *prefer* to only set if we detect flash and anamorphic, but we can't apply this
// flash setting later in v6.8 anymore...
//
// jwcfg.stretching = "exactFit" // bleah Jan12,2014 -- cant do this w/o breaking *all*
// fullscreen !16x9 videos on 16x9 monitors... reverting to anamorphic video is wrong aspect
// when in flash mode (jw bug -- no workaround now)
}
if (play_just1 || onCompleteStop) {
var onCompleteOrig = onComplete;
onComplete = function onComplete(jw) {
var evt = { done: play_just1 || onCompleteStop[jw.getPlaylistIndex()] };
if (evt.done) jw.stop // dont wanna auto-advance to next track in playlist
();if (onCompleteOrig) onCompleteOrig(jw, evt);
};
}
// this class was designed _deliberately_ using scoping techniques _outside_ of the
// methods to allow them to be set/manipulated _per instance_ but auto binding closure
// vvv around each instance/object -- we can now re-enable that eslint rule...
/* eslint-enable no-param-reassign */
log(jwcfg);
jwplayer(jid).setup(jwcfg);
jwplayer(jid).onReady(function () {
log('IA ', jid, ' is ready');
var player = jwplayer(jid // xxx revisit since arrow fn update made "this"!==player
);log('NOTE: JW version: ', jwplayer.version, 'Rendering mode:', player.getRenderingMode());
if (onTime) log('NOTE: onTime() is in use!');
if (onTime) player.onTime(function () {
return onTime(player);
});
if (onComplete) player.onComplete(function () {
return onComplete(player);
});
if (onDisplayClick) player.onDisplayClick(function () {
return onDisplayClick(player);
});
readyIA = true;
// NOTE: we now do this here because jwplayer can shrink down the passed in playlist on us!
self.addClickablePlaylist();
if (audio && responsive && !embed) self.responsiveResize();
if (onReady) onReady(player
// trap for SPACE key press to toggle pause/play
);$(jidsel).parent().mouseover(function () {
mousedover = true;
});
$(jidsel).parent().mouseout(function () {
mousedover = false;
});
$(document).keyup(function (e) {
if (e.keyCode === 32 && mousedover) {
player.pause();
e.preventDefault();
e.stopPropagation();
return false;
}
return true;
});
if (responsive && !audio) $(jidsel).css('margin', 'auto');
var flashy = player.getRenderingMode() === 'flash';
if (audio) {
$(jidsel).css('min-height', AUDIO_HEIGHT // bug IMHO in jwplayer -- for all mobile sets to 200!!
);if (responsive) {
if (AUDIO_HEIGHT > CONTROLS_HEIGHT) {
if (flashy) {
// bug in jwplayer -- flash height set right, but parent/container wrong!
$(jidsel + '_wrapper').height(AUDIO_HEIGHT);
} else {
// xxx force controlbar to always show when using waveforms!
$(jidsel + ' .jwcontrolbar').show().fadeTo(0, 1);
player.resize(player.getWidth(), player.getHeight());
}
}
} else if (flashy) {
$(jidsel).parent().parent().find('.iajw,.iajwBG').css('visibility', 'visible');
} else {
$(jidsel).parent().find('.iajw,.iajwBG').css('visibility', 'visible');
}
} else {
if (embed && !nolinks) {
var butid = 'btn1';
var ttl = tvTitle ? tvTitle.replace(/ : /g, '\n') + '\n\nClick above for more information and clips\nat the Internet Archive' : 'More Formats from Internet Archive';
player.addButton('/images/glogo20x20.png', ttl, function () {
window.top.location.href = details;
}, butid);
if (tv) {
if (tvSource !== false) {
player.addButton('/images/tv/' + identifier.split('_')[0] + '.png', 'Look for this show on ' + tvContributor + ' website', function () {
window.top.location.href = tvSource;
}, 'btn2');
buttons = true;
}
// fix for newlines in html5 mode (only text not HTM newlines work in flash):
$(jidsel + '_dock_' + butid + '_tooltip .jwcontents').css('white-space', 'pre-wrap');
}
}
if (embed && !noshare && !tv && identifier !== false) {
player.addButton('/jw/6.8/embed.png', 'Embedding Examples and Help', function () {
window.top.location.href = '/help/video.php?identifier=' + identifier;
}, 'btn2');
buttons = true;
}
}
if (!responsive && !audio && !embed && typeof $.cookie !== 'undefined') {
var hover = flashy ? 'Click to have player try HTML5 first, then flash' : 'Click to have player try flash first, then HTML5';
player.addButton('/jw/6.8/flash.png', hover, function () {
if (flashy) $.cookie('avpref2', null, { path: '/' });else $.cookie('avpref2', 'flash', { path: '/' }
// reload the page
);window.top.location.href = location.href;
window.top.location.reload(true);
}, 'btn3');
buttons = true;
}
if (!embed && !flashy && !buttons) $('body').addClass('jw_nodock');
if (responsive && !embed && !audio && typeof AJS !== 'undefined')
// eslint-disable-next-line no-undef
AJS.theatre_controls_position(false, 0, width, height);
if (!embed && responsive) self.details_setup();else if (embed && location.host.match(/archive\.org$/) && location.pathname.match(/^\/embed\//)) self.embed_setup();
}).onMeta(function play_onMeta(obj) {
// only call all this once, because sometime between Feb and May 2014,
// firefox+flash start sending onMeta() *very* frequently, not just once,
// and we need to only "first seek" once, especially!
if (!first_onmeta) {
first_onmeta = true;
log('onMeta() fired');
$('body').addClass('responsive-playing');
if (!audio && embed && obj.width && obj.height) self.adjustVideoWidth(this, obj
// xxx suck, ubuntu new firefox re-seeks to start w/o double doing this, etc....
);if (start) {
log('SEEK TO: ', start);
self.pause();
jwplayer(jid).seek(start);
}
}
}).onPlaylistItem(function (obj) {
log('onPlaylistItem: ', obj.index);
var player = jwplayer(jid // xxx revisit since arrow fn update made "this"!==player
);self.playN(obj.index, true);
self.seeker_playlist
// NOTE: if we decide to do this for video, we WONT do it for TV..
();if (audio && !tv && !embed && identifier && typeof history.replaceState !== 'undefined' && player.config && player.config.playlist && player.config.playlist.length > 1 && player.config.playlist[obj.index] && player.config.playlist[obj.index].orig) {
if (update_url_onload) {
var url = '/details/' + identifier + '/' + encodeURIComponent(player.config.playlist[obj.index].orig).replace(/%2F/g, '/').replace(/%20/g, '+');
// eslint-disable-next-line no-undef
var playset = typeof AJS !== 'undefined' && AJS.arg('playset', 1) ? '&playset=1&autoplay=1' : '';
history.replaceState({}, null, url + playset);
} else {
log('looks like /details/ page loaded cold-state -- leave url AS IS');
update_url_onload = true;
}
}
if (speed !== 1.0) setTimeout(function () {
self.speed(speed);
}, 1000);
if (waveformer && !waveformed) {
var flashy = player.getRenderingMode() === 'flash';
var $wrapme = $(jidsel);
if (flashy) $wrapme = $wrapme.parent();
$wrapme.wrap('');
var jWD = $('#' + waveformer).width // xxxx deal w/ browser resize and orientation changes
();var jHT = $wrapme.height();
$('#' + waveformer).prepend('');
player.onTime(function (evt) {
if (!evt.duration) return;
$('#waveformer').css({ width: Math.round(jWD * (evt.position / evt.duration)) });
});
waveformed = true;
setTimeout(function () {
if (!flashy) $(jidsel).css('background-color', 'transparent');
$('#' + waveformer).css('background-color', '#ddd');
}, 1000);
}
}).onError(function (obj) {
log('err');
log(obj);
$(jidsel).css({ 'background-color': 'black' }
// throw "onError event"
);
});
setTimeout(function () {
var $e = false;
if (!jwplayer || !jwplayer(jid) || typeof jwplayer(jid).getRenderingMode === 'undefined') {
if (so) {
$e = $('
').attr({ class: 'text-danger', style: 'text-align:center;background-color:white' }).html('Looks like you cannot play our media.
You may have a better experience with a newer browser like
Firefox or install/update
Flash');
} else {
$e = $('
').attr({ class: 'text-danger', style: 'text-align:center;background-color:white' }).html('Guessing you cannot play our media?
\n Your browser may be too old to play html5 video tags *and* does not have the flash\n plugin, is disabled, or is a very old version of flash?
\n
Get current Flash version');
}
if (embed) $e.insertBefore($(jidsel));else $e.insertAfter($(jidsel));
}
}, 15000 // 15 seconds
);return this;
} // END OF OBJECT CONSTRUCTOR
// From here on down, these methods are "class"/static and not "instance" methods
// returns number of seconds (may be float) as string "hh:mm:ss"
// note will omit "hh:" if 0 (unless pass in truthy alwaysHH)
// Stateless function, global to all Play objects
_createClass(Play, null, [{
key: 'sec2hms',
value: function sec2hms(secIn, alwaysHH) {
var sec = Math.round(secIn);
var hr = Math.floor(sec / 3600);
var min = Math.floor((sec - hr * 3600) / 60);
sec -= hr * 3600 + min * 60;
// left 0-pad to 2 digits as needed
var hms = '';
var tmp = '';
if (alwaysHH || hr > 0) {
tmp = '00' + hr;
hms += tmp.substr(tmp.length - 2, 2);
hms += ':';
}
tmp = '00' + min;
hms += tmp.substr(tmp.length - 2, 2);
hms += ':';
tmp = '00' + sec;
hms += tmp.substr(tmp.length - 2, 2);
return hms;
}
// [nicked from jwplayer JS v6 code]
// Converts a time-representing string to a number.
// @param {String} The input string. Supported are 00:03:00.1 / 03:00.1 / 180.1s / 3.2m / 3.2h
// @return {Number} The number of seconds.
}, {
key: 'seconds',
value: function seconds(strIn) {
var str = strIn.replace(',', '.');
var arr = str.split(':');
var sec = 0;
if (str.substr(-1) === 's') {
sec = Number(str.substr(0, str.length - 1));
} else if (str.substr(-1) === 'm') {
sec = Number(str.substr(0, str.length - 1)) * 60;
} else if (str.substr(-1) === 'h') {
sec = Number(str.substr(0, str.length - 1)) * 3600;
} else if (arr.length > 1) {
sec = Number(arr[arr.length - 1]);
sec += Number(arr[arr.length - 2]) * 60;
if (arr.length === 3) sec += Number(arr[arr.length - 3]) * 3600;
} else {
sec = Number(str);
}
return sec;
}
}, {
key: 'seek',
value: function seek(link) {
var mat = (link.href + '/').match(/[/#]start\/([\d.]+)\//) || link.href.match(/[?&]start=([\d.]+)/);
if (!mat) return true;
var startsec = mat[1];
jwplayer().seek(startsec
// if we have a relatively modern browser, simply update the browser url
);if (typeof history.pushState === 'undefined') location.href = link.href; // older browwser -- full page refresh
else history.pushState({}, null, link.href // newer!
);return false;
}
/* static except(e){
// report back home an exception was thrown!
const img = new Image(1,1)
img.src =
"http://analytics.archive.org/e.gif" +
"?a="+ encodeURIComponent(navigator.userAgent) +
'&e='+ encodeURIComponent(e.toString()) +
(e.stack && typeof(e.stack)=='string' ?
'&s='+ encodeURIComponent(e.stack) : '')
}
*/
}]);
return Play;
}(); // end class Play
/*
// trap for ESCAPE key pressed to close a popup
$(document).keydown(function(e) {
if (e.keyCode==27)
$('#jpop').remove()
})
*/
// allow "Play(.., ..)" globally:
window.Play = function (id, playlist, options) {
return new Play(id, playlist, options);
};
// only these (static) methods are available globally, eg: Play.seek(..)
var _arr2 = ['sec2hms', 'seconds', 'seek'];
for (var _i2 = 0; _i2 < _arr2.length; _i2++) {
var meth = _arr2[_i2];
window.Play[meth] = Play[meth];
}
})(jQuery);