Skip to content

Instantly share code, notes, and snippets.

@miketaylr
Created November 19, 2013 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save miketaylr/7548766 to your computer and use it in GitHub Desktop.
Save miketaylr/7548766 to your computer and use it in GitHub Desktop.
(function() {
var AdModel, AdPodModel, AgeGate, AppController, AppHelper, AppModel, BaseBeaconController, BeaconController, BeaconHelper, BeaconModel, ComscoreBeaconController, Constants, ContentModel, ControlsView, EndCard, EndCardAdModel, EndCardPlaylist, EventBus, FatalError, GeneralEvent, GlobalErrorHandler, HuluBeaconController, Md5, MediaPlayerView, MozartService, NielsenBeaconController, PlayableModel, PlayerController, PlayerModel, PlayerView, PlaylistPlayerModel, PrerollModel, QOSBeaconController, SiteShelfHelper, Ui, VideoEvent, VideoNetworkState, VideoReadyState,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Md5 = (function() {
var b64pad, hexcase, str2rstr_utf16be, str2rstr_utf16le;
function Md5() {}
Md5.hex_md5 = function(s) {
return this._rstr2hex(this._rstr_md5(this._str2rstr_utf8(s)));
};
Md5.b64_md5 = function(s) {
return this._rstr2b64(this._rstr_md5(this._str2rstr_utf8(s)));
};
Md5.any_md5 = function(s, e) {
return this._rstr2any(this._rstr_md5(this._str2rstr_utf8(s)), e);
};
Md5.hex_hmac_md5 = function(k, d) {
return this._rstr2hex(this._rstr_hmac_md5(this._str2rstr_utf8(k), this._str2rstr_utf8(d)));
};
Md5.b64_hmac_md5 = function(k, d) {
return this._rstr2b64(this._rstr_hmac_md5(this._str2rstr_utf8(k), this._str2rstr_utf8(d)));
};
Md5.any_hmac_md5 = function(k, d, e) {
return this._rstr2any(this._rstr_hmac_md5(this._str2rstr_utf8(k), this._str2rstr_utf8(d)), e);
};
Md5.md5_vm_test = function() {
return this.hex_md5("abc").toLowerCase() === "900150983cd24fb0d6963f7d28e17f72";
};
Md5._rstr_md5 = function(s) {
return this._binl2rstr(this._binl_md5(this._rstr2binl(s), s.length * 8));
};
Md5._rstr_hmac_md5 = function(key, data) {
var bkey, hash, i, ipad, opad;
bkey = this._rstr2binl(key);
if (bkey.length > 16) {
bkey = this._binl_md5(bkey, key.length * 8);
}
ipad = Array(16);
opad = Array(16);
i = 0;
while (i < 16) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
i++;
}
hash = this._binl_md5(ipad.concat(this._rstr2binl(data)), 512 + data.length * 8);
return this._binl2rstr(this._binl_md5(opad.concat(hash), 512 + 128));
};
Md5._rstr2hex = function(input) {
var hex_tab, hexcase, i, output, x;
try {
hexcase;
} catch (e) {
hexcase = 0;
}
hex_tab = (hexcase ? "0123456789ABCDEF" : "0123456789abcdef");
output = "";
x = void 0;
i = 0;
while (i < input.length) {
x = input.charCodeAt(i);
output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
i++;
}
return output;
};
Md5._rstr2b64 = function(input) {
var b64pad, i, j, len, output, tab, triplet;
try {
b64pad;
} catch (e) {
b64pad = "";
}
tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
output = "";
len = input.length;
i = 0;
while (i < len) {
triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
j = 0;
while (j < 4) {
if (i * 8 + j * 6 > input.length * 8) {
output += b64pad;
} else {
output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
}
j++;
}
i += 3;
}
return output;
};
Md5._rstr2any = function(input, encoding) {
var dividend, divisor, full_length, i, j, output, q, quotient, remainders, x;
divisor = encoding.length;
i = void 0;
j = void 0;
q = void 0;
x = void 0;
quotient = void 0;
dividend = Array(Math.ceil(input.length / 2));
i = 0;
while (i < dividend.length) {
dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
i++;
}
full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
remainders = Array(full_length);
j = 0;
while (j < full_length) {
quotient = Array();
x = 0;
i = 0;
while (i < dividend.length) {
x = (x << 16) + dividend[i];
q = Math.floor(x / divisor);
x -= q * divisor;
if (quotient.length > 0 || q > 0) {
quotient[quotient.length] = q;
}
i++;
}
remainders[j] = x;
dividend = quotient;
j++;
}
output = "";
i = remainders.length - 1;
while (i >= 0) {
output += encoding.charAt(remainders[i]);
i--;
}
return output;
};
Md5._str2rstr_utf8 = function(input) {
var i, output, x, y;
output = "";
i = -1;
x = void 0;
y = void 0;
while (++i < input.length) {
x = input.charCodeAt(i);
y = (i + 1 < input.length ? input.charCodeAt(i + 1) : 0);
if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
i++;
}
if (x <= 0x7F) {
output += String.fromCharCode(x);
} else if (x <= 0x7FF) {
output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), 0x80 | (x & 0x3F));
} else if (x <= 0xFFFF) {
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
} else {
if (x <= 0x1FFFFF) {
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
}
}
}
return output;
};
str2rstr_utf16le = function(input) {
var i, output;
output = "";
i = 0;
while (i < input.length) {
output += String.fromCharCode(input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF);
i++;
}
return output;
};
str2rstr_utf16be = function(input) {
var i, output;
output = "";
i = 0;
while (i < input.length) {
output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF);
i++;
}
return output;
};
Md5._rstr2binl = function(input) {
var i, output;
output = Array(input.length >> 2);
i = 0;
while (i < output.length) {
output[i] = 0;
i++;
}
i = 0;
while (i < input.length * 8) {
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
i += 8;
}
return output;
};
Md5._binl2rstr = function(input) {
var i, output;
output = "";
i = 0;
while (i < input.length * 32) {
output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
i += 8;
}
return output;
};
Md5._binl_md5 = function(x, len) {
var a, b, c, d, i, olda, oldb, oldc, oldd;
x[len >> 5] |= 0x80 << (len % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
a = 1732584193;
b = -271733879;
c = -1732584194;
d = 271733878;
i = 0;
while (i < x.length) {
olda = a;
oldb = b;
oldc = c;
oldd = d;
a = this._md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
d = this._md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
c = this._md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
b = this._md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = this._md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
d = this._md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = this._md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = this._md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
a = this._md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = this._md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = this._md5_ff(c, d, a, b, x[i + 10], 17, -42063);
b = this._md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = this._md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = this._md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
c = this._md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = this._md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = this._md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
d = this._md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = this._md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
b = this._md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
a = this._md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
d = this._md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
c = this._md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
b = this._md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
a = this._md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
d = this._md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = this._md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
b = this._md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = this._md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = this._md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
c = this._md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = this._md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = this._md5_hh(a, b, c, d, x[i + 5], 4, -378558);
d = this._md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = this._md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = this._md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
a = this._md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = this._md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = this._md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
b = this._md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = this._md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
d = this._md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
c = this._md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
b = this._md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
a = this._md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
d = this._md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
c = this._md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
b = this._md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
a = this._md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
d = this._md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = this._md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = this._md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
a = this._md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = this._md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = this._md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
b = this._md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = this._md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = this._md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
c = this._md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = this._md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = this._md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
d = this._md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = this._md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
b = this._md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
a = this._safe_add(a, olda);
b = this._safe_add(b, oldb);
c = this._safe_add(c, oldc);
d = this._safe_add(d, oldd);
i += 16;
}
return Array(a, b, c, d);
};
Md5._md5_cmn = function(q, a, b, x, s, t) {
return this._safe_add(this._bit_rol(this._safe_add(this._safe_add(a, q), this._safe_add(x, t)), s), b);
};
Md5._md5_ff = function(a, b, c, d, x, s, t) {
return this._md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
};
Md5._md5_gg = function(a, b, c, d, x, s, t) {
return this._md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
};
Md5._md5_hh = function(a, b, c, d, x, s, t) {
return this._md5_cmn(b ^ c ^ d, a, b, x, s, t);
};
Md5._md5_ii = function(a, b, c, d, x, s, t) {
return this._md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
};
Md5._safe_add = function(x, y) {
var lsw, msw;
lsw = (x & 0xFFFF) + (y & 0xFFFF);
msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
};
Md5._bit_rol = function(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
};
hexcase = 0;
b64pad = "";
return Md5;
})();
AppHelper = (function() {
function AppHelper() {}
AppHelper._platform = null;
AppHelper.setCookie = function(name, value, options) {
var expires, path;
if (!(document.cookie != null)) {
return;
}
if (!options) {
options = {};
}
value = AppHelper.encode(name) + '=' + AppHelper.encode(value);
expires = new Date();
if (options.seconds) {
expires.setTime(expires.getTime() + (options.seconds * 1000));
} else {
expires.setMonth(expires.getMonth() + 1);
}
value += '; expires=' + expires.toUTCString();
path = options.path;
if (!(path != null)) {
path = "/";
}
value += '; path=' + path;
return document.cookie = value;
};
AppHelper.getCookie = function(name) {
var c, kv, _i, _len, _ref;
if ((name != null) && (document.cookie != null)) {
_ref = document.cookie.split(';');
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
c = _ref[_i];
kv = c.split('=');
if (name.toLowerCase() === AppHelper.decode($.trim(kv[0].toLowerCase())) && kv.length > 1) {
return AppHelper.decode($.trim(kv[1]));
}
}
}
return null;
};
AppHelper.generateGUID = function() {
var guid, _i;
guid = '';
for (_i = 1; _i <= 8; _i++) {
guid += (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
return guid.toUpperCase();
};
AppHelper.toMilliseconds = function(sec) {
if (isNaN(sec)) {
return 0;
} else {
return Math.floor(sec * 1000);
}
};
AppHelper.setInterval = function(ms, callback) {
return setInterval(callback, ms);
};
AppHelper.setTimeout = function(ms, callback) {
return setTimeout(callback, ms);
};
AppHelper.cacheBuster = function() {
return Math.floor(Math.random() * 100000000);
};
AppHelper.getJSON = function(url, data, success, error) {
var _this = this;
return $.ajax({
url: url,
dataType: 'jsonp',
data: data,
timeout: 20000,
success: function(data, textStatus, jqXHR) {
return success(data);
},
error: function(jqXHR, textStatus, errorThrown) {
return error(jqXHR);
}
});
};
AppHelper.isStringMatchPatterns = function(patterns, str, ignoreCaseIfStringPattern) {
var i, pattern, tmpStr;
i = 0;
while (i < patterns.length) {
tmpStr = str;
pattern = patterns[i];
if (typeof pattern === "string") {
if (ignoreCaseIfStringPattern) {
tmpStr = tmpStr.toLowerCase();
pattern = pattern.toLowerCase();
}
if (tmpStr.indexOf(pattern) >= 0) {
return true;
}
} else {
if (tmpStr.search(pattern) >= 0) {
return true;
}
}
i++;
}
return false;
};
AppHelper.encode = function(value) {
var encoder;
encoder = encodeURIComponent || escape;
return encoder(value);
};
AppHelper.decode = function(value) {
var decoder;
decoder = decodeURIComponent || unescape;
return decoder(value);
};
AppHelper.truncateText = function(str, length) {
return jQuery.trim(str).substring(0, length).split(" ").slice(0, -1).join(" ") + "...";
};
AppHelper.isAndroid = function() {
return RegExp("Android", 'i').test(navigator.userAgent);
};
AppHelper.isIOS = function() {
return RegExp("(iphone|ipod|ipad|itouch)", 'i').test(navigator.userAgent);
};
AppHelper.getIOSVersion = function() {
var agent, start;
agent = window.navigator.userAgent;
start = agent.indexOf('OS ');
if (this.isIOS()) {
return Number(agent.substr(start + 3, 3).replace('_', '.'));
}
return 0;
};
AppHelper.enableAdBreak = function() {
return this.isIOS();
};
AppHelper.getPlatformName = function() {
if (AppHelper._platform === null) {
AppHelper._platform = AppHelper.isIOS() ? 'iOS' : (AppHelper.isAndroid() ? 'android' : 'unknown');
}
return AppHelper._platform;
};
AppHelper.devicePixelRatio = function() {
if (window.devicePixelRatio != null) {
return window.devicePixelRatio;
} else {
return 1;
}
};
AppHelper.isPlaylistCompatible = function() {
var playlist_compatible_agents;
playlist_compatible_agents = ["ipad", "itouch", "ipod", "iphone"].join("|");
return RegExp("(" + playlist_compatible_agents + ")", 'i').test(navigator.userAgent);
};
AppHelper.isPlayerAllowed = function() {
var android_devices, android_devices_regex, can_play_codec, enableAndroid, ios_devices, ios_devices_regex, remaining_devices, remaining_devices_regex;
ios_devices = ["ipad", "itouch", "ipod", "iphone"].join("|");
ios_devices_regex = RegExp("(" + ios_devices + ")", 'i');
android_devices = ["Android.*Mobile", "Android"].join("|");
android_devices_regex = RegExp("(" + android_devices + ")", 'i');
enableAndroid = android_devices_regex.test(navigator.userAgent) && AppHelper.isSupportedAndroidVerision();
remaining_devices = ["Silk\/2", "Silk\/3", "Xbox"].join("|");
remaining_devices_regex = RegExp("(" + remaining_devices + ")", 'i');
can_play_codec = $('.video-player').length > 0 && $('.video-player')[0].canPlayType && ($('.video-player')[0].canPlayType('video/mp4; codecs="avc1.42E00D, avc1.640015, avc1.64001E"') !== 'no');
return ios_devices_regex.test(navigator.userAgent) || remaining_devices_regex.test(navigator.userAgent) || enableAndroid || !Constants.PRODUCTION;
};
AppHelper.isSupportedAndroidVerision = function() {
var major, matches, minor;
try {
matches = Constants.ANDROID_VERSION_REGEX.exec(navigator.userAgent);
if (matches.length === 3) {
major = parseInt(matches[1]);
minor = parseInt(matches[2]);
if ((major >= Constants.ANDROID_MIN_MAJOR_VERSION && minor >= Constants.ANDROID_MIN_MINOR_VERSION) || major >= (Constants.ANDROID_MIN_MAJOR_VERSION + 1)) {
return true;
} else {
return false;
}
} else {
return false;
}
} catch (e) {
return false;
}
};
AppHelper.isAndroidVersion2 = function() {
var majorVersion, matches;
try {
matches = Constants.ANDROID_VERSION_REGEX.exec(navigator.userAgent);
if (matches.length === 3) {
majorVersion = parseInt(matches[1]);
return majorVersion === 2;
}
return false;
} catch (e) {
return false;
}
};
AppHelper.showContentOnly = function() {
var content_only_devices, content_only_devices_regex, matches;
try {
matches = Constants.ANDROID_VERSION_REGEX.exec(navigator.userAgent);
content_only_devices = ["Silk"].join("|");
content_only_devices_regex = RegExp("(" + content_only_devices + ")", 'i');
if (content_only_devices_regex.test(navigator.userAgent) || (matches.length === 3 && parseInt(matches[1]) === 2)) {
return true;
} else {
return false;
}
} catch (e) {
return false;
}
};
AppHelper.isPhone = function() {
return !AppHelper.isTablet() && !AppHelper.isConsole();
};
AppHelper.isTablet = function() {
return RegExp("(ipad|Android|Playbook|Silk|BNTV250)", 'i').test(navigator.userAgent) && !RegExp("(Android.*Mobile)", 'i').test(navigator.userAgent);
};
AppHelper.isConsole = function() {
return RegExp("(Xbox)", 'i').test(navigator.userAgent);
};
AppHelper.isFullScreen = function() {
return document.fullScreenElement || document.mozFullScreen || document.webkitIsFullScreen || $('video').get(0).webkitDisplayingFullscreen;
};
AppHelper.posterSize = function(isEmbed) {
if (isEmbed) {
return Constants.EMBED_POSTER_SIZE;
}
return Constants.REGULAR_POSTER_SIZE;
};
AppHelper.getPosterUrl = function(content_id, size, thumbnail_position) {
if (thumbnail_position == null) {
thumbnail_position = null;
}
if (this.thumbnail_position) {
return Constants.BASE_HOST + ("ib.huluim.com/thumb?id=" + content_id + "&s=" + thumbnail_position + "&size=" + size);
} else {
return Constants.BASE_HOST + ("ib.huluim.com/video/" + content_id + "?size=" + size);
}
};
AppHelper.preferredBitrates = function() {
if (AppHelper.isTablet()) {
return Constants.PREFERRED_BITRATES_TABLET;
} else if (AppHelper.isConsole()) {
return Constants.PREFERRED_BITRATES_CONSOLE;
} else {
return Constants.PREFERRED_BITRATES_PHONE;
}
};
AppHelper.preferredBitrate = function() {
var _ref;
return ((_ref = AppHelper.preferredBitrates()) != null ? _ref[0] : void 0) || 200;
};
AppHelper.getUserId = function() {
var value;
value = this.getCookie(Constants.COOKIE_KEYS.HULU_UID);
if (value != null) {
return parseInt(value);
} else {
return -1;
}
};
AppHelper.getUserPgid = function() {
var pgid;
pgid = this.getCookie(Constants.COOKIE_KEYS.HULU_PGID);
if (this.getUserId() > 0 && (pgid != null) && !isNaN(pgid)) {
return parseInt(pgid);
}
return Constants.DEFAULT_PACKAGE_ID;
};
AppHelper.isPlusUser = function() {
var pgid, plusPackageID;
pgid = this.getUserPgid();
plusPackageID = Constants.PLUS_PACKAGE_ID;
return (pgid & plusPackageID) === plusPackageID;
};
AppHelper.createUrl = function(url, params) {
var param_str;
url += (url.indexOf('?') > -1 ? "&" : "?");
param_str = $.param(params);
return "" + url + param_str;
};
return AppHelper;
})();
Constants = (function() {
function Constants() {}
Constants.PRODUCTION = /hulu\.com$/i.test(window.location.host);
Constants.STAGING = /huluqa\.com$/i.test(window.location.host);
Constants.IS_SSL = /^https/i.test(window.location.protocol);
Constants.EMBED = false;
Constants.AD_ZONE = false;
Constants.VERSION = "html5v1.0";
Constants.VIDEO_ASPECT_RATIO = 360 / 640;
Constants.REGULAR_POSTER_SIZE = '640x360';
Constants.EMBED_POSTER_SIZE = '512x288';
Constants.REPLAY_POSTER_SIZE = '220x124';
Constants.TITLE_HEIGHT = 50;
Constants.PLAY_TIMEOUT = 200;
Constants.AD_FREE_PERIOD = 15;
Constants.MP4_DEVICE_ID = 52;
Constants.PLAYLIST_DEVICE_ID = 55;
Constants.DEVICE_ID = AppHelper.isPlaylistCompatible() ? Constants.PLAYLIST_DEVICE_ID : Constants.MP4_DEVICE_ID;
Constants.PREFERRED_BITRATES_PHONE = [200];
Constants.PREFERRED_BITRATES_TABLET = [400];
Constants.PREFERRED_BITRATES_CONSOLE = [1000];
Constants.ANDROID_VERSION_REGEX = /Android\s(\d{1})\.(\d{1}).*;/i;
Constants.ANDROID_MIN_MAJOR_VERSION = 2;
Constants.ANDROID_MIN_MINOR_VERSION = 0;
Constants.UNAVAILABLE_ERROR_MESSAGE = "This video is currently not available in the browser on mobile devices.";
Constants.GEO_BLOCK_MESSAGE = "We're sorry, currently our video library can only be streamed within the United States.";
Constants.DEFAULT_ERROR_MESSAGE = "An error occurred. Please refresh the page.";
Constants.VIDEO_EXPIRED_ERROR_MESSAGE = "D'oh! This video isn't available.<br/><br/>We don't like it when this happens, either, but some videos must be pulled from Hulu from time to time. Don't worry, though. We have plenty of other stuff to watch.";
Constants.STREAM_LOAD_ERROR = "D'oh! This video won't load.<br/><br/>Try reloading this page or checking your Internet connection to see if that helps.";
Constants.STATUS = {
STARTING: 0,
READY: 1,
PLAYING: 2,
PAUSED: 3,
BUFFERING: 4,
DONE: 5
};
Constants.COOKIE_KEYS = {
VISIT: "HULU_VISIT",
AGE_CHECK: "HTML5_AGE_CHECK_",
ERROR_SAMPLE_RATE: "HTML5_ERROR_SAMPLE_RATE",
ADSTATE: "HTML5_ADSTATE",
HULU_GUID: "guid",
HULU_UID: "_hulu_uid",
HULU_PGID: "_hulu_pgid"
};
Constants.BASE_SIMPLE_HOST = (Constants.IS_SSL ? "https://" : "http://");
Constants.BASE_HOST = (Constants.IS_SSL ? "https://a248.e.akamai.net/" : "http://");
Constants.BASE_SITE_HOST = (Constants.IS_SSL ? "https://secure." : "http://www.");
Constants.CONTENT_SELECT_URL = Constants.BASE_HOST + (Constants.PRODUCTION ? "h5.hulu.com/" : "h5.huluqa.com/") + (AppHelper.isPlaylistCompatible() ? "h5.m3u8" : "h5.mp4");
Constants.BEACONS = {
BEACON_PROTOCOL_VERSION: 2,
BEACON_CONFIG_URL: Constants.BASE_SIMPLE_HOST + ("t." + (Constants.PRODUCTION ? "hulu" : "huluqa") + ".com/config/v3/config?distro=hulu&distroplatform=embed&type=json"),
BEACON_TEMPLATE_URL: Constants.PRODUCTION ? "https://play.hulu.com/beacon_definition" : "https://play.huluqa.com/beacon_definition",
TYPES: {
AD_INTERACTION: "adinteraction",
CONTENT_INTERACTION: "contentinteraction",
ERROR: "error",
META: "meta",
PLAYBACK: "playback",
PLAYER_TRACKING: "playertracking",
PLUS_TRACKING: "plustracking",
REVENUE: "revenue",
SESSION: "session"
},
EVENTS: {
CLICK: 'click',
DRIVER_CLICK: 'driverclick',
DRIVER_LOAD: 'driverload',
EMBED: 'embed',
END: 'end',
END_UPSELL: 'endupsell',
END_WATCH_AGAIN: 'endwatchagain',
FULLSCREEN_CLOSE: 'fullscreenclose',
FULLSCREEN_OPEN: 'fullscreenopen',
HTTP_ERROR: 'HTTPError',
IO_ERROR: 'IOError',
IOS_PLAYER_ERROR: "iOSPlayerError",
NET_CONNECTION_CLOSED: "NetConnection.Connect.Closed",
NET_STREAM_FILE_INVALID: "NetStream.Play.FileStructureInvalid",
NET_STREAM_INSUFFICIENT_BW: "NetStream.Play.InsufficientBW",
NET_STREAM_NO_TRACK_SUPPORT: "NetStream.Play.NoSupportedTrackFound",
PAUSE: 'pause',
PLAY: 'play',
PLAYER_LOADED: 'playerloaded',
POSITION: 'position',
SEEK: 'seek',
SHOW_END_CARD: 'showendcard',
START: 'start',
STARTUP: 'startup',
ASSET_IMPRESSION: 'assetimpression'
},
FIRE_TYPES: {
ALWAYS: 'always',
ERROR: 'error',
NEVER: 'never'
}
};
Constants.BEACONS_DEFAULTS = {
REALTIME_HOST: Constants.PRODUCTION ? "t.hulu.com" : "track.qa.hulu.com",
STANDARD_HOST: Constants.PRODUCTION ? "t2.hulu.com" : "t2.huluqa.com",
POD_SLOT_LOOKUP: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
BEACONS: [
{
type: Constants.BEACONS.TYPES.AD_INTERACTION,
event: Constants.BEACONS.EVENTS.CLICK
}, {
type: Constants.BEACONS.TYPES.CONTENT_INTERACTION,
event: Constants.BEACONS.EVENTS.END_WATCH_AGAIN
}, {
type: Constants.BEACONS.TYPES.CONTENT_INTERACTION,
event: Constants.BEACONS.EVENTS.FULLSCREEN_CLOSE
}, {
type: Constants.BEACONS.TYPES.CONTENT_INTERACTION,
event: Constants.BEACONS.EVENTS.FULLSCREEN_OPEN
}, {
type: Constants.BEACONS.TYPES.CONTENT_INTERACTION,
event: Constants.BEACONS.EVENTS.PLAY
}, {
type: Constants.BEACONS.TYPES.CONTENT_INTERACTION,
event: Constants.BEACONS.EVENTS.PAUSE
}, {
type: Constants.BEACONS.TYPES.CONTENT_INTERACTION,
event: Constants.BEACONS.EVENTS.SEEK
}, {
type: Constants.BEACONS.TYPES.CONTENT_INTERACTION,
event: Constants.BEACONS.EVENTS.SHOW_END_CARD
}, {
type: Constants.BEACONS.TYPES.PLAYBACK,
event: Constants.BEACONS.EVENTS.END
}, {
type: Constants.BEACONS.TYPES.PLAYBACK,
event: Constants.BEACONS.EVENTS.POSITION
}, {
type: Constants.BEACONS.TYPES.PLAYBACK,
event: Constants.BEACONS.EVENTS.START
}, {
type: Constants.BEACONS.TYPES.PLAYER_TRACKING,
event: Constants.BEACONS.EVENTS.PLAYER_LOADED
}, {
type: Constants.BEACONS.TYPES.PLUS_TRACKING,
event: Constants.BEACONS.EVENTS.DRIVER_CLICK
}, {
type: Constants.BEACONS.TYPES.PLUS_TRACKING,
event: Constants.BEACONS.EVENTS.DRIVER_LOAD
}, {
type: Constants.BEACONS.TYPES.REVENUE,
event: Constants.BEACONS.EVENTS.END
}, {
type: Constants.BEACONS.TYPES.REVENUE,
event: Constants.BEACONS.EVENTS.POSITION
}, {
type: Constants.BEACONS.TYPES.REVENUE,
event: Constants.BEACONS.EVENTS.START
}, {
type: Constants.BEACONS.TYPES.REVENUE,
event: Constants.BEACONS.EVENTS.ASSET_IMPRESSION
}, {
type: Constants.BEACONS.TYPES.SESSION,
event: Constants.BEACONS.EVENTS.STARTUP
}
]
};
Constants.COMSCORE = {
HOST: (Constants.IS_SSL ? "https://sb" : "http://b") + ".scorecardresearch.com/b",
C1: "1",
CA1: "3",
C2: "3000007",
ADS_C5_PREFIX: "01",
PHONE_PLATFORM_ID: "Mobile Phone HTML5",
TABLET_PLATFORM_ID: "Mobile Tablet HTML5"
};
Constants.NIELSEN = {
HOST: Constants.BASE_SIMPLE_HOST + "secure-us.imrworldwide.com/cgi-bin/m",
QA_CLIENT_ID: "us-502202",
PRODUCTION_CLIENT_ID: "us-600346",
DEFAULT_PRODUCTION_VC_ID: "72"
};
Constants.QOS = {
HOST: "/_qos/playback"
};
Constants.DOPPLER_URLS = Constants.PRODUCTION ? {
ingest: Constants.BASE_SITE_HOST + 'hulu.com/doppler/1.0/ingest?source=huluminus',
status: Constants.BASE_SITE_HOST + 'hulu.com/doppler/1.0/status',
regex: /\/doppler\//i
} : Constants.STAGING ? {
ingest: Constants.BASE_SITE_HOST + 'huluqa.com/doppler/1.0/ingest?source=huluminus',
status: Constants.BASE_SITE_HOST + 'huluqa.com/doppler/1.0/status',
regex: /\/doppler\//i
} : void 0;
Constants.DEFAULT_PACKAGE_ID = 1;
Constants.PLUS_PACKAGE_ID = 3;
Constants.PLUS_UPSELL_BASE_URL = "https://secure." + (Constants.PRODUCTION ? "hulu" : "huluqa") + ".com/plus/mobile/signup?from=mobileclips";
Constants.SMALL_PLAYER_THRESHOLD = 720;
return Constants;
})();
BeaconHelper = (function() {
function BeaconHelper() {}
BeaconHelper.getBeaconEventName = function(type, event) {
return "BeaconController.Events." + type + "_" + event;
};
BeaconHelper.sendBeacons = function(urls) {
var u, _i, _len, _results;
_results = [];
for (_i = 0, _len = urls.length; _i < _len; _i++) {
u = urls[_i];
_results.push(this.sendBeacon(u));
}
return _results;
};
BeaconHelper.sendBeacon = function(url, params) {
if (params == null) {
params = void 0;
}
if (params != null) {
url = AppHelper.createUrl(url, params);
}
return this._pingImage(url);
};
BeaconHelper._pingImage = function(url) {
var img;
img = img = new Image();
img.src = url;
if (img.onerror) {
img.onerror = function() {};
}
if (img.onload) {
img.onload = function() {};
}
return img;
};
BeaconHelper.getBrowserVersion = function() {
if ((typeof $ !== "undefined" && $ !== null ? $.client : void 0) != null) {
return [$.client.browser, $.client.version].join(" ");
}
return window.navigator.appName;
};
BeaconHelper.getDeviceName = function() {
return window.navigator.platform;
};
BeaconHelper.getDeviceOS = function() {
if ((typeof $ !== "undefined" && $ !== null ? $.client : void 0) != null) {
return [$.client.os, $.client.osVersion].join(" ");
}
return window.navigator.platform;
};
return BeaconHelper;
})();
BaseBeaconController = (function() {
function BaseBeaconController() {}
BaseBeaconController.prototype.onAppReady = function() {};
BaseBeaconController.prototype.reset = function() {};
return BaseBeaconController;
})();
HuluBeaconController = (function(_super) {
__extends(HuluBeaconController, _super);
function HuluBeaconController(beacon_controller) {
this.beacon_controller = beacon_controller;
this._initEvents();
this.last_position_beacon_total_time_sent_at = {};
}
HuluBeaconController.prototype.reset = function() {
HuluBeaconController.__super__.reset.call(this);
return this.last_position_beacon_total_time_sent_at = {};
};
HuluBeaconController.prototype._initEvents = function() {
var _this = this;
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.SESSION, Constants.BEACONS.EVENTS.STARTUP), function(event, object) {
_this._fireEventBeacon(Constants.BEACONS.TYPES.META, object, Constants.BEACONS.EVENTS.EMBED);
return _this._fireEventBeacon(Constants.BEACONS.TYPES.SESSION, object, Constants.BEACONS.EVENTS.STARTUP);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.REVENUE, Constants.BEACONS.EVENTS.START), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.REVENUE, object, Constants.BEACONS.EVENTS.START);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.REVENUE, Constants.BEACONS.EVENTS.ASSET_IMPRESSION), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.REVENUE, object, Constants.BEACONS.EVENTS.ASSET_IMPRESSION);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.REVENUE, Constants.BEACONS.EVENTS.END), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.REVENUE, object, Constants.BEACONS.EVENTS.END);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.REVENUE, Constants.BEACONS.EVENTS.POSITION), function(event, data) {
return _this._firePercentBeacons(Constants.BEACONS.TYPES.REVENUE, data.object, data.percent);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.AD_INTERACTION, Constants.BEACONS.EVENTS.CLICK), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.AD_INTERACTION, object, Constants.BEACONS.EVENTS.CLICK);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.START), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.PLAYBACK, object, Constants.BEACONS.EVENTS.START);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.END), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.PLAYBACK, object, Constants.BEACONS.EVENTS.END);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.POSITION), function(event, object) {
return _this._fireTimeBeacon(Constants.BEACONS.TYPES.PLAYBACK, object);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYER_TRACKING, Constants.BEACONS.EVENTS.PLAYER_LOADED), function(event, object) {
return _this._fireNonTemplatedBeacon(Constants.BEACONS.TYPES.PLAYER_TRACKING, object, Constants.BEACONS.EVENTS.PLAYER_LOADED);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLUS_TRACKING, Constants.BEACONS.EVENTS.DRIVER_CLICK), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.PLUS_TRACKING, object, Constants.BEACONS.EVENTS.DRIVER_CLICK);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLUS_TRACKING, Constants.BEACONS.EVENTS.DRIVER_LOAD), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.PLUS_TRACKING, object, Constants.BEACONS.EVENTS.DRIVER_LOAD);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.END_UPSELL), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.CONTENT_INTERACTION, object, Constants.BEACONS.EVENTS.END_UPSELL);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.END_WATCH_AGAIN), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.CONTENT_INTERACTION, object, Constants.BEACONS.EVENTS.END_WATCH_AGAIN);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.FULLSCREEN_CLOSE), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.CONTENT_INTERACTION, object, Constants.BEACONS.EVENTS.FULLSCREEN_CLOSE);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.FULLSCREEN_OPEN), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.CONTENT_INTERACTION, object, Constants.BEACONS.EVENTS.FULLSCREEN_OPEN);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.PLAY), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.CONTENT_INTERACTION, object, Constants.BEACONS.EVENTS.PLAY);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.PAUSE), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.CONTENT_INTERACTION, object, Constants.BEACONS.EVENTS.PAUSE);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.SEEK), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.CONTENT_INTERACTION, object, Constants.BEACONS.EVENTS.SEEK);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.SHOW_END_CARD), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.CONTENT_INTERACTION, object, Constants.BEACONS.EVENTS.SHOW_END_CARD);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, Constants.BEACONS.EVENTS.HTTP_ERROR), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.ERROR, object, Constants.BEACONS.EVENTS.HTTP_ERROR);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, Constants.BEACONS.EVENTS.IO_ERROR), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.ERROR, object, Constants.BEACONS.EVENTS.IO_ERROR);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, Constants.BEACONS.EVENTS.NET_CONNECTION_CLOSED), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.ERROR, object, Constants.BEACONS.EVENTS.NET_CONNECTION_CLOSED);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, Constants.BEACONS.EVENTS.NET_STREAM_INSUFFICIENT_BW), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.ERROR, object, Constants.BEACONS.EVENTS.NET_STREAM_INSUFFICIENT_BW);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, Constants.BEACONS.EVENTS.NET_STREAM_FILE_INVALID), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.ERROR, object, Constants.BEACONS.EVENTS.NET_STREAM_FILE_INVALID);
});
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, Constants.BEACONS.EVENTS.NET_STREAM_NO_TRACK_SUPPORT), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.ERROR, object, Constants.BEACONS.EVENTS.NET_STREAM_NO_TRACK_SUPPORT);
});
return EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, Constants.BEACONS.EVENTS.IOS_PLAYER_ERROR), function(event, object) {
return _this._fireEventBeacon(Constants.BEACONS.TYPES.ERROR, object, Constants.BEACONS.EVENTS.IOS_PLAYER_ERROR);
});
};
HuluBeaconController.prototype._fireEventBeacon = function(type, object, event) {
var urls;
urls = this._buildUrls(type, event, object);
if (((object != null ? object.specificParams : void 0) != null) && urls.length > 0) {
urls[0] = AppHelper.createUrl(urls[0], object.specificParams);
}
return BeaconHelper.sendBeacons(urls);
};
HuluBeaconController.prototype._fireNonTemplatedBeacon = function(type, object, event) {
var baseUrl, cmc, param, params, _i, _len, _ref;
baseUrl = "" + (this.beacon_controller.getParam("beacon_endpoint")) + "/" + type + "/" + event;
params = {
beaconevent: event
};
_ref = ["cb", "client", "computerguid", "device_id", "distro", "distro_platform", "os", "player", "region"];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
param = _ref[_i];
params[param.replace("_", "")] = this.beacon_controller.getParam(param);
}
cmc = this.beacon_controller.getParam("cmc");
if ((cmc != null) && cmc !== "") {
params["cmc"] = cmc;
}
return BeaconHelper.sendBeacon(baseUrl, params);
};
HuluBeaconController.prototype._fireTimeBeacon = function(type, object) {
var send_cutoff, time_since_last_position_beacon, urls;
time_since_last_position_beacon = object.total_time_playing - this._getLastPositionBeaconTotalTimeSentAt(object.getID());
send_cutoff = object.total_time_playing >= 3 * 60 ? 3 * 60 : 30;
if (time_since_last_position_beacon >= send_cutoff) {
urls = this._buildUrls(type, Constants.BEACONS.EVENTS.POSITION, object);
BeaconHelper.sendBeacons(urls);
return this._setLastPositionBeaconTotalTimeSentAt(object.getID(), object.total_time_playing);
}
};
HuluBeaconController.prototype._firePercentBeacons = function(type, object, percent) {
var should_fire, urls;
should_fire = this.beacon_controller.getShouldFire(type, Constants.BEACONS.EVENTS.POSITION);
if (should_fire === Constants.BEACONS.FIRE_TYPES.ALWAYS) {
urls = this._buildUrls(type, Constants.BEACONS.EVENTS.POSITION, object);
BeaconHelper.sendBeacons(urls);
return this._setLastPositionBeaconTotalTimeSentAt(object.getID(), object.total_time_playing);
}
};
HuluBeaconController.prototype._buildUrls = function(type, event, object) {
var t, templates, urls, _i, _len;
urls = [];
templates = this.beacon_controller.getTemplates(type, event) || [];
for (_i = 0, _len = templates.length; _i < _len; _i++) {
t = templates[_i];
urls.push(this._processTemplate(t, type, event, object));
}
return urls;
};
HuluBeaconController.prototype._processTemplate = function(template, type, event, object) {
var result, tokenPattern,
_this = this;
tokenPattern = /\{([0-9a-z\_\!]+)\}/g;
result = template.replace(tokenPattern, function(match, text, urlId) {
var templateName;
if (text[0] === '!') {
templateName = text.slice(1);
return _this._processTemplate(_this.beacon_controller.getTemplate(templateName), type, event, object);
}
return _this._getParam(text, object, type, event);
});
return result;
};
HuluBeaconController.prototype._getParam = function(name, object, type, event) {
var value;
switch (name) {
case 'watched':
return AppHelper.toMilliseconds(object.total_time_playing - this._getLastPositionBeaconTotalTimeSentAt(object.getID()));
case 'beacon_type':
return type;
case 'beacon_event':
return event;
default:
value = this.beacon_controller.getParam(name, object);
if (!(name === 'beacon_endpoint' || name === 'realtime_beacon_endpoint' || name === 'donut_params' || name === 'r1' || name === 'r2' || name === 'c1' || name === 'c2')) {
value = AppHelper.encode(value);
}
return value;
}
};
HuluBeaconController.prototype._setLastPositionBeaconTotalTimeSentAt = function(object_id, time) {
return this.last_position_beacon_total_time_sent_at[object_id] = time;
};
HuluBeaconController.prototype._getLastPositionBeaconTotalTimeSentAt = function(object_id) {
if (this.last_position_beacon_total_time_sent_at[object_id] === void 0) {
this.last_position_beacon_total_time_sent_at[object_id] = 0;
}
return this.last_position_beacon_total_time_sent_at[object_id];
};
return HuluBeaconController;
})(BaseBeaconController);
Ui = (function() {
function Ui(app_model, element) {
this.app_model = app_model;
this.element = $(element);
this._buildHTML();
if (this.app_model.isEmbed()) {
this.element.addClass('embed');
}
if (this.app_model.getPartner() != null) {
$('.partner-bug').addClass(this.app_model.getPartner().toLowerCase());
}
this._adjustDimensions();
}
Ui.prototype._buildHTML = function() {
return this.element.html('<div id="html5player">\
<div id="html5-player-container">\
<div class="container">\
<div class="video-holder">\
<div class="player" id="main-player">\
<video class="video-player" webkit-playsinline></video>\
<div class="top-bars-container">\
<div class="ad-top-bar">\
<div class="bar-info">\
<span class="ad-count">Ad <span class="ad-num"></span> of <span class="ad-num-total"></span></span>\
<span class="ad-time"><span class="ad-seconds"></span> seconds</span>\
</div>\
</div>\
</div>\
<div class="cards-container">\
<div class="card error-card">\
<div class="scrim"></div>\
<div class="error-info">\
<div class="error-message"></div>\
</div>\
</div>\
<div class="card start-play-card">\
<div class="start-play-btn"></div>\
<div class="ui-elements">\
<div class="table">\
<div class="program-info">\
<span class="show-name"></span>\
<span class="episode-name"></span>\
</div>\
</div>\
</div>\
</div>\
<div class="card end-card"></div>\
<img class="card poster" />\
<div class="card loading-card"></div>\
<div class="card age-gate-card" style="display: none"></div>\
<div class="card paused-card"> \
<div class="start-play-btn"></div>\
<div class="scrim"></div>\
<div class="card-info">\
<div class="pre">You are watching</div>\
<div class="program-info">\
<span class="show-name"></span>\
<span class="episode-name"></span>\
</div>\
<div class="time-remaining"></div>\
</div>\
</div>\
</div>\
<div class="bug partner-bug"></div>\
<div class="bug network-bug"></div>\
<div class="controls-container" id="main-controls">\
<div class="crystal-tray"></div>\
<div class="controls-bar">\
<div class="controls">\
<div class="controls-row">\
<div class="control-bar-button pause-btn"></div>\
<div class="seekbar-container">\
<div class="seekbar">\
<div class="current-bar"></div>\
<div class="breaks-holder">\
<div class="break-dot"></div>\
</div>\
</div>\
</div>\
<div class="time-remaining">00:00</div>\
<div class="control-bar-button fullscreen-btn"></div>\
</div>\
</div>\
</div>\
</div>\
<div class="bug hulu-bug"></div>\
</div>\
</div>\
</div>\
</div>\
</div>');
};
Ui.prototype._adjustDimensions = function(width, height) {
var targetHeight, targetWidth, _ref, _ref1;
this.element.width('');
if (!((width != null) && (height != null))) {
width = width || this.element.width();
if (width <= 0) {
width = $(window).width();
}
height = height || $(window).height();
if (!this.app_model.isAdZone() && $('.video-meta').length > 0 && !(typeof Hulu !== "undefined" && Hulu !== null ? (_ref = Hulu.Utils) != null ? (_ref1 = _ref.DOM) != null ? _ref1.isInViewVertically($('.video-meta')) : void 0 : void 0 : void 0)) {
height -= $('.video-meta').height();
}
targetHeight = width * Constants.VIDEO_ASPECT_RATIO;
targetWidth = height / Constants.VIDEO_ASPECT_RATIO;
if (targetHeight < height) {
height = targetHeight;
} else {
width = targetWidth;
}
}
if (!this.app_model.isEmbed()) {
if (width >= Constants.SMALL_PLAYER_THRESHOLD && !this.element.hasClass('large-player')) {
this.element.addClass('large-player');
} else if (width < Constants.SMALL_PLAYER_THRESHOLD && this.element.hasClass('large-player')) {
this.element.removeClass('large-player');
}
}
this.element.width(width);
this.element.height(height);
if ($('#video-description').length > 0) {
try {
if ($('.desc-left').length > 0) {
$('.desc-left').width(width);
}
if ($('.player-width').length > 0) {
$('.player-width').width(width);
}
} catch (e) {
}
}
return true;
};
Ui.prototype.changePlayerSize = function(width, height) {
return this._adjustDimensions(width, height);
};
return Ui;
})();
NielsenBeaconController = (function(_super) {
__extends(NielsenBeaconController, _super);
function NielsenBeaconController(beacon_controller) {
this.beacon_controller = beacon_controller;
this._initEvents();
}
NielsenBeaconController.prototype._initEvents = function() {
var _this = this;
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.START), function(event, object) {
return _this._fireBeacon(true, object);
});
return EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.END), function(event, object) {
return _this._fireBeacon(false, object);
});
};
NielsenBeaconController.prototype._fireBeacon = function(for_start, current_model) {
var params;
params = this._getParams(for_start, current_model);
return BeaconHelper.sendBeacon(Constants.NIELSEN.HOST, params);
};
NielsenBeaconController.prototype._getParams = function(for_start, current_model) {
var ad_var, cp_identifier, episode, params, pscnc_id, season_number, secondary_site_channel_nielsen_id, start_num, title;
params = {
cg: AppHelper.encode(this.beacon_controller.getParam('series_title')),
cc: 1,
c4: "mn," + this.beacon_controller.getParam('dp_nielsen_channel_id'),
c9: "pv," + this.beacon_controller.getParam('distro_platform'),
c7: "hg," + this.beacon_controller.getParam('computerguid')
};
pscnc_id = this.beacon_controller.getParam('primary_site_channel_nielsen_channel_id');
pscnc_id = pscnc_id === void 0 ? Constants.NIELSEN.DEFAULT_PRODUCTION_VC_ID : pscnc_id;
params.c6 = "vc,c" + pscnc_id;
title = this.beacon_controller.getParam('series_title');
start_num = for_start ? "0" : "2";
cp_identifier = this.beacon_controller.getParam('cp_identifier');
season_number = this.beacon_controller.getParam('season_number');
episode = this.beacon_controller.getParam('episode_number');
ad_var = this.beacon_controller.getParam('break_count') ? "|sf" : "|lf";
params.tl = AppHelper.encode("dav" + start_num + "-%5B" + cp_identifier + "%5D" + title + "_" + season_number + "_" + episode + ad_var);
secondary_site_channel_nielsen_id = this.beacon_controller.getParam('secondary_site_channel_nielsen_id');
if (!(secondary_site_channel_nielsen_id != null)) {
params.c5 = "gn," + secondary_site_channel_nielsen_id;
}
params.ci = Constants.PRODUCTION ? Constants.NIELSEN.PRODUCTION_CLIENT_ID : Constants.NIELSEN.QA_CLIENT_ID;
params.rnd = this.beacon_controller.getParam('cb');
return params;
};
return NielsenBeaconController;
})(BaseBeaconController);
QOSBeaconController = (function(_super) {
__extends(QOSBeaconController, _super);
function QOSBeaconController(beacon_controller) {
this.beacon_controller = beacon_controller;
this._initEvents();
this.reset();
}
QOSBeaconController.prototype.onAppReady = function() {
QOSBeaconController.__super__.onAppReady.call(this);
return this._loaded_time = new Date().getTime();
};
QOSBeaconController.prototype.reset = function() {
QOSBeaconController.__super__.reset.call(this);
this._start_time = new Date().getTime();
return this.last_position_beacon_time_sent = 0;
};
QOSBeaconController.prototype._initEvents = function() {
var _this = this;
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.POSITION), function(event, object) {
return _this._fireBeacon(false, object);
});
return EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.END), function(event, object) {
return _this._fireBeacon(true, object);
});
};
QOSBeaconController.prototype._fireBeacon = function(finished, object) {
var params, time_since_last_position_beacon;
try {
time_since_last_position_beacon = object.total_time_playing - this.last_position_beacon_time_sent;
if (this.last_position_beacon_time_sent === 0 || finished || time_since_last_position_beacon >= 3 * 60) {
params = this._buildParams(finished, object);
this.last_position_beacon_time_sent = object.total_time_playing;
return $.post(Constants.QOS.HOST, params, function() {});
}
} catch (e) {
}
};
QOSBeaconController.prototype._buildParams = function(finished, object) {
var data;
data = {
"session": this.beacon_controller.getParam('sessionguid'),
"distro": this.beacon_controller.getParam('distro'),
"distro_platform": this.beacon_controller.getParam('distro_platform'),
"region": "US",
"content_id": this.beacon_controller.getParam('content_id'),
"series_title": this.beacon_controller.getParam('series_title'),
"user_id": this.beacon_controller.getParam('user_id'),
"plan_id": this.beacon_controller.getParam('plan_id'),
"device_id": this.beacon_controller.getParam('computerguid'),
"dj_device_id": Constants.DEVICE_ID,
"player_version": Constants.VERSION,
"os": this.beacon_controller.getParam('os'),
"client": this.beacon_controller.getParam('oem'),
"player_loading_time": this._loaded_time - this._start_time,
"playback_finished": finished,
"error_messages": ["content_access_restricted", "device_access_restricted", "playback_error"],
"ad_metrics": {
"total_duration": this.beacon_controller.getParam('total_ad_duration'),
"loading_failed_count": 0,
"playback_failed_count": 0,
"dropped_frame_count": 0,
"cdns": [
{
"cdn": "akamai",
"played_ad_count": 0,
"playback_duration": 0,
"time_weighted_bitrate": 0,
"time_weighted_bandwidth": 0,
"loading_time": 0,
"loading_error_count": 0,
"playback_error_count": 0,
"buffering_count": 0,
"buffering_duration": 0,
"buffering_timeout_count": 0,
"skip_count": 1,
"skip_length": 0,
"seek_count": 0,
"seek_duration": 0,
"seek_timeout_count": 0
}
]
},
"content_metrics": {
"total_duration": this.beacon_controller.getParam('content_duration'),
"loading_failed_count": 0,
"playback_failed_count": 0,
"dropped_frame_count": 0,
"cdns": [
{
"cdn": "akamai",
"played_ad_count": 0,
"playback_duration": 0,
"time_weighted_bitrate": 0,
"time_weighted_bandwidth": 0,
"loading_time": 0,
"loading_error_count": 0,
"playback_error_count": 3,
"buffering_count": this.beacon_controller.getParam('buffer_count'),
"buffering_duration": this.beacon_controller.getParam('buffer_time'),
"buffering_timeout_count": 0,
"skip_count": 1,
"skip_length": 0,
"seek_count": 2,
"seek_duration": 0,
"seek_timeout_count": 0
}
]
}
};
return $.toJSON(data);
};
return QOSBeaconController;
})(BaseBeaconController);
ComscoreBeaconController = (function(_super) {
__extends(ComscoreBeaconController, _super);
function ComscoreBeaconController(beacon_controller) {
this.beacon_controller = beacon_controller;
this._initEvents();
}
ComscoreBeaconController.prototype._initEvents = function() {
var _this = this;
EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.REVENUE, Constants.BEACONS.EVENTS.START), function(event, object) {
return _this._fireBeacon(false, object);
});
return EventBus.on(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.START), function(event, object) {
return _this._fireBeacon(true, object);
});
};
ComscoreBeaconController.prototype._fireBeacon = function(for_content, current_model) {
var params, url;
params = this._getParams(for_content, current_model);
url = this._buildUrl(params);
return BeaconHelper.sendBeacon(url);
};
ComscoreBeaconController.prototype._buildUrl = function(params) {
var k, keys, parts, url, _i, _len;
keys = ((function() {
var _results;
_results = [];
for (k in params) {
_results.push(k);
}
return _results;
})()).sort(this._comScoreBeaconParamComparator);
url = "" + Constants.COMSCORE.HOST + "?";
parts = [];
for (_i = 0, _len = keys.length; _i < _len; _i++) {
k = keys[_i];
parts.push("" + k + "=" + params[k]);
}
url += parts.join("&");
return url;
};
ComscoreBeaconController.prototype._comScoreBeaconParamComparator = function(a, b) {
var aParams, alphaComparison, bParams, numericParamRegex;
numericParamRegex = /^(.*?)(\d+)$/i;
aParams = numericParamRegex.exec(a);
bParams = numericParamRegex.exec(b);
if ((aParams != null) && (bParams != null)) {
alphaComparison = aParams[1].localeCompare(bParams[1]);
if (alphaComparison !== 0) {
return alphaComparison;
}
return parseInt(aParams[2]) - parseInt(bParams[2]);
} else if (!(aParams != null) && (bParams != null)) {
return 1;
} else if ((aParams != null) && !(bParams != null)) {
return -1;
}
return a.localeCompare(b);
};
ComscoreBeaconController.prototype._getParams = function(for_content, current_model) {
var episode, param, primary_channel;
episode = this.beacon_controller.getParam('episode_number');
param = {
c1: Constants.COMSCORE.C1,
c2: Constants.COMSCORE.C2,
c3: this.beacon_controller.getParam('cp_comscore_id') === "None" ? "" : this.beacon_controller.getParam('cp_comscore_id'),
c4: this.beacon_controller.getParam('dp_comscore_id'),
c5: this._getSiteChannelComscoreId(!for_content),
c6: AppHelper.encode(this.beacon_controller.getParam('series_title')) + (episode <= 0 ? "" : "--" + episode),
c14: this.beacon_controller.app_model.getDistroPlatform(),
rn: Math.floor(Math.random() * 100000000)
};
if (for_content) {
param.c10 = current_model.getCurrentSegment() + "-" + current_model.getTotalSegments();
} else {
primary_channel = this.beacon_controller.getParam('primary_channel');
param.ca1 = Constants.COMSCORE.CA1;
param.ca2 = Constants.COMSCORE.C2;
param.ca3 = current_model.flight_id;
param.ca4 = current_model.ad_unit_id;
param.ca5 = primary_channel === void 0 || primary_channel === "" ? "" : primary_channel;
}
if (this.beacon_controller.getParam('user_id') > 0) {
param.c13 = this.beacon_controller.getParam('computerguid');
param.c15 = this.beacon_controller.getParam('hashed_user_id');
param.c16 = AppHelper.isPlusUser() ? 1 : 0;
}
return param;
};
ComscoreBeaconController.prototype._getSiteChannelComscoreId = function(forAd) {
var ad_model, site_channel;
site_channel = this.beacon_controller.getParam('site_channel_comscore_id');
ad_model = this.beacon_controller.getParam('ad_model');
if (site_channel === void 0 || site_channel === "") {
return "";
}
if (forAd) {
return Constants.COMSCORE.ADS_C5_PREFIX + site_channel;
}
if (this.beacon_controller.getParam('is_web')) {
if (ad_model !== null && ad_model.toLowerCase() === "shortform") {
return "04" + site_channel;
} else {
return "05" + site_channel;
}
} else {
if (ad_model !== null && ad_model.toLowerCase() === "shortform") {
return "02" + site_channel;
} else {
return "03" + site_channel;
}
}
};
return ComscoreBeaconController;
})(BaseBeaconController);
BeaconModel = (function() {
function BeaconModel(app_model, player_model) {
this.app_model = app_model;
this.player_model = player_model;
this.templates = void 0;
this.types = void 0;
this.should_fire = {};
this.standard_host = Constants.BEACONS_DEFAULTS.STANDARD_HOST;
this.realtime_host = Constants.BEACONS_DEFAULTS.REALTIME_HOST;
}
BeaconModel.prototype.parseBeaconTemplate = function(data) {
var k, name, obj, template, v, value, _ref, _ref1;
this.templates = data['templates'];
this.types = data['types'];
_ref = this.types;
for (obj in _ref) {
value = _ref[obj];
for (k in value) {
v = value[k];
if (k === 'templates') {
for (name in v) {
template = v[name];
this.templates[name] = template;
}
}
}
}
if (((_ref1 = this.templates) != null ? _ref1['standard'] : void 0) != null) {
this.templates['standard'] += "&orientation={orientation}&socialidentities={social_identities}&siteversion={site_version}{donut_params}";
}
return $(this).trigger(BeaconModel.Events.ProcessTemplateDone);
};
BeaconModel.prototype.parseBeaconConfig = function(data) {
var realtime, standard;
realtime = data['beacons']['realtime'];
this.realtime_cdn_hosts = realtime['cdn-hosts'];
this.realtime_host = realtime['host'];
this._processBeacons(realtime['beacon']);
standard = data['beacons']['standard'];
this.standard_host = standard['host'];
this._processBeacons(standard['beacon']);
return $(this).trigger(BeaconModel.Events.ProcessConfigDone);
};
BeaconModel.prototype._processBeacons = function(beacons) {
var b, e, _i, _len, _results;
_results = [];
for (_i = 0, _len = beacons.length; _i < _len; _i++) {
b = beacons[_i];
this.setShouldFireType(b['type'], b['send']);
if (b['event']) {
_results.push((function() {
var _j, _len1, _ref, _results1;
_ref = b['event'];
_results1 = [];
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
e = _ref[_j];
_results1.push(this.setShouldFire(b['type'], e.name, e.send));
}
return _results1;
}).call(this));
} else {
_results.push(void 0);
}
}
return _results;
};
BeaconModel.prototype.getTemplates = function(type, event) {
var template, _ref, _ref1, _ref2;
template = (_ref = this.types) != null ? (_ref1 = _ref[type]) != null ? (_ref2 = _ref1['events']) != null ? _ref2[event] : void 0 : void 0 : void 0;
if (template != null) {
return template;
} else if (this.getShouldFire(type, event) === Constants.BEACONS.FIRE_TYPES.ALWAYS) {
return ["{!standard}"];
} else if (!Constants.PRODUCTION) {
return Logger.error('BeaconModel.Errors.EventNotDefined type: ' + type + ' event: ' + event);
}
};
BeaconModel.prototype.getTemplate = function(name) {
return (this.templates || BeaconModel.default_template)[name];
};
BeaconModel.prototype.getParam = function(name, object) {
var key, value, values, _ref, _ref1, _ref2, _ref3;
if (object == null) {
object = {};
}
switch (name) {
case 'beacon_endpoint':
return Constants.BASE_HOST + ("" + this.standard_host + "/v3");
case 'realtime_beacon_endpoint':
return Constants.BASE_SIMPLE_HOST + ("" + this.realtime_host + "/beacon/v3");
case 'cmc':
return AppModel.CONTENT_MARKETING_CAMPAIGN;
case 'device_id':
return Constants.DEVICE_ID;
case 'distro':
return this.app_model.getBeaconDistro();
case 'distro_platform':
return this.app_model.getDistroPlatform();
case 'ad_type':
return object.ad_unit_type;
case 'annotation_enabled':
return "false";
case 'client':
return BeaconHelper.getBrowserVersion();
case 'pod':
return object.pod_text;
case 'language':
return 'en';
case 'oem':
return BeaconHelper.getDeviceName();
case 'os':
return BeaconHelper.getDeviceOS();
case 'player':
return Constants.VERSION;
case 'region':
return "US";
case 'swapped_in':
return "0";
case 'position':
return AppHelper.toMilliseconds(object.position);
case 'url':
case 'page_url':
return window.location.href;
case 'referrer_url':
return this.app_model.getReferralURL();
case 'embed':
return this.app_model.getEmbedURL();
case 'plan_id':
return this.app_model.getPlanID();
case 'user_id':
return this.app_model.getUserID();
case 'sessionguid':
return this.app_model.getSessionGUID();
case 'computerguid':
return this.app_model.getComputerGUID();
case 'site_session_id':
return this.app_model.getSiteSessionID();
case 'status':
return AppModel.PLAYER_STATUS;
case 'bitrate':
return this.player_model.getBitrate();
case 'visit':
return this.app_model.getVisit();
case 'seq':
return AppModel.BEACON_COUNTER++;
case 'fullscreen':
return AppHelper.isFullScreen();
case 'player_mode':
return this.player_model.getPlayerMode();
case 'auth':
case 'ad_start_volume':
case 'adtargeting_userinfo':
case 'swappable_options':
case 'flash':
case 'fms_server':
return "";
case 'cb':
return AppHelper.cacheBuster();
case 'social_identities':
return this.app_model.getSocialIdentities();
case 'site_version':
return this.app_model.getSiteVersion();
case 'r1':
case 'r2':
case 'c1':
case 'c2':
return this.app_model.getTrackingSource(name);
case 'donut_params':
return this.app_model.getDonutParams();
case 'orientation':
return this.app_model.getOrientation();
}
_ref = this.app_model.server_beacons;
for (key in _ref) {
values = _ref[key];
if (values[name]) {
return values[name];
}
}
_ref1 = this.app_model.server_beacons;
for (key in _ref1) {
value = _ref1[key];
if (name === key) {
return value;
}
}
if (object.server_beacons) {
_ref2 = object.server_beacons;
for (key in _ref2) {
values = _ref2[key];
if (values[name] && name !== 'pod') {
return values[name];
}
}
_ref3 = object.server_beacons;
for (key in _ref3) {
value = _ref3[key];
if (name === key && name !== 'pod') {
return value;
}
}
}
if (this[name] !== void 0) {
return this[name];
}
if (this.app_model[name] !== void 0) {
return this.app_model[name];
}
if (this.player_model[name] != null) {
return this.player_model[name];
}
Logger.warn(["unable to find beacon template parameter ", name]);
return "";
};
BeaconModel.prototype.setShouldFireType = function(type, fire) {
var e, _results;
_results = [];
for (e in this.should_fire[type]) {
_results.push(this.setShouldFire(type, e, fire));
}
return _results;
};
BeaconModel.prototype.setShouldFire = function(type, event, fire) {
if (!this.should_fire[type]) {
this.should_fire[type] = {};
}
return this.should_fire[type][event] = fire;
};
BeaconModel.prototype.getShouldFire = function(type, event) {
if (this.should_fire[type] && this.should_fire[type][event]) {
return this.should_fire[type][event];
}
Logger.warn(["Beacon type/event not found", type, event]);
return Constants.BEACONS.FIRE_TYPES.ALWAYS;
};
BeaconModel.Events = {
ProcessConfigDone: "BeaconModel.Events.ProcessConfigDone",
ProcessTemplateDone: "BeaconModel.Events.ProcessTemplateDone"
};
BeaconModel.Errors = {
EventNotDefined: "BeaconModel.Errors.EventNotDefined"
};
BeaconModel.default_template = {
"standard": "{beacon_endpoint}/{beacon_type}/{beacon_event}?annotationenabled={annotation_enabled}&auth={auth}&bitrate={bitrate}&beaconevent={beacon_event}&cb={cb}&cdn={cdn}&client={client}&computerguid={computerguid}&contentid={content_id}&cpidentifier={cp_identifier}&deviceid={device_id}&distro={distro}&distroplatform={distro_platform}&language={language}&embedurl={embed}&oem={oem}&os={os}&packageavailability={package_availability}&packageid={package_id}&planid={plan_id}&player={player}&playermode={player_mode}&fullscreen={fullscreen}&position={position}&region={region}&sessionguid={sessionguid}&sitesessionid={site_session_id}&userid={user_id}&visit={visit}&seq={seq}&referrerurl={referrer_url}&r1={r1}&r2={r2}&c1={c1}&c2={c2}&orientation={orientation}&socialidentities={social_identities}&siteversion={site_version}{donut_params}"
};
return BeaconModel;
})();
PlayableModel = (function() {
function PlayableModel(duration, can_seek) {
this.duration = duration;
this.can_seek = can_seek;
this.id = AppHelper.generateGUID();
this.reset();
}
PlayableModel.prototype.getPlayInfo = function(preferred_bitrates) {
var available_urls, lower, most_preferred_bitrate, next_best_available, preferred_bitrate, rate, sorted_bitrates, upper, url, x, _i, _len, _ref;
available_urls = {};
_ref = this.urls;
for (rate in _ref) {
url = _ref[rate];
available_urls[rate.substring(5)] = url;
}
for (_i = 0, _len = preferred_bitrates.length; _i < _len; _i++) {
preferred_bitrate = preferred_bitrates[_i];
if (available_urls[preferred_bitrate] != null) {
return [preferred_bitrate, available_urls[preferred_bitrate], this.position];
}
}
most_preferred_bitrate = preferred_bitrates[0];
if (most_preferred_bitrate != null) {
sorted_bitrates = ((function() {
var _results;
_results = [];
for (rate in available_urls) {
url = available_urls[rate];
_results.push([parseInt(rate), url]);
}
return _results;
})()).sort(function(a, b) {
if (a[0] < b[0]) {
return -1;
} else if (a[0] > b[0]) {
return 1;
} else {
return 0;
}
});
lower = ((function() {
var _j, _len1, _results;
_results = [];
for (_j = 0, _len1 = sorted_bitrates.length; _j < _len1; _j++) {
x = sorted_bitrates[_j];
if (x[0] <= most_preferred_bitrate) {
_results.push(x);
}
}
return _results;
})()).reverse();
upper = (function() {
var _j, _len1, _results;
_results = [];
for (_j = 0, _len1 = sorted_bitrates.length; _j < _len1; _j++) {
x = sorted_bitrates[_j];
if (x[0] > most_preferred_bitrate) {
_results.push(x);
}
}
return _results;
})();
next_best_available = lower.concat(upper)[0];
if (next_best_available != null) {
return [next_best_available[0], next_best_available[1], this.position];
}
}
return [];
};
PlayableModel.prototype.reset = function() {
this.played = false;
this.position = 0;
return this.total_time_playing = 0;
};
PlayableModel.prototype.timeUpdate = function(position, update_total) {
var last_position;
if (update_total == null) {
update_total = true;
}
last_position = this.position;
this.position = position;
if (update_total) {
return this.total_time_playing += this.position - last_position;
}
};
PlayableModel.prototype.playStarted = function() {};
PlayableModel.prototype.finishedPlaying = function() {
return this.played = true;
};
PlayableModel.prototype.getPosition = function() {
return this.position;
};
PlayableModel.prototype.setPosition = function(position) {
return this.position = position;
};
PlayableModel.prototype.getDuration = function() {
return this.duration;
};
PlayableModel.prototype.getTimeRemaining = function() {
return this.getDuration() - this.getPosition();
};
PlayableModel.prototype.getID = function() {
return this.id;
};
PlayableModel.prototype.toString = function() {
return this.id;
};
PlayableModel.prototype.markPlayed = function() {
return this.played = true;
};
PlayableModel.prototype.markUnplayed = function() {
return this.played = false;
};
PlayableModel.Events = {
UpdateAdTopBar: "PlayableModel.Events.UpdateAdTopBar"
};
return PlayableModel;
})();
BeaconController = (function() {
function BeaconController(app_model, player_model) {
this.app_model = app_model;
this.player_model = player_model;
this._beaconTemplateError = __bind(this._beaconTemplateError, this);
this._checkReady = __bind(this._checkReady, this);
this.beacon_model = new BeaconModel(this.app_model, this.player_model);
this._loadBoaconTemplate();
this._loadBeaconConfig();
this.hulu_beacon_controller = new HuluBeaconController(this);
this.qos_beacon_controller = new QOSBeaconController(this);
this.comscore_beacon_controller = new ComscoreBeaconController(this);
this.nielsen_beacon_controller = new NielsenBeaconController(this);
this._check_ready_timer = AppHelper.setInterval(100, this._checkReady);
this._content_process_ready = false;
this._template_process_ready = false;
this._config_process_ready = false;
}
BeaconController.prototype._checkReady = function() {
if (this._content_process_ready && this._template_process_ready && this._config_process_ready) {
$(this).trigger(BeaconController.Events.Ready);
return clearInterval(this._check_ready_timer);
}
};
BeaconController.prototype.onAppReady = function() {
this.hulu_beacon_controller.onAppReady();
this.qos_beacon_controller.onAppReady();
this.comscore_beacon_controller.onAppReady();
return this.nielsen_beacon_controller.onAppReady();
};
BeaconController.prototype.reset = function() {
this.hulu_beacon_controller.reset();
this.qos_beacon_controller.reset();
this.comscore_beacon_controller.reset();
return this.nielsen_beacon_controller.reset();
};
BeaconController.prototype.processContentResponse = function(data) {
this.beacon_model.cp_comscore_id = data['tp_comScoreId'];
this.beacon_model.dp_comscore_id = data['tp_distributionPartnerComScoreId'];
this.beacon_model.dp_nielsen_channel_id = data['tp_distributionPartnerNielsenId'];
this.beacon_model.cp_identifier = data['cp_identifier'];
this.beacon_model.site_channel_comscore_id = data['tp_siteChannelComScoreId'];
this.beacon_model.primary_site_channel_nielsen_channel_id = data['tp_primarySiteChannelNielsenChannelId'];
this.beacon_model.secondary_site_channel_nielsen_id = data['tp_secondarySiteChannelNielsenId'];
this.beacon_model.is_web = data['tp_isWeb'];
this.beacon_model.ad_model = data['tp_Ad_Model'];
this.beacon_model.primary_channel = data['tp_siteChannelPrimary'];
this.beacon_model.break_count = data['breaks'].length;
this.beacon_model.hashed_user_id = data['tp_hashedUserId'];
return this._content_process_ready = true;
};
BeaconController.prototype.getParam = function(name, object) {
return this.beacon_model.getParam(name, object);
};
BeaconController.prototype.getTemplates = function(type, event) {
return this.beacon_model.getTemplates(type, event);
};
BeaconController.prototype.getTemplate = function(name) {
return this.beacon_model.getTemplate(name);
};
BeaconController.prototype.getShouldFire = function(type, event) {
return this.beacon_model.getShouldFire(type, event);
};
BeaconController.prototype._loadBoaconTemplate = function() {
var _this = this;
$(this.beacon_model).one(BeaconModel.Events.ProcessTemplateDone, function() {
return _this._template_process_ready = true;
});
return AppHelper.getJSON(Constants.BEACONS.BEACON_TEMPLATE_URL + "?beacon_protocol_version=" + Constants.BEACONS.BEACON_PROTOCOL_VERSION, {}, function(data) {
return _this.beacon_model.parseBeaconTemplate(data);
}, function(message) {
return _this._beaconTemplateError(message);
});
};
BeaconController.prototype._beaconTemplateError = function(message) {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, Constants.BEACONS.EVENTS.HTTP_ERROR), {
server_beacons: {
error_code: "Beacon Template Error: " + JSON.stringify(message),
fatal_failure: 0
}
});
return this._template_process_ready = true;
};
BeaconController.prototype._loadBeaconConfig = function() {
var b, _i, _len, _ref,
_this = this;
_ref = Constants.BEACONS_DEFAULTS.BEACONS;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
this.beacon_model.setShouldFire(b.type, b.event, Constants.BEACONS.FIRE_TYPES.ALWAYS);
}
$(this.beacon_model).one(BeaconModel.Events.ProcessConfigDone, function() {
return _this._config_process_ready = true;
});
return AppHelper.getJSON(Constants.BEACONS.BEACON_CONFIG_URL + "&cb=" + AppHelper.cacheBuster(), {}, function(data) {
return _this.beacon_model.parseBeaconConfig(data);
}, function(message) {
return _this._beaconConfigError(message);
});
};
BeaconController.prototype._beaconConfigError = function(message) {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, Constants.BEACONS.EVENTS.HTTP_ERROR), {
server_beacons: {
error_code: "Beacon Config Error: " + JSON.stringify(message),
fatal_failure: 0
}
});
return this._config_process_ready = true;
};
BeaconController.Events = {
Ready: "BeaconController.Events.Ready"
};
return BeaconController;
})();
FatalError = (function() {
function FatalError() {}
FatalError.DEEJAY_ERROR = "FatalError.DEEJAY_ERROR";
FatalError.PLAYER_ERROR = "FatalError.PLAYER_ERROR";
FatalError.VIDEO_EXPIRED = "FatalError.VIDEO_EXPIRED";
FatalError.VIDEO_UNAVAILABLE = "FatalError.VIDEO_UNAVAILABLE";
FatalError.GEO_BLOCK = "FatalError.GEO_BLOCK";
return FatalError;
})();
GeneralEvent = (function() {
function GeneralEvent() {}
GeneralEvent.RESET = "GeneralEvent.RESET";
GeneralEvent.FATAL_ERROR = "GeneralEvent.FATAL_ERROR";
GeneralEvent.WATCH_AGAIN = "GeneralEvent.WATCH_AGAIN";
return GeneralEvent;
})();
AdPodModel = (function(_super) {
__extends(AdPodModel, _super);
function AdPodModel(play_pos, pod_num) {
this.play_pos = play_pos;
this.pod_num = pod_num;
AdPodModel.__super__.constructor.call(this, 0, false);
}
AdPodModel.prototype.reset = function() {
var a, _i, _len, _ref;
AdPodModel.__super__.reset.call(this);
if (this.ads != null) {
_ref = this.ads;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
a = _ref[_i];
a.reset();
}
}
this.current_ad = 0;
return this.already_viewed_position = 0;
};
AdPodModel.prototype.addAd = function(ad) {
var a, i, _i, _len, _ref, _results;
if (!(this.ads != null)) {
this.ads = [];
}
this.ads.push(ad);
this.duration += ad.duration;
_ref = this.ads;
_results = [];
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
a = _ref[i];
_results.push(a.pod_text = "" + this.pod_num + "_" + this.ads.length + "_" + Constants.BEACONS_DEFAULTS.POD_SLOT_LOOKUP[i]);
}
return _results;
};
AdPodModel.prototype.getPlayInfo = function(preferred_bitrates) {
this._sendAdTimeUpdate();
return this.ads[this.current_ad].getPlayInfo(preferred_bitrates);
};
AdPodModel.prototype._sendAdTimeUpdate = function(show) {
if (show == null) {
show = true;
}
return $(this).trigger(PlayableModel.Events.UpdateAdTopBar, {
show: show,
ad_num: this.current_ad + 1,
ad_num_total: this.ads.length,
remaining: Math.round(this.duration - this.position)
});
};
AdPodModel.prototype.finishedPlaying = function() {
this.ads[this.current_ad].finishedPlaying();
this.already_viewed_position += this.ads[this.current_ad].duration;
this.current_ad++;
if (this.current_ad >= this.ads.length) {
this._sendAdTimeUpdate(false);
return AdPodModel.__super__.finishedPlaying.call(this);
}
};
AdPodModel.prototype.timeUpdate = function(position) {
var adPodPosition, adPosition;
if (AppHelper.isPlaylistCompatible()) {
adPodPosition = position;
adPosition = position - this.already_viewed_position;
} else {
adPodPosition = this.already_viewed_position + position;
adPosition = position;
}
this.position = adPodPosition;
this._sendAdTimeUpdate();
return this.ads[this.current_ad].timeUpdate(adPosition);
};
AdPodModel.prototype.markPlayed = function() {
var a, _i, _len, _ref;
AdPodModel.__super__.markPlayed.apply(this, arguments);
_ref = this.ads;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
a = _ref[_i];
a.markPlayed();
}
return this.current_ad = this.ads.length;
};
AdPodModel.prototype.markUnplayed = function() {
var a, _i, _len, _ref;
AdPodModel.__super__.markUnplayed.apply(this, arguments);
_ref = this.ads;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
a = _ref[_i];
a.markUnplayed();
}
return this.current_ad = 0;
};
AdPodModel.prototype.playStarted = function() {
return this.getCurrentAd().playStarted();
};
AdPodModel.prototype.getCurrentAd = function() {
return this.ads[this.current_ad];
};
return AdPodModel;
})(PlayableModel);
ContentModel = (function(_super) {
__extends(ContentModel, _super);
function ContentModel(urls, duration, start_marker, end_marker, app_model) {
this.urls = urls;
this.start_marker = start_marker != null ? start_marker : 0;
this.end_marker = end_marker;
this.app_model = app_model;
if ((this.end_marker != null) && (this.end_marker - this.start_marker) < duration) {
duration = this.end_marker - this.start_marker;
}
ContentModel.__super__.constructor.call(this, duration, true);
}
ContentModel.prototype.reset = function() {
ContentModel.__super__.reset.call(this);
this.setPosition(0);
this.just_set_position = false;
this.fired_play = false;
this.fired_percent_1 = false;
this.fired_percent_25 = false;
this.fired_percent_50 = false;
this.fired_percent_80 = false;
return this.fired_percent_99 = false;
};
ContentModel.prototype.setBreakPos = function(break_pos) {
var b, total_segments, unique_break_pos, _i, _len, _ref;
unique_break_pos = break_pos.filter(function(itm, i, a) {
return i === a.indexOf(itm);
});
this.break_pos = unique_break_pos.sort(function(a, b) {
return a - b;
});
total_segments = 0;
_ref = this.break_pos;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if ((0 < b && b < this.duration)) {
total_segments++;
}
}
total_segments++;
return this.total_segments = total_segments;
};
ContentModel.prototype.setPosition = function(position) {
this.just_set_position = true;
return ContentModel.__super__.setPosition.call(this, position + this.start_marker);
};
ContentModel.prototype.playStarted = function() {
if (this.position >= 0 && !this.fired_play) {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.START), this);
return this.fired_play = true;
}
};
ContentModel.prototype.finishedPlaying = function() {
var _ref;
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.END), this);
ContentModel.__super__.finishedPlaying.call(this);
return (_ref = window.Player) != null ? typeof _ref.onContentEnd === "function" ? _ref.onContentEnd({
playedTime: this.total_time_playing,
duration: this.duration
}) : void 0 : void 0;
};
ContentModel.prototype.timeUpdate = function(position) {
ContentModel.__super__.timeUpdate.call(this, position, !this.just_set_position);
if (!this.just_set_position) {
if (!this.fired_percent_1 && (position / this.duration > 0.01 || position > 1)) {
this.fired_percent_1 = true;
this._triggerTimeEvent(1);
}
if (!this.fired_percent_25 && position / this.duration > 0.25) {
this.fired_percent_25 = true;
this._triggerTimeEvent(25);
}
if (!this.fired_percent_50 && position / this.duration > 0.50) {
this.fired_percent_50 = true;
this._triggerTimeEvent(50);
}
if (!this.fired_percent_80 && position / this.duration > 0.80) {
this.fired_percent_80 = true;
this._triggerTimeEvent(80);
}
if (!this.fired_percent_99 && (position / this.duration > 0.99 || this.duration - position < 5)) {
this.fired_percent_99 = true;
this._triggerTimeEvent(99);
}
}
this.just_set_position = false;
this.playStarted();
return EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYBACK, Constants.BEACONS.EVENTS.POSITION), this);
};
ContentModel.prototype.getTotalSegments = function() {
return this.total_segments;
};
ContentModel.prototype.getCurrentSegment = function() {
var ans, b, _i, _len, _ref;
ans = 1;
_ref = this.break_pos;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if (this.position < b) {
return ans;
}
if ((0 < b && b < this.duration)) {
ans++;
}
}
return ans;
};
ContentModel.prototype._triggerTimeEvent = function(percent) {
var lable, pageName, pageType, programmingtType;
try {
if (typeof _gaq !== "undefined" && _gaq !== null) {
pageType = this.app_model.getPageType();
pageName = this.app_model.getPageName();
switch (this.app_model.programming_type) {
case 'Excerpt':
programmingtType = 'clip';
break;
case 'Full Episode':
programmingtType = 'episode';
}
switch (pageType) {
case 'homepage':
case 'category':
lable = pageType + (pageName.indexOf('mobile_editorial') === 0 ? pageName.substring(16) : '') + '-' + this.app_model.video_id.toString();
break;
case 'series':
lable = pageName + '_' + programmingtType + '-' + this.app_model.video_id.toString();
break;
case 'watch':
lable = pageType + '_' + programmingtType + '-' + this.app_model.video_id.toString();
}
return _gaq.push(['_trackEvent', 'mobile-video-progress', lable, percent.toString(), parseInt(this.position)]);
}
} catch (ex) {
return Logger.warn(['Exception thrown when try to call window.Player.trackGoogleEventVideoViewthrough', ex]);
}
};
return ContentModel;
})(PlayableModel);
PrerollModel = (function(_super) {
__extends(PrerollModel, _super);
function PrerollModel(urls, play_pos, duration, can_seek) {
this.urls = urls;
this.play_pos = play_pos;
PrerollModel.__super__.constructor.call(this, duration, can_seek);
}
PrerollModel.prototype.getPlayInfo = function(preferred_bitrates) {
var a;
a = PrerollModel.__super__.getPlayInfo.call(this, preferred_bitrates);
a[2] = 0;
return a;
};
PrerollModel.prototype.playStarted = function() {
return PrerollModel.__super__.playStarted.call(this);
};
PrerollModel.prototype.finishedPlaying = function() {
return PrerollModel.__super__.finishedPlaying.call(this);
};
PrerollModel.prototype.timeUpdate = function(position) {
return PrerollModel.__super__.timeUpdate.call(this, position);
};
return PrerollModel;
})(PlayableModel);
AdModel = (function(_super) {
__extends(AdModel, _super);
function AdModel(urls, duration, can_seek) {
this.urls = urls;
AdModel.__super__.constructor.call(this, duration, can_seek);
}
AdModel.prototype.reset = function() {
AdModel.__super__.reset.call(this);
this._start_from_beginning = false;
this._has_seek_forward = false;
this._largest_position = 0;
this.fired_start = false;
this.fired_percent_25 = false;
this.fired_percent_50 = false;
this.fired_percent_75 = false;
return this.fired_end = false;
};
AdModel.prototype.getPlayInfo = function(preferred_bitrates) {
var a;
a = AdModel.__super__.getPlayInfo.call(this, preferred_bitrates);
a[2] = 0;
return a;
};
AdModel.prototype.playStarted = function() {
if (!this.fired_start) {
this.fired_start = true;
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.REVENUE, Constants.BEACONS.EVENTS.START), this);
Logger.info("revenue start");
return this._checkForAudits(0);
}
};
AdModel.prototype.finishedPlaying = function() {
if (!this.fired_end && (this._start_from_beginning && !this._has_seek_forward)) {
this.fired_end = true;
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.REVENUE, Constants.BEACONS.EVENTS.END), this);
Logger.info("revenue end");
this._checkForAudits(100);
}
return AdModel.__super__.finishedPlaying.call(this);
};
AdModel.prototype.timeUpdate = function(position) {
this._start_from_beginning = this._start_from_beginning || (position >= 0 && position < 1);
this._has_seek_forward = this._has_seek_forward || (position - this._largest_position > 1);
this._largest_position = Math.max(this._largest_position, position);
if (!this.fired_percent_25 && position / this.duration > 0.25) {
this.fired_percent_25 = true;
this._triggerTimeEvent(25);
}
if (!this.fired_percent_50 && position / this.duration > 0.50) {
this.fired_percent_50 = true;
this._triggerTimeEvent(50);
}
if (!this.fired_percent_75 && position / this.duration > 0.75) {
this.fired_percent_75 = true;
this._triggerTimeEvent(75);
}
return AdModel.__super__.timeUpdate.call(this, position);
};
AdModel.prototype.markPlayed = function() {
AdModel.__super__.markPlayed.call(this);
this.fired_start = true;
this.fired_percent_25 = true;
this.fired_percent_50 = true;
this.fired_percent_75 = true;
return this.fired_end = true;
};
AdModel.prototype.markUnplayed = function() {
AdModel.__super__.markUnplayed.call(this);
this.fired_start = false;
this.fired_percent_25 = false;
this.fired_percent_50 = false;
this.fired_percent_75 = false;
return this.fired_end = false;
};
AdModel.prototype._triggerTimeEvent = function(percent) {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.REVENUE, Constants.BEACONS.EVENTS.POSITION), {
object: this,
percent: percent
});
return this._checkForAudits(percent);
};
AdModel.prototype._checkForAudits = function(percent) {
var a, url, _i, _len, _ref, _results;
if (this['audits']) {
_ref = this['audits'];
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
a = _ref[_i];
if (a.percent === percent) {
url = a.url;
if (url !== null && Constants.IS_SSL && url.indexOf("http://") === 0) {
url = url.replace(/^http:/i, "https:");
}
_results.push(BeaconHelper.sendBeacon(url));
} else {
_results.push(void 0);
}
}
return _results;
}
};
return AdModel;
})(PlayableModel);
PlayerModel = (function() {
function PlayerModel(app_model) {
this.app_model = app_model;
this._updateTotalTime = __bind(this._updateTotalTime, this);
this._updateAdTopBar = __bind(this._updateAdTopBar, this);
this.content = void 0;
this.breaks = void 0;
this._current_playable = void 0;
this.current_break = void 0;
this.reset();
}
PlayerModel.prototype.getPod = function(index) {
var pod, _i, _len, _ref;
_ref = this.breaks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
pod = _ref[_i];
if (pod.pod_num === index) {
return pod;
}
}
};
PlayerModel.prototype.reset = function() {
var b, _i, _len, _ref, _results;
if (this._current_playable != null) {
$(this._current_playable).off(PlayableModel.Events.UpdateAdTopBar, this._updateAdTopBar);
}
this.current_break = void 0;
this._current_playable = void 0;
this.total_ad_duration = 0;
this.last_total_time_playing_ad = 0;
this.is_done = false;
this.in_break = false;
this.end_card_ad_model = void 0;
this._total_playback_time = 0;
this._total_playback_time_last_update = void 0;
if (this.content != null) {
this.content.reset();
}
if (this.breaks != null) {
_ref = this.breaks;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
_results.push(b.reset());
}
return _results;
}
};
PlayerModel.prototype.processContentResponse = function(data) {
var ad, ads, b, break_pos, breaks, broadKind, content, max_end_marker, pod, podNum, pods, preroll, _i, _len, _ref, _ref1;
this.is_done = false;
this.start_marker = Math.max(this.app_model.getStartTime() / 1000, 0);
max_end_marker = parseFloat(data['duration']) / 1000;
this.end_marker = this.app_model.getEndTime() / 1000 || max_end_marker;
this.end_marker = Math.min(this.end_marker, max_end_marker);
content = new ContentModel(data['all_bitrate_urls'], this.end_marker - this.start_marker, this.start_marker, this.end_marker, this.app_model);
breaks = [];
break_pos = [];
pods = {};
if (!AppHelper.showContentOnly()) {
_ref = data['breaks'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
broadKind = b['kind'].split(':');
break_pos.push(b['pos'] / 1000);
switch (broadKind[0]) {
case "preroll":
case "postroll":
preroll = new PrerollModel(b['all_bitrate_urls'], b['pos'] / 1000, b['duration'] / 1000, b['can_seek']);
preroll.server_beacons = b['server_beacons'];
breaks.push(preroll);
break;
case "ad":
if (!((_ref1 = b['pod']) === 0 || _ref1 === 1 || _ref1 === (-1)) && (b['pos'] / 1000 < this.start_marker || (b['pos'] > 0 && !AppHelper.enableAdBreak()))) {
break;
}
this.total_ad_duration += b['duration'] / 1000;
ad = new AdModel(b['all_bitrate_urls'], b['duration'] / 1000, b['can_seek']);
ad.flight_id = b['flight_id'];
ad.ad_unit_id = b['ad_unit_id'];
if (b['audits']) {
ad.audits = b['audits'];
}
ad.server_beacons = b['server_beacons'];
ad.ad_unit_type = b['ad_unit_type'];
podNum = b['pod'];
if (!pods[podNum]) {
pods[podNum] = new AdPodModel(b['pos'] / 1000, podNum);
}
pods[podNum].addAd(ad);
break;
default:
Logger.error(["unknown content type", b]);
}
}
for (pod in pods) {
ads = pods[pod];
if (ads !== void 0) {
breaks.push(ads);
}
}
}
content.setBreakPos(break_pos);
this.setContent(content);
this.setBreaks(breaks);
this.dynamic_bug_br = data['dynamic_bug_br'];
if (data['end_card']) {
this.end_card_ad_model = new EndCardAdModel(data['end_card']);
}
return $(this).trigger(PlayerModel.Events.ProcessContentDone);
};
PlayerModel.prototype.setProgress = function(percent) {
var current_position, new_position, _ref, _ref1, _ref2;
current_position = (_ref = this.content) != null ? _ref.getPosition() : void 0;
new_position = percent * ((_ref1 = this.content) != null ? _ref1.getDuration() : void 0);
if ((_ref2 = this.content) != null) {
_ref2.setPosition(new_position);
}
return this.checkForSkippedAds(current_position, new_position);
};
PlayerModel.prototype.getPlayInfo = function(preferred_bitrates) {
var info, _ref;
info = (_ref = this._current_playable) != null ? _ref.getPlayInfo(preferred_bitrates) : void 0;
if (((info != null ? info[1] : void 0) != null) && info[1].indexOf(".mp4") < 0) {
info[1] = info[1] + "?.mp4";
}
if (info != null) {
info[3] = this.canSeek();
}
return info;
};
PlayerModel.prototype.getBitrate = function() {
var _ref;
return ((_ref = this.getPlayInfo(AppHelper.preferredBitrates())) != null ? _ref[0] : void 0) || AppHelper.preferredBitrate();
};
PlayerModel.prototype._updateAdTopBar = function(event, data) {
var other_playable, _ref, _ref1;
if (data['show'] === true) {
if ((_ref = (_ref1 = this._current_playable) != null ? _ref1.pod_num : void 0) === 0 || _ref === 1) {
if (this._current_playable.pod_num === 0) {
other_playable = this.getPod(1);
if (other_playable != null) {
data['remaining'] += Math.round(other_playable.duration);
}
} else {
other_playable = this.getPod(0);
if (other_playable != null) {
data['ad_num'] += other_playable.ads.length;
}
}
if (other_playable != null) {
data['ad_num_total'] = this._current_playable.ads.length + other_playable.ads.length;
}
}
}
return $(this).trigger(PlayerModel.Events.UpdateAdTopBar, data);
};
PlayerModel.prototype.checkForSkippedAds = function(current_position, new_position) {
var b, firstPod, lastPod, time_since_last_ad, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3;
new_position += this.start_marker;
time_since_last_ad = this.content.total_time_playing - this.last_total_time_playing_ad;
if (current_position < new_position) {
lastPod = void 0;
_ref = this.breaks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if ((current_position < (_ref1 = b.play_pos) && _ref1 < new_position)) {
b.markPlayed();
lastPod = b;
}
}
if (lastPod !== void 0 && lastPod !== this.current_break && time_since_last_ad >= Constants.AD_FREE_PERIOD) {
lastPod.markUnplayed();
return this.current_break = lastPod;
}
} else {
firstPod = void 0;
_ref2 = this.breaks;
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
b = _ref2[_j];
if ((current_position > (_ref3 = b.play_pos) && _ref3 > new_position)) {
if (b !== this.current_break) {
b.markUnplayed();
}
if (firstPod === void 0) {
firstPod = b;
}
}
}
if (firstPod !== void 0 && time_since_last_ad >= Constants.AD_FREE_PERIOD) {
return this.current_break = firstPod;
}
}
};
PlayerModel.prototype.findNextToPlay = function() {
var b, new_playable, _i, _len, _ref;
new_playable = void 0;
if (this.current_break !== void 0 && !this.current_break.played) {
this.in_break = true;
this.last_total_time_playing_ad = this.content.total_time_playing;
new_playable = this.current_break;
} else {
if (this.breaks != null) {
_ref = this.breaks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if (!b.played && (b.play_pos <= this.content.getPosition() || (this.content.played && b.play_pos > this.content.getPosition()))) {
this.in_break = true;
this.current_break = b;
this.last_total_time_playing_ad = this.content.total_time_playing;
new_playable = b;
break;
}
}
}
}
if (!(new_playable != null)) {
this.in_break = false;
if ((this.content != null) && !this.content.played) {
new_playable = this.content;
}
}
if (this._current_playable != null) {
$(this._current_playable).off(PlayableModel.Events.UpdateAdTopBar, this._updateAdTopBar);
}
this._current_playable = new_playable;
if (this._current_playable != null) {
$(this._current_playable).on(PlayableModel.Events.UpdateAdTopBar, this._updateAdTopBar);
}
return new_playable;
};
PlayerModel.prototype.getSeekPercentage = function() {
var percent;
if (!(this.content != null)) {
return 0;
}
percent = (Math.round(this.content.getPosition()) - this.start_marker) / this.content.getDuration() * 100;
return Math.min(100, Math.max(0, percent));
};
PlayerModel.prototype.getTimeRemaining = function() {
if (!(this.content != null)) {
return 0;
}
return this.content.getDuration() - (this.content.getPosition() - this.start_marker);
};
PlayerModel.prototype.breakAvailable = function() {
var b, _i, _len, _ref;
if (this.in_break) {
return false;
}
if (!(this.breaks != null)) {
return false;
}
_ref = this.breaks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if (!b.played && b.play_pos <= this.content.getPosition()) {
return true;
}
}
return false;
};
PlayerModel.prototype._updateTotalTime = function() {
var new_timestamp;
new_timestamp = (new Date()).getTime();
this._total_playback_time += new_timestamp - this._total_playback_time_last_update;
return this._total_playback_time_last_update = new_timestamp;
};
PlayerModel.prototype.timeUpdate = function(time) {
var _ref;
this._updateTotalTime();
if (this.isInContentState()) {
this.checkForSkippedAds(this.content.getPosition(), time);
}
if ((_ref = this._current_playable) != null) {
_ref.timeUpdate(time);
}
};
PlayerModel.prototype.playStarted = function() {
var _ref;
if (!(this._total_playback_time_last_update != null)) {
this._total_playback_time_last_update = (new Date()).getTime();
}
return (_ref = this._current_playable) != null ? _ref.playStarted() : void 0;
};
PlayerModel.prototype.getBreaksForDots = function() {
var b, breaks, percent, _i, _len, _ref;
breaks = [];
_ref = this.breaks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if (b.play_pos - this.start_marker > 0 && b.play_pos < this.content.getDuration()) {
percent = (b.play_pos - this.start_marker) / this.content.getDuration() * 100;
breaks.push({
location: percent,
active: b === this._current_playable
});
}
}
return breaks;
};
PlayerModel.prototype.currentPlayableEnded = function() {
if (this._current_playable != null) {
this._current_playable.finishedPlaying();
return $(this._current_playable).off(PlayableModel.Events.UpdateAdTopBar, this._updateAdTopBar);
}
};
PlayerModel.prototype.getPlayerMode = function() {
if (this.app_model.isEmbed()) {
return "embed";
} else {
return this.app_model.getPlayerMode();
}
};
PlayerModel.prototype.isPlaybackPending = function() {
switch (this._media_player_view_state) {
case MediaPlayerView.States.Buffering:
case MediaPlayerView.States.Seeking:
return true;
default:
return false;
}
};
PlayerModel.prototype.setContent = function(content) {
this.content = content;
};
PlayerModel.prototype.setBreaks = function(breaks) {
this.breaks = breaks;
};
PlayerModel.prototype.setInBreak = function(in_break) {
this.in_break = in_break;
};
PlayerModel.prototype.setPosition = function(pos) {
var _ref;
return (_ref = this._current_playable) != null ? _ref.setPosition(pos) : void 0;
};
PlayerModel.prototype.markAsDone = function() {
return this.is_done = true;
};
PlayerModel.prototype.getContent = function() {
return this.content;
};
PlayerModel.prototype.getBreaks = function() {
return this.breaks;
};
PlayerModel.prototype.getInBreak = function() {
return this.in_break;
};
PlayerModel.prototype.getIsDone = function() {
return this.is_done;
};
PlayerModel.prototype.getCurrentPlayable = function() {
return this._current_playable;
};
PlayerModel.prototype.getPosition = function() {
var _ref;
return (_ref = this._current_playable) != null ? _ref.getPosition() : void 0;
};
PlayerModel.prototype.isInContentState = function() {
return this._current_playable instanceof ContentModel;
};
PlayerModel.prototype.isInBreakState = function() {
return this._current_playable instanceof AdPodModel || this._current_playable instanceof PrerollModel;
};
PlayerModel.prototype.isPlaying = function() {
return this._media_player_view_state === MediaPlayerView.States.Playing;
};
PlayerModel.prototype.canSeek = function() {
var _ref;
return (_ref = this._current_playable) != null ? _ref.can_seek : void 0;
};
PlayerModel.prototype.setMediaPlayerViewState = function(_media_player_view_state) {
this._media_player_view_state = _media_player_view_state;
};
PlayerModel.Events = {
UpdateAdTopBar: "PlayerModel.Events.UpdateAdTopBar",
ProcessContentDone: "PlayerModel.Events.ProcessContentDone"
};
return PlayerModel;
})();
PlayerController = (function() {
PlayerController.CONTROLS_TIMEOUT = 3000;
function PlayerController(app_model, ui) {
this.app_model = app_model;
this.ui = ui;
this._onFatalError = __bind(this._onFatalError, this);
this._updateAdTopBar = __bind(this._updateAdTopBar, this);
this._onSeek = __bind(this._onSeek, this);
this.hideControls = __bind(this.hideControls, this);
this.showControls = __bind(this.showControls, this);
this.reset = __bind(this.reset, this);
this._onPlayerTimeUpdate = __bind(this._onPlayerTimeUpdate, this);
this._onAgeSubmission = __bind(this._onAgeSubmission, this);
this._onSegmentEnded = __bind(this._onSegmentEnded, this);
this.startPlay = __bind(this.startPlay, this);
if (AppHelper.isPlaylistCompatible()) {
this.player_model = new PlaylistPlayerModel(this.app_model);
} else {
this.player_model = new PlayerModel(this.app_model);
}
this.player_view = new PlayerView(this.app_model, this.player_model, this.ui);
this.controls_view = new ControlsView();
this.thumbnail_position = this.app_model.getThumbnailTime();
this.controls_timeout = void 0;
this._initEvents();
this._app_ready = false;
}
PlayerController.prototype._initEvents = function() {
var _this = this;
$(this.player_view).on(PlayerView.Events.Ended, this._onSegmentEnded);
$(this.player_view).on(PlayerView.Events.Paused, function(event) {
return _this._onPlayerPaused(event);
});
$(this.player_view).on(PlayerView.Events.Resumed, function(event) {
return _this._onPlayerResumed(event);
});
$(this.player_view).on(PlayerView.Events.Playing, function(event) {
return _this._onPlayerPlaying(event);
});
$(this.player_view).on(PlayerView.Events.Buffering, function(event) {
return _this._onPlayerBuffering(event);
});
$(this.player_view).on(PlayerView.Events.BufferFinished, function(event) {
return _this._onPlayerBufferFinished(event);
});
$(this.player_view).on(PlayerView.Events.TimeUpdate, this._onPlayerTimeUpdate);
$(this.player_view).on(PlayerView.Events.Error, function(event) {
return _this._onPlayerError(event);
});
$(this.player_view).on(PlayerView.Events.StartPlayClick, this.startPlay);
$(this.player_view).on(AgeGate.Events.AgeSubmitted, this._onAgeSubmission);
$(this.controls_view).on(ControlsView.Events.PauseBtnClick, function(event) {
return _this._onUserPause();
});
$(this.controls_view).on(ControlsView.Events.FullscreenBtnClick, function(event) {
return _this._toggleFullScreen();
});
EventBus.on(GeneralEvent.RESET, this.reset);
EventBus.on(GeneralEvent.FATAL_ERROR, this._onFatalError);
EventBus.on(ControlsView.Events.Seek, this._onSeek);
$(this.player_model).on(PlayerModel.Events.UpdateAdTopBar, this._updateAdTopBar);
if (this.player_model instanceof PlaylistPlayerModel) {
return $(this.player_model).on(PlaylistPlayerModel.Events.SegmentFinished, function(event, data) {
return _this._onSegmentEnded(event, data);
});
}
};
PlayerController.prototype.ensureReadyForAsyncPlayback = function() {
return this.player_view.ensureReadyForAsyncPlayback();
};
PlayerController.prototype.onAppReady = function(begin_playback) {
this.player_view.hideLoading();
this._app_ready = true;
if (this.app_model.hasPlayedThrough() || this.app_model.canAutoPlay() || begin_playback) {
return this.player_view.triggerStartPlayClick();
}
};
PlayerController.prototype.processContentResponse = function(data) {
var poster_size, poster_url,
_this = this;
poster_size = AppHelper.posterSize(this.app_model.isEmbed());
poster_url = AppHelper.getPosterUrl(this.app_model.content_id, poster_size, this.thumbnail_position);
this.player_view.setPosterSource(poster_url);
this.player_view.showPoster();
$(this.player_model).one(PlayerModel.Events.ProcessContentDone, function() {
return $(_this).trigger(PlayerController.Events.Ready);
});
this.player_model.processContentResponse(data);
this.player_view.initEndCard();
return this.player_view.setCardData(data['tp_Series_Title'], data['title'], data['duration']);
};
PlayerController.prototype.startPlay = function() {
var _this = this;
if (this.app_model.ageRestricted()) {
this.player_view.showAgeGate();
return;
}
this.player_view.showMediaPlayer();
if (this._app_ready) {
this.drawBreakDots();
$(this.player_view).on(PlayerView.Events.ShowControls, this.showControls);
$(this.player_view).on(PlayerView.Events.HideControls, this.hideControls);
$(this.controls_view).on(ControlsView.Events.ShowControls, this.showControls);
this.player_view.setBug(PlayerView.Bugs.Network, this.player_model.dynamic_bug_br);
this.controls_view.setSeekPercentage(0);
return this._findAndPlayNext();
} else {
this.player_view.showLoading();
return AppHelper.setTimeout(Constants.PLAY_TIMEOUT, function() {
return _this.startPlay();
});
}
};
PlayerController.prototype.isPlaying = function() {
return this.player_model.isPlaying();
};
PlayerController.prototype.isPlaybackPending = function() {
return this.player_model.isPlaybackPending();
};
PlayerController.prototype._onSegmentEnded = function(event, data) {
this.player_view.hideBug(PlayerView.Bugs.Network);
this.player_model.currentPlayableEnded();
return this._findAndPlayNext();
};
PlayerController.prototype._onAgeSubmission = function(event, object) {
if (this.app_model.verifyAge(object.birthdate)) {
this.player_view.hideAgeGate();
this.app_model.minimum_age_verified = true;
return this.startPlay();
} else {
return this.player_view.showAgeGateDenied();
}
};
PlayerController.prototype._onPlayerTimeUpdate = function(event, data) {
if (this.player_model.getIsDone() || this.app_model.changing_video) {
return;
}
this.player_model.timeUpdate(data.currentTime);
this._updateSeekBar();
if (AppHelper.isPlaylistCompatible() && !this.player_model.timeIsInCurrentRange(data.currentTime)) {
this._findAndPlayNext();
} else {
this._checkForBreak();
}
this.player_view.hideLoading();
return this._updateTimeRemaining(event, data);
};
PlayerController.prototype._onPlayerPaused = function(event) {
return this.controls_view.hide(true);
};
PlayerController.prototype._onPlayerResumed = function(event) {
return this.resume();
};
PlayerController.prototype._onPlayerPlaying = function(event) {
AppModel.PLAYER_STATUS = "playing";
this.player_view.hideLoading();
if (!this.controls_view.isShown() && this.player_model.isInContentState()) {
this.player_view.showBug(PlayerView.Bugs.Network);
} else {
this.player_view.hideBug(PlayerView.Bugs.Network);
}
return this.player_model.playStarted();
};
PlayerController.prototype.reset = function() {
this.clearControlsTimeout();
this.player_view.reset();
this.player_model.reset();
this.hideControls(true);
return this.controls_view.reset();
};
PlayerController.prototype._onPlayerError = function(event) {
if (this.player_model.isInContentState()) {
return EventBus.trigger(GeneralEvent.FATAL_ERROR, {
type: FatalError.PLAYER_ERROR,
message: "Playback error"
});
} else {
return this._onSegmentEnded();
}
};
PlayerController.prototype._onPlayerBuffering = function(event) {
return this.app_model.onPlayerStartBuffer();
};
PlayerController.prototype._onPlayerBufferFinished = function(event) {
return this.app_model.onPlayerEndBuffer();
};
PlayerController.prototype.showControls = function(event, sourceEvent) {
var _this = this;
if (AppModel.PLAYER_STATUS !== "paused") {
this.controls_view.show();
if (this.player_model.isInContentState()) {
this.player_view.showBug(PlayerView.Bugs.Partner);
}
this.player_view.hideBug(PlayerView.Bugs.Network);
this.clearControlsTimeout();
if (!this.controls_view.is_dragging) {
return this.controls_timeout = AppHelper.setTimeout.apply(this, [
PlayerController.CONTROLS_TIMEOUT, function() {
return _this.hideControls();
}
]);
}
}
};
PlayerController.prototype.hideControls = function(skip_animation) {
if (skip_animation == null) {
skip_animation = false;
}
this.controls_view.hide(skip_animation);
this.player_view.hideBug(PlayerView.Bugs.Partner);
if (this.player_model.isInContentState()) {
this.player_view.showBug(PlayerView.Bugs.Network);
}
return this.clearControlsTimeout();
};
PlayerController.prototype.showPlayer = function() {
return this.player_view.show();
};
PlayerController.prototype.hidePlayer = function() {
return this.player_view.hide();
};
PlayerController.prototype._checkForBreak = function() {
var playAvailable;
playAvailable = this.player_model.breakAvailable();
if (playAvailable) {
if (AppModel.PLAYER_STATUS === "playing" && !AppHelper.isIOS()) {
this.pause();
}
return this._findAndPlayNext();
}
};
PlayerController.prototype._updateSeekBar = function() {
return this.controls_view.setSeekPercentage(this.player_model.getSeekPercentage());
};
PlayerController.prototype._updateTimeRemaining = function(event, data) {
var content_time_remaining;
content_time_remaining = this.player_model.getTimeRemaining();
if (content_time_remaining <= 0) {
return this._onSegmentEnded(event, data);
} else {
this.player_view.setTimeRemaining(content_time_remaining);
return this.controls_view.setTimeRemaining(content_time_remaining);
}
};
PlayerController.prototype._findAndPlayNext = function() {
this.player_model.findNextToPlay();
if (this.player_model.getCurrentPlayable() != null) {
return this.playCurrentPlayable();
} else if (!this.player_model.getIsDone()) {
this.player_view.exitFullScreen();
this.player_view.showEndCard(this.player_model.end_card_ad_model);
this.controls_view.hide(true);
AppModel.PLAYER_STATUS = "paused";
this.player_model.markAsDone();
return $(this).trigger(PlayerController.Events.Done);
}
};
PlayerController.prototype.playCurrentPlayable = function() {
var b, bitrate, duration, hash, p, params, parts, position, seekable, url, _i, _len, _ref;
if (!AppHelper.isPlaylistCompatible()) {
this.player_view.showLoading();
}
_ref = this.player_model.getPlayInfo(AppHelper.preferredBitrates()), bitrate = _ref[0], url = _ref[1], position = _ref[2], seekable = _ref[3];
if (!(url != null)) {
Logger.error("url undefined");
return;
}
if (this.player_model.isInContentState()) {
this.controls_view.showFullscreenButton();
} else {
this.controls_view.hideFullscreenButton();
}
hash = window.location.hash;
params = {};
if (hash) {
hash = hash.substring(1);
parts = hash.split("&");
for (_i = 0, _len = parts.length; _i < _len; _i++) {
p = parts[_i];
b = p.split("=");
params[b[0]] = b[1];
}
}
if ((params['drip'] != null) && (params['rule'] != null)) {
url = "http://dripls.hulu.com/progressive?url=" + url + "&r=" + params['rule'];
position = void 0;
} else {
position = position != null ? position : this.player_model.last_reported_time;
}
if (this.player_model.isInContentState() && AppHelper.isPlaylistCompatible()) {
this.player_view.setStartMarker(this.player_model.getCurrentPlayable().play_pos);
}
duration = this.player_model.getCurrentPlayable().getDuration();
this.player_view.play(url, position, duration, seekable);
return this.resume();
};
PlayerController.prototype.pause = function(hide_elements) {
if (hide_elements == null) {
hide_elements = true;
}
if (hide_elements) {
this.clearControlsTimeout();
this.player_view.hideBug(PlayerView.Bugs.Network);
if (AppModel.PLAYER_STATUS === "playing") {
this.player_view.pause();
}
this.player_view.hideAdTopBar();
}
return AppModel.PLAYER_STATUS = "paused";
};
PlayerController.prototype.resume = function() {
AppModel.PLAYER_STATUS = "playing";
this.player_view.isInBreak(!this.player_model.isInContentState());
if (this.player_model.isInContentState()) {
return this.player_view.showBug(PlayerView.Bugs.Hulu);
} else {
return this.player_view.hideBug();
}
};
PlayerController.prototype._onSeek = function(event, data) {
if (this.player_model.canSeek()) {
this.pause(false);
this.player_model.setProgress(data.percent);
this._findAndPlayNext();
this.player_view.setTriggeredByUser(true);
return this._updateSeekBar();
}
};
PlayerController.prototype._updateAdTopBar = function(event, data) {
if (data['show'] === true) {
return this.player_view.showAdTopBar(data['ad_num'], data['ad_num_total'], data['remaining']);
} else {
return this.player_view.hideAdTopBar();
}
};
PlayerController.prototype.drawBreakDots = function() {
var breaks;
this.controls_view.clearBreakDots();
breaks = this.player_model.getBreaksForDots();
return this.controls_view.drawBreakDots(breaks);
};
PlayerController.prototype._toggleFullScreen = function() {
this.player_view.toggleFullScreen(true);
return this.player_view.setTriggeredByUser(true);
};
PlayerController.prototype._onUserPause = function() {
this.pause();
return this.player_view.setTriggeredByUser(true);
};
PlayerController.prototype.clearControlsTimeout = function() {
if (this.controls_timeout != null) {
clearTimeout(this.controls_timeout);
return this.controls_timeout = void 0;
}
};
PlayerController.prototype._onFatalError = function(event, error) {
switch (error.type) {
case FatalError.PLAYER_ERROR:
return this.player_view.showError(Constants.STREAM_LOAD_ERROR);
case FatalError.VIDEO_EXPIRED:
return this.player_view.showError(Constants.VIDEO_EXPIRED_ERROR_MESSAGE);
case FatalError.VIDEO_UNAVAILABLE:
return this.player_view.showError(Constants.UNAVAILABLE_ERROR_MESSAGE);
case FatalError.GEO_BLOCK:
return this.player_view.showError(Constants.GEO_BLOCK_MESSAGE);
default:
return this.player_view.showError();
}
};
PlayerController.Events = {
Ready: "PlayerController.Events.Ready",
Done: "PlayerController.Events.Done"
};
return PlayerController;
})();
AppController = (function() {
function AppController(app_model, parent_div) {
this.app_model = app_model;
this._processContentResponse = __bind(this._processContentResponse, this);
this._onFatalError = __bind(this._onFatalError, this);
this._djError = __bind(this._djError, this);
this._loadContent = __bind(this._loadContent, this);
this._checkReady = __bind(this._checkReady, this);
this._markBeaconControllerReady = __bind(this._markBeaconControllerReady, this);
this._markPlayerControllerReady = __bind(this._markPlayerControllerReady, this);
this.pauseEverything = __bind(this.pauseEverything, this);
this.setVideo = __bind(this.setVideo, this);
this._onWatchAgain = __bind(this._onWatchAgain, this);
this._onReset = __bind(this._onReset, this);
this.ui = new Ui(this.app_model, parent_div);
this.player_controller = new PlayerController(this.app_model, this.ui);
this.beacon_controller = new BeaconController(this.app_model, this.player_controller.player_model);
this.is_auto_start_request_pending = false;
this._initEvents();
if (this.app_model.getInitialEID() != null) {
this.setVideo(this.app_model.getInitialEID(), this.app_model.isAutoStart());
}
if (!AppHelper.isPlayerAllowed()) {
EventBus.trigger(GeneralEvent.FATAL_ERROR, {
type: FatalError.VIDEO_UNAVAILABLE
});
}
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLAYER_TRACKING, Constants.BEACONS.EVENTS.PLAYER_LOADED));
}
AppController.prototype._initEvents = function() {
EventBus.on(GeneralEvent.RESET, this._onReset);
EventBus.on(GeneralEvent.FATAL_ERROR, this._onFatalError);
EventBus.on(GeneralEvent.WATCH_AGAIN, this._onWatchAgain);
$(this.player_controller).one(PlayerController.Events.Ready, this._markPlayerControllerReady);
return $(this.beacon_controller).one(BeaconController.Events.Ready, this._markBeaconControllerReady);
};
AppController.prototype._onReset = function() {
this.app_model.reset();
this.beacon_controller.reset();
if (!this.app_model.changing_video) {
return this.player_controller.onAppReady();
}
};
AppController.prototype._onWatchAgain = function() {
return this.setVideo(this.app_model.video_eid, true);
};
AppController.prototype.changePlayerSize = function(width, height) {
return this.ui.changePlayerSize(width, height);
};
AppController.prototype.setVideo = function(video_id, auto_start) {
this.auto_start = auto_start;
if (!AppHelper.isPlayerAllowed()) {
return;
}
this.app_model.first_play = true;
this.app_model.video_eid = video_id;
this.app_model.changing_video = true;
EventBus.trigger(GeneralEvent.RESET);
this.app_model.video_eid = video_id;
this._player_controller_ready = false;
this.player_controller.showPlayer();
$(this.player_controller).one(PlayerController.Events.Ready, this._markPlayerControllerReady);
if (this.auto_start) {
this.player_controller.ensureReadyForAsyncPlayback();
}
this._loadContent(video_id);
this._clearReadyCheckTimer();
return this._ready_check_timer = AppHelper.setInterval(100, this._checkReady);
};
AppController.prototype.stopVideo = function() {
this.app_model.changing_video = true;
this.app_model.reset();
this.beacon_controller.reset();
this.player_controller.reset();
this.player_controller.hidePlayer();
return this.app_model.changing_video = false;
};
AppController.prototype.pauseEverything = function() {
return this.player_controller.pause();
};
AppController.prototype.getCurrentVideoId = function() {
return this.app_model.video_eid;
};
AppController.prototype.isPlaying = function() {
return this.player_controller.isPlaying();
};
AppController.prototype.isPlaybackPending = function() {
return this.player_controller.isPlaybackPending() || this.is_auto_start_request_pending;
};
AppController.prototype._markPlayerControllerReady = function(event) {
return this._player_controller_ready = true;
};
AppController.prototype._markBeaconControllerReady = function(event) {
return this._beacon_controller_ready = true;
};
AppController.prototype._checkReady = function() {
if (this._player_controller_ready && this._beacon_controller_ready) {
this._clearReadyCheckTimer();
this.player_controller.onAppReady(this.auto_start);
this.beacon_controller.onAppReady();
this.app_model.changing_video = false;
return this.is_auto_start_request_pending = false;
}
};
AppController.prototype._loadContent = function(video_id) {
var adstate, params;
adstate = AppHelper.getCookie(Constants.COOKIE_KEYS.ADSTATE);
params = {
video_id: video_id,
guid: this.app_model.getComputerGUID(),
bitrate: AppHelper.preferredBitrate(),
embed: this.app_model.isEmbed(),
dp_id: this.app_model.getDistro(),
adstate: adstate ? adstate : ''
};
if (Constants.IS_SSL) {
params.require_ssl = true;
}
this.is_auto_start_request_pending = this.auto_start;
return AppHelper.getJSON(Constants.CONTENT_SELECT_URL, params, this._processContentResponse, this._djError);
};
AppController.prototype._djError = function(message) {
return EventBus.trigger(GeneralEvent.FATAL_ERROR, {
type: FatalError.DEEJAY_ERROR,
message: "DeeJay Error: " + JSON.stringify(message)
});
};
AppController.prototype._onFatalError = function(event, error) {
switch (error.type) {
case FatalError.DEEJAY_ERROR:
case FatalError.PLAYER_ERROR:
return EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, Constants.BEACONS.EVENTS.HTTP_ERROR), {
server_beacons: {
error_code: error.message,
fatal_failure: 1
}
});
}
};
AppController.prototype._clearReadyCheckTimer = function() {
if (this._ready_check_timer) {
return clearInterval(this._ready_check_timer);
}
};
AppController.prototype._processContentResponse = function(data) {
var _ref;
if (data['error']) {
switch (data['error']) {
case 'Video_expired':
EventBus.trigger(GeneralEvent.FATAL_ERROR, {
type: FatalError.VIDEO_EXPIRED
});
break;
case 'Geo restriction':
EventBus.trigger(GeneralEvent.FATAL_ERROR, {
type: FatalError.GEO_BLOCK
});
break;
default:
EventBus.trigger(GeneralEvent.FATAL_ERROR, {
type: FatalError.VIDEO_UNAVAILABLE
});
}
return;
}
this.app_model.setIsAdZone(data['cp_identifier'] === 'AdZone');
this.app_model.setContentID(data['content_id']);
this.app_model.setVideoID(data['site_id']);
this.app_model.setShowID(data['show_id']);
this.app_model.setSeriesTitle(data['tp_Series_Title']);
this.app_model.setEpisodeTitle(data['title']);
this.app_model.setEpisodeNumber(data['episode_number']);
this.app_model.setSeasonNumber(data['season_number']);
this.app_model.setServerBeacons(data['server_beacons']);
this.app_model.setAttr((_ref = data['adaudit_params']) != null ? _ref['attr'] : void 0);
this.app_model.setContentDuration(data['duration']);
this.app_model.setMinimumAge(data['min_age']);
this.app_model.setPackageID(data['package_id']);
this.app_model.setMozartEndpoint(data['mozart_endpoint']);
this.app_model.setMozartToken(data['mozart_token']);
this.app_model.setProgrammingType(data['programming_type']);
this.player_controller.processContentResponse(data);
this.beacon_controller.processContentResponse(data);
return AppHelper.setCookie(Constants.COOKIE_KEYS.ADSTATE, data['adstate'], {
seconds: 10 * 365 * 24 * 60 * 60
});
};
return AppController;
})();
VideoNetworkState = (function() {
function VideoNetworkState() {}
VideoNetworkState.NETWORK__EMPTY = 0;
VideoNetworkState.NETWORK_IDLE = 1;
VideoNetworkState.NETWORK_LOADING = 2;
VideoNetworkState.NETWORK_NO_SOURCE = 3;
return VideoNetworkState;
})();
VideoReadyState = (function() {
function VideoReadyState() {}
VideoReadyState.HAVE_NOTHING = 0;
VideoReadyState.HAVE_METADATA = 1;
VideoReadyState.HAVE_CURRENT_DATA = 2;
VideoReadyState.HAVE_FUTURE_DATA = 3;
VideoReadyState.HAVE_ENOUGH_DATA = 4;
return VideoReadyState;
})();
EventBus = (function() {
EventBus._instance = void 0;
function EventBus() {
if (EventBus._instance) {
throw new Error("EventBus instance already exists");
}
}
EventBus.getInstance = function() {
if (!(EventBus._instance != null)) {
EventBus._instance = new EventBus();
}
return EventBus._instance;
};
EventBus.on = function(event, callback) {
return $(this.getInstance()).on(event, callback);
};
EventBus.off = function(event, callback) {
return $(this.getInstance()).off(event, callback);
};
EventBus.trigger = function(event, data) {
return $(this.getInstance()).trigger(event, data);
};
return EventBus;
})();
VideoEvent = (function() {
function VideoEvent() {}
VideoEvent.LOAD_START = "loadstart";
VideoEvent.PROGRESS = "progress";
VideoEvent.SUSPEND = "suspend";
VideoEvent.ABORT = "abort";
VideoEvent.ERROR = "error";
VideoEvent.EMPTIED = "emptied";
VideoEvent.STALLED = "stalled";
VideoEvent.LOADED_METADATA = "loadedmetadata";
VideoEvent.LOADED_DATA = "loadeddata";
VideoEvent.CAN_PLAY = "canplay";
VideoEvent.CAN_PLAY_THROUGH = "canplaythrough";
VideoEvent.PLAYING = "playing";
VideoEvent.WAITING = "waiting";
VideoEvent.SEEKING = "seeking";
VideoEvent.SEEKED = "seeked";
VideoEvent.ENDED = "ended";
VideoEvent.DURATION_CHANGE = "durationchange";
VideoEvent.TIME_UPDATE = "timeupdate";
VideoEvent.PLAY = "play";
VideoEvent.PAUSE = "pause";
VideoEvent.ALL_EVENTS = [VideoEvent.LOAD_START, VideoEvent.PROGRESS, VideoEvent.SUSPEND, VideoEvent.ABORT, VideoEvent.ERROR, VideoEvent.EMPTIED, VideoEvent.STALLED, VideoEvent.LOADED_METADATA, VideoEvent.LOADED_DATA, VideoEvent.CAN_PLAY, VideoEvent.CAN_PLAY_THROUGH, VideoEvent.PLAYING, VideoEvent.WAITING, VideoEvent.SEEKING, VideoEvent.SEEKED, VideoEvent.ENDED, VideoEvent.DURATION_CHANGE, VideoEvent.TIME_UPDATE, VideoEvent.PLAY, VideoEvent.PAUSE];
return VideoEvent;
})();
AppModel = (function() {
AppModel.PLAYER_STATUS = "paused";
AppModel.BEACON_COUNTER = 0;
function AppModel(params) {
this._userID = this._extractUserID(params);
this._computerGUID = this._extractComputerGUID(params);
this._planID = this._extractPlanID(params);
this._siteSessionID = this._extractSiteSessionID(params);
this._referralURL = this._extractParam(params, 'referral_url', "");
this._initialEID = this._extractInitialEID(params);
this._autoStart = this._extractParam(params, 'auto_start');
this._loggingContainer = this._extractParam(params, 'logging_container');
this._embed = this._extractParam(params, 'embed', false);
this._panelPlatform = this._extractParam(params, 'panel_platform');
this._partner = this._extractParam(params, 'partner');
this._thumbnailTime = this._extractParam(params, 'it');
this._startTime = this._extractStartTime(params);
this._endTime = parseFloat(this._extractParam(params, 'et'));
this._embedURL = Md5.hex_md5(window.location.href);
this._sessionGUID = AppHelper.generateGUID();
this.resetBufferStats();
this.minimum_age_verified = false;
this.changing_video = false;
this._has_played_through = false;
this.first_play = true;
AppModel.CONTENT_MARKETING_CAMPAIGN = params['cmc'];
this.updateParams(params);
}
AppModel.prototype.updateParams = function(params) {
this._pageType = this._extractParam(params, 'pagetype', "");
this._pageName = this._extractParam(params, 'pagename', "");
this._socialIdentities = this._extractParam(params, 'socialidentities', []);
this._playerMode = this._extractParam(params, 'playermode', "normal");
this._siteVersion = this._extractParam(params, 'siteversion', "");
this._trackingSource = this._extractParam(params, 'trackingsource', {});
this._donutParams = this._extractParam(params, 'donutparams', {});
this._distroPlatform = this._extractParam(params, 'distroplatform', "HTML5");
this._orientation = this._extractParam(params, 'orientation', "");
return this._beaconDistro = null;
};
AppModel.prototype.getUserID = function() {
return this._userID;
};
AppModel.prototype.getComputerGUID = function() {
return this._computerGUID;
};
AppModel.prototype.getPlanID = function() {
return this._planID;
};
AppModel.prototype.getSiteSessionID = function() {
var _ref;
if (!this.isEmbed() && (((_ref = window.Player) != null ? _ref.getSiteSessionId : void 0) != null)) {
this._siteSessionID = window.Player.getSiteSessionId();
}
return this._siteSessionID;
};
AppModel.prototype.getReferralURL = function() {
return this._referralURL;
};
AppModel.prototype.getInitialEID = function() {
return this._initialEID;
};
AppModel.prototype.isAutoStart = function() {
return this._autoStart;
};
AppModel.prototype.getLoggingContainer = function() {
return this._loggingContainer;
};
AppModel.prototype.isEmbed = function() {
return this._embed;
};
AppModel.prototype.getPanelPlatform = function() {
return this._panelPlatform;
};
AppModel.prototype.getPartner = function() {
return this._partner;
};
AppModel.prototype.getThumbnailTime = function() {
return this._thumbnailTime;
};
AppModel.prototype.getStartTime = function() {
return this._startTime;
};
AppModel.prototype.getEndTime = function() {
return this._endTime;
};
AppModel.prototype.getEmbedURL = function() {
return this._embedURL;
};
AppModel.prototype.getSessionGUID = function() {
return this._sessionGUID;
};
AppModel.prototype.getPlayerMode = function() {
return this._playerMode;
};
AppModel.prototype.getOrientation = function() {
return this._orientation;
};
AppModel.prototype.getSocialIdentities = function() {
if (this._socialIdentities.length > 0) {
return this._socialIdentities.join(',');
} else {
return "";
}
};
AppModel.prototype.getSiteVersion = function() {
return this._siteVersion;
};
AppModel.prototype.getTrackingSource = function(type) {
var _ref;
if (((_ref = this._trackingSource) != null ? _ref[type] : void 0) != null) {
return this._trackingSource[type];
} else {
return "";
}
};
AppModel.prototype.getDonutParams = function() {
var donutParams, key, value, _ref;
donutParams = [];
_ref = this._donutParams;
for (key in _ref) {
value = _ref[key];
donutParams.push(key + '=' + value);
}
if (donutParams.length > 0) {
return '&' + donutParams.join('&');
}
return "";
};
AppModel.prototype.getPageType = function() {
return this._pageType;
};
AppModel.prototype.getPageName = function() {
return this._pageName;
};
AppModel.prototype.isAdZone = function() {
return this.adzone;
};
AppModel.prototype.getDistroPlatform = function() {
if (this.isEmbed()) {
return "HTML5_Embed";
} else {
return this._distroPlatform;
}
};
AppModel.prototype.getDistro = function() {
if (this.getPartner() != null) {
return this.getPartner().toLowerCase();
}
return "hulu";
};
AppModel.prototype.getBeaconDistro = function() {
if (this._beaconDistro === null) {
this._beaconDistro = this._getBeaconDistro();
}
return this._beaconDistro;
};
AppModel.prototype.getVisit = function() {
var current_visit;
if (!(this._visit != null)) {
try {
current_visit = AppHelper.getCookie(Constants.COOKIE_KEYS.VISIT);
if (current_visit != null) {
current_visit = parseInt(current_visit);
current_visit = (isNaN(current_visit) ? 0 : current_visit) + 1;
} else {
current_visit = 1;
}
this._visit = current_visit;
AppHelper.setCookie(Constants.COOKIE_KEYS.VISIT, current_visit, {
seconds: 2 * 60 * 60
});
} catch (_error) {}
}
return this._visit;
};
AppModel.prototype.canAutoPlay = function() {
var _ref, _ref1;
if (this.isEmbed()) {
return false;
}
if (AppHelper.isIOS()) {
return false;
}
if (AppHelper.isPhone()) {
return false;
}
return typeof Hulu !== "undefined" && Hulu !== null ? (_ref = Hulu.Controls) != null ? (_ref1 = _ref.MobileDevice) != null ? _ref1.isHtml5Autoplay() : void 0 : void 0 : void 0;
};
AppModel.prototype.setIsAdZone = function(adzone) {
this.adzone = adzone;
};
AppModel.prototype.setContentID = function(content_id) {
this.content_id = content_id;
};
AppModel.prototype.setVideoID = function(video_id) {
this.video_id = video_id;
};
AppModel.prototype.setShowID = function(show_id) {
this.show_id = show_id;
};
AppModel.prototype.setSeriesTitle = function(series_title) {
this.series_title = series_title;
};
AppModel.prototype.setEpisodeTitle = function(episode_title) {
this.episode_title = episode_title;
};
AppModel.prototype.setEpisodeNumber = function(episode_number) {
this.episode_number = episode_number;
};
AppModel.prototype.setSeasonNumber = function(season_number) {
this.season_number = season_number;
};
AppModel.prototype.setServerBeacons = function(server_beacons) {
this.server_beacons = server_beacons;
};
AppModel.prototype.setAttr = function(attr) {
this.attr = attr;
};
AppModel.prototype.setContentDuration = function(content_duration) {
this.content_duration = content_duration;
};
AppModel.prototype.setMinimumAge = function(minimum_age) {
this.minimum_age = minimum_age;
};
AppModel.prototype.setPackageID = function(package_id) {
this.package_id = package_id;
};
AppModel.prototype.setMozartEndpoint = function(mozart_endpoint) {
this.mozart_endpoint = mozart_endpoint;
};
AppModel.prototype.setMozartToken = function(mozart_token) {
this.mozart_token = mozart_token;
};
AppModel.prototype.setProgrammingType = function(programming_type) {
this.programming_type = programming_type;
};
AppModel.prototype.reset = function() {
this.video_eid = null;
this._has_played_through = !this.changing_video;
AppModel.BEACON_COUNTER = 0;
this._sessionGUID = AppHelper.generateGUID();
return this.resetBufferStats();
};
AppModel.prototype.hasPlayedThrough = function() {
return this._has_played_through;
};
AppModel.prototype.markAsPlayedThrough = function() {
return this._has_played_through = true;
};
AppModel.prototype.resetBufferStats = function() {
this._buffer_start_time = void 0;
this.buffer_count = 0;
return this.buffer_time = 0;
};
AppModel.prototype.onPlayerStartBuffer = function() {
this._buffer_start_time = new Date().getTime();
return this.buffer_count++;
};
AppModel.prototype.onPlayerEndBuffer = function() {
var now, time;
if (this._buffer_start_time === void 0) {
Logger.warn("Buffer never started");
}
now = new Date().getTime();
time = now - this._buffer_start_time;
return this.buffer_time += time;
};
AppModel.prototype.ageRestricted = function() {
var restricted;
restricted = (this.minimum_age != null) && !this.minimum_age_verified;
if (restricted) {
if (AppHelper.getCookie(Constants.COOKIE_KEYS.AGE_CHECK + this.minimum_age.toString())) {
return false;
}
}
return restricted;
};
AppModel.prototype.verifyAge = function(birthdate) {
var current_date;
current_date = new Date();
current_date.setFullYear(current_date.getFullYear() - this.minimum_age);
if (current_date - birthdate > 0) {
AppHelper.setCookie(Constants.COOKIE_KEYS.AGE_CHECK + this.minimum_age.toString(), true, {
seconds: 7 * 24 * 60 * 60
});
return true;
} else {
return false;
}
};
AppModel.prototype._extractUserID = function(params) {
if (((params != null ? params['user_id'] : void 0) != null) && params['user_id'] >= 0) {
return params['user_id'];
} else {
return 0;
}
};
AppModel.prototype._extractComputerGUID = function(params) {
var computer_guid;
if ((params != null ? params['computer_guid'] : void 0) != null) {
return params['computer_guid'];
} else {
computer_guid = AppHelper.getCookie(Constants.COOKIE_KEYS.HULU_GUID);
if (!(computer_guid != null)) {
computer_guid = AppHelper.generateGUID();
}
AppHelper.setCookie(Constants.COOKIE_KEYS.HULU_GUID, computer_guid, {
seconds: 10 * 365 * 24 * 60 * 60
});
return computer_guid;
}
};
AppModel.prototype._extractPlanID = function(params) {
if (((params != null ? params['plan_id'] : void 0) != null) && params['plan_id'] > 0) {
return params['plan_id'];
} else {
return 0;
}
};
AppModel.prototype._extractSiteSessionID = function(params) {
var site_session_id;
site_session_id = this._extractParam(params, 'site_session_id');
if (site_session_id != null) {
return site_session_id;
} else {
return AppHelper.generateGUID();
}
};
AppModel.prototype._extractInitialEID = function(params) {
var _ref;
if ((params != null ? (_ref = params['video']) != null ? _ref['eid'] : void 0 : void 0) != null) {
return params['video']['eid'];
}
};
AppModel.prototype._extractStartTime = function(params) {
var start_time;
start_time = this._extractParam(params, 'st');
if (start_time) {
return parseFloat(start_time);
}
return 0;
};
AppModel.prototype._extractParam = function(params, name, defaultValue) {
if ((params != null ? params[name] : void 0) != null) {
return params[name];
}
return defaultValue;
};
AppModel.prototype._getBeaconDistro = function() {
var domainPattern, host, results;
if (this._referralURL !== null && this._referralURL !== "") {
host = "";
domainPattern = /^(\w+:\/\/)?[\w+-.]+(?=(\/|:\d+))/;
results = domainPattern.exec(this._referralURL);
if (results !== null) {
host = results[0];
}
if (host.search(/^(.)*facebook\.com/g) >= 0) {
return "facebook";
} else if (host.search(/^(.)*(twimg|twitter)\.com/g) >= 0) {
return "twitter";
}
}
if (this.getPartner() != null) {
if (this.getPartner().toLowerCase() === "edp") {
return "Express";
}
return this.getPartner().toLowerCase();
}
return this.getDistro();
};
return AppModel;
})();
EndCardAdModel = (function() {
function EndCardAdModel(data) {
var cb_url, _ref;
cb_url = data["cb"];
if (this._isValidUrl(cb_url)) {
this.cb_url = cb_url;
this.cb_clickthrough = data["cb_clickthrough"];
this.pod = data["pod"] || -1;
this.cb_server_beacons = ((_ref = data["server_beacons"]) != null ? _ref["cb"] : void 0) || {};
this.cb_audits = data["cb_audits"];
}
}
EndCardAdModel.prototype._isValidUrl = function(url) {
return url !== null && url.indexOf("http") === 0;
};
EndCardAdModel.prototype.companionViewed = function() {
if (!this._cb_viewed) {
this._cb_viewed = true;
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.REVENUE, Constants.BEACONS.EVENTS.ASSET_IMPRESSION), {
pod_text: "" + this.pod + "_1_a",
server_beacons: this.cb_server_beacons
});
return this._trackCbAudits();
}
};
EndCardAdModel.prototype.companionClicked = function() {
return EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.AD_INTERACTION, Constants.BEACONS.EVENTS.CLICK), {
pod_text: "" + this.pod + "_1_a",
server_beacons: this.cb_server_beacons
});
};
EndCardAdModel.prototype._trackCbAudits = function() {
var audit, url, _i, _len, _ref, _results;
if (this.cb_audits !== null && this.cb_audits.length > 0) {
_ref = this.cb_audits;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
audit = _ref[_i];
url = audit.url;
if (url !== null && Constants.IS_SSL && url.indexOf("http://") === 0) {
url = url.replace(/^http:/i, "https:");
}
_results.push(BeaconHelper.sendBeacon(url));
}
return _results;
}
};
return EndCardAdModel;
})();
PlaylistPlayerModel = (function(_super) {
__extends(PlaylistPlayerModel, _super);
function PlaylistPlayerModel(app_model) {
this.app_model = app_model;
this._updateAdTopBar = __bind(this._updateAdTopBar, this);
PlaylistPlayerModel.__super__.constructor.call(this, this.app_model);
}
PlaylistPlayerModel.prototype.reset = function() {
PlaylistPlayerModel.__super__.reset.call(this);
this.last_reported_time = 0;
return this.elapsed_break_time = 0;
};
PlaylistPlayerModel.prototype.processContentResponse = function(data) {
var ad, ads, b, break_pos, breaks, broadKind, content, max_end_marker, ori_play_pos, pod, podNum, pods, preroll, shift, shifted_play_pos, _i, _len, _ref, _ref1;
this.is_done = false;
this.start_marker = Math.max(this.app_model.getStartTime() / 1000, 0);
this.full_stream_duration = max_end_marker = parseFloat(data['duration']) / 1000;
this.end_marker = this.app_model.getEndTime() / 1000 || max_end_marker;
this.end_marker = Math.min(this.end_marker, max_end_marker);
this.playlist_url = data['stream_url'];
shift = 0;
this.intro_dur = 0;
content = new ContentModel(data['all_bitrate_urls'], this.end_marker - this.start_marker, this.start_marker, this.end_marker, data['content_id']);
breaks = [];
break_pos = [];
pods = {};
_ref = data['breaks'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
broadKind = b['kind'].split(':');
ori_play_pos = b['pos'] / 1000;
shifted_play_pos = ori_play_pos + shift;
break_pos.push(ori_play_pos);
this.full_stream_duration += b['duration'] / 1000;
switch (broadKind[0]) {
case "preroll":
case "postroll":
if (broadKind[0] === "preroll") {
this.intro_dur += b['duration'] / 1000;
}
preroll = new PrerollModel(b['all_bitrate_urls'], shifted_play_pos, b['duration'] / 1000, b['can_seek']);
preroll.server_beacons = b['server_beacons'];
preroll.ori_play_pos = ori_play_pos;
breaks.push(preroll);
break;
case "ad":
this.total_ad_duration += b['duration'] / 1000;
ad = new AdModel(b['all_bitrate_urls'], b['duration'] / 1000, b['can_seek']);
ad.flight_id = b['flight_id'];
ad.ad_unit_id = b['ad_unit_id'];
if (b['audits']) {
ad.audits = b['audits'];
}
ad.server_beacons = b['server_beacons'];
ad.ad_unit_type = b['ad_unit_type'];
if ((_ref1 = b['pod']) === 0 || _ref1 === 1) {
this.intro_dur += b['duration'] / 1000;
}
podNum = b['pod'];
if (!pods[podNum]) {
pods[podNum] = new AdPodModel(shifted_play_pos, podNum);
}
pods[podNum].addAd(ad);
pods[podNum].ori_play_pos = ori_play_pos;
break;
default:
Logger.error(["unknown content type", b]);
}
shift += b['duration'] / 1000;
}
for (pod in pods) {
ads = pods[pod];
if (ads !== void 0) {
breaks.push(ads);
}
}
content.play_pos = this.intro_dur;
content.setBreakPos(break_pos);
this.setContent(content);
this.setBreaks(breaks);
this.dynamic_bug_br = data['dynamic_bug_br'];
if (data['end_card']) {
this.end_card_ad_model = new EndCardAdModel(data['end_card']);
}
return $(this).trigger(PlayerModel.Events.ProcessContentDone);
};
PlaylistPlayerModel.prototype.findNextToPlay = function() {
var b, new_playable, _i, _len, _ref;
new_playable = void 0;
if (this.current_break !== void 0 && this.current_break.play_pos <= this.last_reported_time && this.current_break.play_pos + this.current_break.getDuration() > this.last_reported_time) {
this.in_break = true;
this.last_total_time_playing_ad = this.content.total_time_playing;
new_playable = this.current_break;
} else {
if (this.breaks != null) {
_ref = this.breaks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if (b.play_pos <= this.last_reported_time && b.play_pos + b.getDuration() > this.last_reported_time) {
this.in_break = true;
this.current_break = b;
this.last_total_time_playing_ad = this.content.total_time_playing;
new_playable = b;
break;
}
}
}
}
if (!(new_playable != null)) {
this.in_break = false;
if ((this.content != null) && !this.content.played) {
new_playable = this.content;
}
}
if (this._current_playable != null) {
$(this._current_playable).off(PlayableModel.Events.UpdateAdTopBar, this._updateAdTopBar);
}
this._current_playable = new_playable;
if (this._current_playable != null) {
$(this._current_playable).on(PlayableModel.Events.UpdateAdTopBar, this._updateAdTopBar);
}
return new_playable;
};
PlaylistPlayerModel.prototype.checkForSkippedAds = function(current_position, new_position) {};
PlaylistPlayerModel.prototype._updateAdTopBar = function(event, data) {
var other_playable, _ref, _ref1;
if (data['show'] === true) {
if ((_ref = (_ref1 = this._current_playable) != null ? _ref1.pod_num : void 0) === 0 || _ref === 1) {
if (this._current_playable.pod_num === 0) {
other_playable = this.getPod(1);
if (other_playable != null) {
data['remaining'] += Math.round(other_playable.getDuration());
}
} else {
other_playable = this.getPod(0);
if (other_playable != null) {
data['ad_num'] += other_playable.ads.length;
}
}
if (other_playable != null) {
data['ad_num_total'] = this._current_playable.ads.length + other_playable.ads.length;
}
}
}
return $(this).trigger(PlayerModel.Events.UpdateAdTopBar, data);
};
PlaylistPlayerModel.prototype.playStarted = function() {
if (this.isInContentState()) {
return this._current_playable.setPosition(0);
}
};
PlaylistPlayerModel.prototype.getPlayInfo = function(preferred_bitrates) {
var position;
position = this.isInContentState() ? this.getShiftedContentPosition(this.content.getPosition()) : (this._current_playable ? this._current_playable.play_pos + this._current_playable.getPosition() : 0);
return [AppHelper.preferredBitrate(), this.playlist_url, position, this.canSeek()];
};
PlaylistPlayerModel.prototype.timeUpdate = function(time) {
var playable, prct, _ref;
this._updateTotalTime();
this.last_reported_time = time;
playable = void 0;
if (this.isInBreakState()) {
this._current_playable.timeUpdate(time - this._current_playable.play_pos);
if (this._current_playable instanceof AdPodModel) {
playable = this._current_playable.getCurrentAd();
} else {
playable = this._current_playable;
}
if (playable.getTimeRemaining() <= 0) {
this.elapsed_break_time += playable.getDuration();
}
} else {
if (this.last_reported_time < this.getShiftedContentPosition(this.start_marker)) {
this.last_reported_time = this.getShiftedContentPosition(this.start_marker);
prct = (this.last_reported_time - this._current_playable.play_pos) / this._current_playable.getDuration();
EventBus.trigger(ControlsView.Events.Seek, {
percent: prct,
full_stream: true
});
}
if ((_ref = this._current_playable) != null) {
_ref.timeUpdate(this.getOriginContentPosition(this.last_reported_time));
}
playable = this._current_playable;
}
if (playable != null) {
if (!playable.fired_start) {
playable.playStarted();
}
if (playable.getTimeRemaining() <= 0) {
$(this).trigger(PlaylistPlayerModel.Events.SegmentFinished);
}
}
};
PlaylistPlayerModel.prototype.getBreaksForDots = function() {
var b, breaks, percent, _i, _len, _ref;
breaks = [];
_ref = this.breaks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if (b.ori_play_pos - this.start_marker > 0 && b.ori_play_pos < this.content.getDuration()) {
percent = (b.ori_play_pos - this.start_marker) / this.content.getDuration() * 100;
breaks.push({
location: percent,
active: b === this._current_playable
});
}
}
return breaks;
};
PlaylistPlayerModel.prototype.getOriginContentPosition = function(shiftedPosition) {
var b, shift, _i, _len, _ref;
shift = 0;
_ref = this.breaks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if (b.play_pos <= shiftedPosition) {
if (b.play_pos + b.getDuration() <= shiftedPosition) {
shift += b.getDuration();
} else {
shift += shiftedPosition - b.play_pos;
}
}
}
return shiftedPosition - shift;
};
PlaylistPlayerModel.prototype.getShiftedContentPosition = function(originPosition) {
var b, shifted_pos, _i, _len, _ref;
shifted_pos = originPosition;
_ref = this.breaks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if (b.ori_play_pos <= originPosition) {
shifted_pos += b.getDuration();
}
}
return shifted_pos;
};
PlaylistPlayerModel.prototype.timeIsInCurrentRange = function(time) {
var b, _i, _len, _ref;
if (!this._current_playable) {
return false;
}
if (!this.isInContentState()) {
return this._current_playable.play_pos <= time && this._current_playable.play_pos + this._current_playable.getDuration() > time;
} else {
_ref = this.breaks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
b = _ref[_i];
if (b.play_pos <= time && b.play_pos + b.getDuration() > time) {
return false;
}
}
time = this.getOriginContentPosition(time);
return 0 <= time && time <= this.content.getDuration();
}
};
PlaylistPlayerModel.Events = {
SegmentFinished: "PlaylistPlayerModel.Events.SegmentFinished"
};
return PlaylistPlayerModel;
})(PlayerModel);
EndCardPlaylist = (function() {
EndCardPlaylist.ITEMS_PER_PAGE = 32;
function EndCardPlaylist(app_model) {
this.app_model = app_model;
this.current_position = 0;
this.current_page = 0;
this.total_count = 0;
this.items = [];
}
EndCardPlaylist.prototype.currentItem = function() {
if (this.current_position < this.items.length) {
return this.items[this.current_position];
} else {
return null;
}
};
EndCardPlaylist.prototype.next = function() {
Math.min(this.total_count - 1, ++this.current_position);
if (this.current_position + 5 >= this.items.length && this.items.length !== this.total_count) {
return _retrieveVideos();
}
};
EndCardPlaylist.prototype.previous = function() {
return Math.max(0, --this.current_position);
};
EndCardPlaylist.prototype.hasNext = function() {
return this.current_position < this.total_count - 1;
};
EndCardPlaylist.prototype.hasPrevious = function() {
return this.current_position > 0;
};
EndCardPlaylist.prototype.currentContentId = function() {
return this.app_model.content_id;
};
EndCardPlaylist.prototype._retrieveVideos = function() {};
return EndCardPlaylist;
})();
GlobalErrorHandler = (function() {
function GlobalErrorHandler() {}
GlobalErrorHandler.Events = {
Types: {
SITE: "site"
},
SubTypes: {
JAVASCRIPT: "javascript",
AJAX: "ajax"
}
};
GlobalErrorHandler.isSampled = false;
GlobalErrorHandler.stackTraceEnabled = false;
GlobalErrorHandler.lastScriptErrorLogged = false;
GlobalErrorHandler.sentEmptyWindowOnErrorException = false;
GlobalErrorHandler.rateLimiterMaxPostPerPeriod = 10;
GlobalErrorHandler.rateLimiterPeriodInSeconds = 600;
GlobalErrorHandler.postedErrorTimestamps = [];
GlobalErrorHandler.oldOn = $.fn.on;
GlobalErrorHandler.oldSetTimeout = window.setTimeout;
GlobalErrorHandler.oldReady = $.fn.ready;
GlobalErrorHandler.oldAjax = $.ajax;
GlobalErrorHandler.initialize = function(app_model) {
var sampleRate;
this.app_model = app_model;
sampleRate = parseFloat(AppHelper.getCookie(Constants.COOKIE_KEYS.ERROR_SAMPLE_RATE));
if (isNaN(sampleRate)) {
sampleRate = 1;
}
GlobalErrorHandler.isSampled = GlobalErrorHandler.isEnableErrorLogging(sampleRate);
GlobalErrorHandler.stackTraceEnabled = !(($.browser.webkit && !window.chrome) || $.browser.msie) && (typeof printStackTrace !== "undefined" && printStackTrace !== null);
if (!GlobalErrorHandler.stackTraceEnabled) {
window.printStackTrace = function() {
return null;
};
}
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {
if (!jqXHR.__failHandled && ajaxSettings.async) {
return GlobalErrorHandler.postAjaxError(ajaxSettings, jqXHR, "Unhandled AJAX error");
}
});
/*
Instrument on window.setTimeout
*/
window.setTimeout = function(func, millisec) {
var newFunc;
newFunc = func;
if (func instanceof Function) {
newFunc = GlobalErrorHandler.proxy(func);
}
return GlobalErrorHandler.oldSetTimeout.apply(this, [newFunc].concat([].slice.apply(arguments).slice(1)));
};
/*
Instrument on jquery .on(), which is invoked by bind/click/etc.
*/
$.fn.on = function(types, selector, data, fn, one) {
var fnIndex, newArgs;
if (typeof types !== "object") {
newArgs = Array.prototype.slice.call(arguments);
fnIndex = -1;
if (!(data != null) && !(fn != null)) {
fnIndex = 1;
} else if (fn == null) {
fnIndex = 2;
} else {
fnIndex = 3;
}
if (fnIndex >= 0) {
newArgs[fnIndex] = GlobalErrorHandler.proxy(newArgs[fnIndex]);
}
return GlobalErrorHandler.oldOn.apply(this, arguments);
} else {
return GlobalErrorHandler.oldOn.apply(this, arguments);
}
};
/*
Instrument on jquery dom ready function
*/
$.fn.ready = function(fn) {
if (fn instanceof Function) {
fn = GlobalErrorHandler.proxy(fn);
}
return GlobalErrorHandler.oldReady.call(this, fn);
};
window.onerror = function(message, url, lineNumber) {
var $;
if (typeof $ === "undefined") {
$ = jQuery;
}
if (!GlobalErrorHandler.lastScriptErrorLogged) {
try {
if (message instanceof ErrorEvent) {
url = message.filename;
lineNumber = message.lineno;
message = "ErrorEvent: " + message.message;
} else {
if (message instanceof Event) {
message = "Event: " + message.type;
}
}
} catch (_error) {}
GlobalErrorHandler.postError({
type: GlobalErrorHandler.Events.Types.SITE,
subType: GlobalErrorHandler.Events.SubTypes.JAVASCRIPT,
message: message + "; at: " + url + ", " + lineNumber,
internalReceiver: "window.onerror",
details: {
windowOnErrorMessage: (message != null ? message.toString() : null),
windowOnErrorURL: url,
windowOnErrorLineNumber: lineNumber
}
});
}
return GlobalErrorHandler.lastScriptErrorLogged = false;
};
return $.ajax = function() {
var jqXHR, oldDone, oldFail;
jqXHR = GlobalErrorHandler.oldAjax.apply(this, arguments);
oldDone = jqXHR.done;
oldFail = jqXHR.fail;
jqXHR.done = function(doneCallback) {
var newCallback;
if (arguments.length > 1) {
throw new ArgumentError("doneCallback", "deferred.done() only support one callback for now!");
}
newCallback = doneCallback;
if ((doneCallback != null) && GlobalErrorHandler.stackTraceEnabled) {
if (!(doneCallback instanceof Function)) {
Logger.warn(".done() should get a function as callback");
} else {
newCallback = function() {
try {
return doneCallback.apply(this, arguments);
} catch (e) {
return GlobalErrorHandler.logError(e);
}
};
}
}
return oldDone.call(this, newCallback);
};
jqXHR.fail = function() {
jqXHR.__failHandled = true;
return oldFail.apply(this, arguments);
};
jqXHR.__failHandled = false;
jqXHR.__stackTrace = printStackTrace({
guess: false
});
return jqXHR;
};
};
GlobalErrorHandler.isEnableErrorLogging = function(sampleRate) {
/*
sampleRate = parseFloat(sampleRate)
if not isNaN(sampleRate) and sampleRate > 0
guid = Hulu.Behaviors.getComputerGUID() # TODO: Hulu.Behaviors.getComputerGUID() isn't defined
guidInt = parseInt(guid.substr(24), 16)
return guidInt % 1000000 < sampleRate * 1000000
false
*/
return true;
};
GlobalErrorHandler.logError = function(e, customMessage) {
var message, stackTrace;
if (!(e != null) || e._posted) {
return;
}
message = e.toString();
if ((customMessage != null) && customMessage !== "") {
message = customMessage + "\n" + message;
}
stackTrace = printStackTrace({
e: e,
guess: true
});
if (stackTrace != null) {
stackTrace = stackTrace.join("\n");
}
try {
e._posted = true;
} catch (_error) {}
return GlobalErrorHandler.postError({
type: GlobalErrorHandler.Events.Types.SITE,
subType: GlobalErrorHandler.Events.SubTypes.JAVASCRIPT,
message: message,
stackTrace: stackTrace,
internalReceiver: "logError"
});
};
GlobalErrorHandler.inBlacklist = function(error) {
var messagePatterns, urlPatterns;
if (error == null) {
return false;
}
messagePatterns = ["uncaught error: can't load xregexp twice in the same frame", "setreturnvalue", "originalCreateNotification", "schema_generated_bindings", "miscellaneous_bindings", /chrome:\/\//i, "http://www.superfish.com/", "http://www.google-analytics.com/ga.js", "_leaflycbfunc", /C:\/Users\//, "http://www.hulu.com/PIE.htc"];
if ((error.message != null) && AppHelper.isStringMatchPatterns(messagePatterns, error.message.toString(), true)) {
return true;
}
urlPatterns = ["http://www.superfish.com/", "http://www.google-analytics.com/ga.js", "http://s.hulu.com/gc", /^chrome:\/\//i, /^resource:\/\//i];
return (error.details != null) && (error.details.windowOnErrorURL != null) && AppHelper.isStringMatchPatterns(urlPatterns, error.details.windowOnErrorURL.toString(), true);
};
GlobalErrorHandler.isEmptyWindowOnErrorException = function(error) {
return (error != null) && (error.details != null) && (error.details.windowOnErrorMessage != null) && error.details.windowOnErrorMessage.toString().toLowerCase() === "script error." && (!(error.details.windowOnErrorURL != null) || error.details.windowOnErrorURL === "") && error.details.windowOnErrorLineNumber === 0;
};
GlobalErrorHandler.isRateLimited = function() {
var oldestAllowed;
oldestAllowed = (new Date()).getTime() - GlobalErrorHandler.rateLimiterPeriodInSeconds * 1000;
while (GlobalErrorHandler.postedErrorTimestamps.length > 0 && GlobalErrorHandler.postedErrorTimestamps[0] < oldestAllowed) {
GlobalErrorHandler.postedErrorTimestamps.shift();
}
return GlobalErrorHandler.postedErrorTimestamps.length >= GlobalErrorHandler.rateLimiterMaxPostPerPeriod;
};
GlobalErrorHandler.getContext = function() {
var _ref, _ref1, _ref2, _ref3;
return {
client: BeaconHelper.getBrowserVersion(),
computerguid: ((_ref = this.app_model) != null ? _ref.getComputerGUID() : void 0) != null ? this.app_model.getComputerGUID() : void 0,
deviceid: Constants.DEVICE_ID,
distro: 'hulu',
distroplatform: 'hulu',
language: 'en',
os: BeaconHelper.getDeviceOS(),
pageurl: window.location.href,
region: 'US',
referrerurl: ((_ref1 = this.app_model) != null ? _ref1.getReferralURL() : void 0) != null ? this.app_model.getReferralURL() : void 0,
sitesessionid: ((_ref2 = this.app_model) != null ? _ref2.getSiteSessionID() : void 0) != null ? this.app_model.getSiteSessionID() : void 0,
userid: ((_ref3 = this.app_model) != null ? _ref3.getUserID() : void 0) != null ? this.app_model.getUserID() : void 0
};
};
/*
@author yun.zheng for h2o -- revised by arash for html5 player
<p>This file is for handling errors (both script error and AJAX error) globally.</p>
<p>For script error, since IE/Safiri doesn't support error stack trace:</p>
<li>1. If it's not IE or Safari, then the errors thrown within the functions wrapped by @proxy
will be caught and log to server with error message and stack trace, and the other error will be
handled by window.onerror and log to server with only message (+url&line number)</li>
<li>2. If it's IE or Safari, then all the errors will be handled by window.onerror and log to server with
only message (+url&line number)</li>
<p>For AJAX error:</p>
<li>If it's already handled by developers with <b>.fail()</b>, then it won't log any error here.</li>
<li>If it's NOT handled by developers already with <b>.fail()</b>, then it will log AJAX error to server.
And if the stack trace is enabled, the stack trace of firing the AJAX request will be logged as well</li>
*/
/*
Post ajax error to error log service. Should be used in ajax fail handler. Example:
<p>
$.ajax(url).fail(function(jqXHR) {
// error handling
GlobalErrorHandler.postAjaxError(this, jqXHR);
});
</p>
@param {object} ajaxSettings The ajax setting, should be the native context of fail handler.
@param {object} jqXHR The ajax object, should be the first parameter of fail handler
@param {string} errorTitle The title to post together with ajax error
*/
GlobalErrorHandler.postAjaxError = function(ajaxSettings, jqXHR, errorTitle) {
var message, requestType, requestURL, stackTrace, status, statusText, _ref, _ref1;
if ((jqXHR != null) && (ajaxSettings != null)) {
errorTitle = (errorTitle != null ? errorTitle : "");
message = errorTitle + ":\nAJAX error: status " + jqXHR.status + " " + jqXHR.statusText + ", type " + ajaxSettings.type + ", url " + ajaxSettings.url;
stackTrace = null;
if (jqXHR.__stackTrace != null) {
stackTrace = "The AJAX request is fired at:\n" + jqXHR.__stackTrace.join("\n");
}
requestURL = null;
requestType = null;
if (typeof ajaxSettings !== "undefined") {
requestURL = (typeof ajaxSettings.url !== "undefined" ? ajaxSettings.url : null);
requestType = (typeof ajaxSettings.type !== "undefined" ? ajaxSettings.type : null);
}
if ((_ref = Constants.DOPPLER_URLS) != null ? (_ref1 = _ref.regex) != null ? _ref1.test(requestURL) : void 0 : void 0) {
return;
}
status = null;
statusText = null;
if (typeof jqXHR !== "undefined") {
status = (typeof jqXHR.status !== "undefined" ? jqXHR.status : null);
statusText = (typeof jqXHR.statusText !== "undefined" ? jqXHR.statusText : null);
}
return GlobalErrorHandler.postError({
type: GlobalErrorHandler.Events.Types.SITE,
subType: GlobalErrorHandler.Events.SubTypes.AJAX,
message: message,
stackTrace: stackTrace,
internalReceiver: "Hulu.Error.postAjaxError",
details: {
ajaxRequestURL: requestURL,
ajaxRequestType: requestType,
ajaxStatus: status,
ajaxStatusText: statusText
}
});
}
};
/*
Takes a function and returns a new one that will log script error and always have a particular context
Will fallback to jQuery.proxy if error logging is not enabled
@param {function} fn Function to log error
@param {object} context The context for the function
@returns {function} The wrapped function
*/
GlobalErrorHandler.proxy = function(fn, context) {
if (!GlobalErrorHandler.stackTraceEnabled) {
return $.proxy(fn, context);
}
return function() {
if (context == null) {
context = this;
}
try {
return fn.apply(context, arguments);
} catch (e) {
if (!GlobalErrorHandler.lastScriptErrorLogged) {
GlobalErrorHandler.logError(e);
}
GlobalErrorHandler.lastScriptErrorLogged = true;
throw e;
}
};
};
/*
Function that POSTs errors to doppler. The error must be an object of the
following format. All attributes are optional, including "details."
{
type: String (see Error.Types),
subType: String (see Error.SubTypes),
message: String,
stackTrace: String,
internalReceiver: String,
details: {
ajaxRequestURL: String,
ajaxRequestType: String,
ajaxStatus: Number,
ajaxStatusText: String,
windowOnErrorMessage: String,
windowOnErrorURL: String,
windowOnErrorLineNumber: Number
}
}
@param {Object} error (see above)
*/
GlobalErrorHandler.postError = function(error) {
var context, _ref;
if (error == null) {
return;
}
if (!GlobalErrorHandler.isSampled) {
return;
}
if (GlobalErrorHandler.isEmptyWindowOnErrorException(error)) {
if (GlobalErrorHandler.sentEmptyWindowOnErrorException) {
return;
}
GlobalErrorHandler.sentEmptyWindowOnErrorException = true;
}
if (GlobalErrorHandler.isRateLimited()) {
return;
}
GlobalErrorHandler.postedErrorTimestamps.push((new Date()).getTime());
context = GlobalErrorHandler.getContext();
$.extend(context, {
jqueryVersion: $.fn.jquery,
playerVersion: Constants.VERSION
});
if ((((_ref = Constants.DOPPLER_URLS) != null ? _ref.ingest : void 0) != null) && !GlobalErrorHandler.inBlacklist(error)) {
return $.ajax({
type: "POST",
url: Constants.DOPPLER_URLS.ingest,
data: {
context: JSON.stringify(context),
error: JSON.stringify(error)
}
}).fail(function() {
return Logger.warn("Error log service should not fail!");
}).done(function(response) {
var newRate;
if ((response != null) && (response["sampleRate"] != null)) {
newRate = parseFloat(response["sampleRate"]);
GlobalErrorHandler.isSampled = !isNaN(newRate) && GlobalErrorHandler.isEnableErrorLogging(newRate);
if (!isNaN(newRate)) {
return AppHelper.setCookie(Constants.COOKIE_KEYS.ERROR_SAMPLE_RATE, newRate);
}
}
});
}
};
/*
Function that post script error to logger service
@param {Error} error Script error.
@param {string} customMessage Custom message to log
*/
GlobalErrorHandler.postScriptError = function(error, customMessage) {
return GlobalErrorHandler.logError(error, customMessage);
};
return GlobalErrorHandler;
})();
window.Logger = (function() {
function Logger() {}
Logger.initialize = function() {
this.launch_time = new Date();
this.scope_filter;
this.message_filter;
return this.output = null;
};
Logger.get_elapsed_time = function() {
return (new Date()) - this.launch_time;
};
Logger.actual_logging = function(messages, method) {
var args, args_str, min, sec, time, time_str;
if (Constants.PRODUCTION) {
return;
}
args = Array.prototype.slice.call(messages).concat();
time = Logger.get_elapsed_time();
time_str = "";
min = Math.floor(time / (60 * 1000));
time_str = (min < 10 ? "0" : "") + min + ":";
time -= min * 60 * 1000;
sec = Math.floor(time / 1000);
time_str += (sec < 10 ? "0" : "") + sec + ".";
time -= sec * 1000;
time_str += (time < 100 ? "0" : "") + (time < 10 ? "0" : "") + time;
args_str = args.join('|');
if (Logger.message_filter != null) {
if (Logger.message_filter instanceof String && args_str.indexOf(Logger.message_filter) === -1) {
return;
}
if (Logger.message_filter instanceof RegExp && !Logger.message_filter.test(args_str)) {
return;
}
}
try {
if (Logger.output != null) {
$(window.parent.document).find('#' + Logger.output).html(time_str + " >> " + method.toUpperCase() + ": " + args_str + "\n" + $(window.parent.document).find('#' + Logger.output).html());
} else if (console[method].apply !== null) {
args.unshift(time_str);
console[method].apply(console, args);
}
} catch (error) {
return;
}
};
Logger.setOutputContainer = function(id) {
return Logger.output = id;
};
Logger.log = function() {
Logger.actual_logging(arguments, 'log');
};
Logger.info = function() {
Logger.actual_logging(arguments, 'info');
};
Logger.warn = function() {
Logger.actual_logging(arguments, 'warn');
};
Logger.error = function() {
Logger.actual_logging(arguments, 'error');
};
return Logger;
}).call(this);
MozartService = (function(_super) {
__extends(MozartService, _super);
MozartService.RECOMMENDED_PATH = '/recommended/upnext';
function MozartService(app_model) {
this.app_model = app_model;
MozartService.__super__.constructor.call(this, this.app_model);
this._retrieveVideos();
}
MozartService.prototype._retrieveVideos = function() {
var _this = this;
return AppHelper.getJSON(this.app_model.mozart_endpoint + MozartService.RECOMMENDED_PATH, this._requestParameters(), function(data) {
return _this._processMozartResponse(data);
}, function(message) {
return Logger.info(message);
});
};
MozartService.prototype._processMozartResponse = function(data) {
var v, _i, _len, _ref, _ref1, _results;
if (!data) {
return;
}
this.total_count = data['total_count'];
this.current_page++;
_ref = data['data'];
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
v = _ref[_i];
if (v['type'] === 'video' && v['is_html5_enabled']) {
_results.push(this.items.push({
video_id: v['id'],
content_id: v['content_id'],
title: v['title'],
show_name: (_ref1 = v['show']) != null ? _ref1['name'] : void 0,
link: v['link'],
rawObject: v
}));
} else {
_results.push(void 0);
}
}
return _results;
};
MozartService.prototype._requestParameters = function() {
return {
access_token: this.app_model.mozart_token,
video_id: this.app_model.video_id,
show_id: this.app_model.show_id,
dp_identifier: this.app_model.getDistro() !== 'Express' ? this.app_model.getDistro() : void 0,
items_per_page: EndCardPlaylist.ITEMS_PER_PAGE,
position: this.current_page * EndCardPlaylist.ITEMS_PER_PAGE,
format: 'jsonp',
mode: 'default',
content_pgid: 67,
user_pgid: 1,
region: 'us',
language: 'en'
};
};
return MozartService;
})(EndCardPlaylist);
SiteShelfHelper = (function(_super) {
__extends(SiteShelfHelper, _super);
function SiteShelfHelper(app_model) {
this.app_model = app_model;
SiteShelfHelper.__super__.constructor.call(this, this.app_model);
this._data_loaded = false;
}
SiteShelfHelper.prototype.currentItem = function() {
this._retrieveVideos();
return SiteShelfHelper.__super__.currentItem.call(this);
};
SiteShelfHelper.prototype._retrieveVideos = function() {
var collection, items_hash,
_this = this;
if (!this._data_loaded) {
collection = Hulu.SourceAware.getShelfConfig(false, this.app_model.video_id, false).collection.toArray();
items_hash = {};
Hulu.SourceAware.fetchNextVideoIds(this.app_model.video_id, function(up_next) {
var id, next_ids, v, _i, _j, _len, _len1, _ref, _results;
next_ids = up_next.next_ids.split('_');
for (_i = 0, _len = collection.length; _i < _len; _i++) {
v = collection[_i];
items_hash[v.id] = v;
}
_results = [];
for (_j = 0, _len1 = next_ids.length; _j < _len1; _j++) {
id = next_ids[_j];
v = items_hash[id];
_results.push(_this.items.push({
video_id: v.id,
content_id: v.contentId,
title: v.title,
show_name: (_ref = v.show) != null ? _ref.name : void 0,
link: v.pageUrl,
rawObject: v
}));
}
return _results;
});
this.total_count = this.items.length;
return this._data_loaded = true;
}
};
return SiteShelfHelper;
})(EndCardPlaylist);
AgeGate = (function() {
function AgeGate(element) {
var current_year, num, _i, _j,
_this = this;
this.element = $(element);
this._buildHTML();
$('#day_select').append('<option value="-1">Day</option>');
for (num = _i = 1; _i <= 31; num = ++_i) {
$('#day_select').append('<option value="' + num + '">' + num + '</option>');
}
current_year = new Date().getFullYear();
$('#year_select').append('<option value="-1">Year</option>');
for (num = _j = current_year; current_year <= 1900 ? _j <= 1900 : _j >= 1900; num = current_year <= 1900 ? ++_j : --_j) {
$('#year_select').append('<option value="' + num + '"">' + num + '</option>');
}
$('.submit_button').click(function() {
var birthdate;
if (!_this._checkBirthDate()) {
return;
}
birthdate = new Date();
birthdate.setFullYear($("#year_select").val(), $("#month_select").val(), $("#day_select").val());
return $(_this).trigger(AgeGate.Events.AgeSubmitted, {
birthdate: birthdate
});
});
$(".submit_button").css("opacity", 0.5);
$("#year_select, #month_select, #day_select").bind("change", function(event) {
if (event.target.options[0].value < 0) {
event.target.options.remove(0);
}
if (_this._checkBirthDate()) {
return $(".submit_button").css("opacity", 1);
}
});
this.element.show();
}
AgeGate.prototype._buildHTML = function() {
return this.element.html('<div id="age_gate">\
<div class="notification">The following is intended only for mature audiences.</div>\
<div class="instructions">To view this video, please provide your date of birth</div>\
<div class="age_gate_form clearfix">\
<select id="month_select">\
<option value="-1">Month</option>\
<option value="0">January</option>\
<option value="1">February</option>\
<option value="2">March</option>\
<option value="3">April</option>\
<option value="4">May</option>\
<option value="5">June</option>\
<option value="6">July</option>\
<option value="7">August</option>\
<option value="8">September</option>\
<option value="9">October</option>\
<option value="10">November</option>\
<option value="11">December</option>\
</select>\
<select id="day_select"></select>\
<select id="year_select"></select>\
<span class="submit_button" />\
</div>\
</div>');
};
AgeGate.prototype.showAgeGateDenied = function() {
return this.element.html('<div id="age_gate">\
<div class="notification">We\'re sorry, but the video you have requested<br/>is restricted to users 17 years and older.</div>\
<div class="instructions">Your parents will thank us. Don\'t worry, though.<br/>We have plenty of other stuff to watch.</div>\
</div>');
};
AgeGate.prototype._checkBirthDate = function() {
return $("#year_select").val() >= 0 && $("#month_select").val() >= 0 && $("#day_select").val() >= 0;
};
AgeGate.Events = {
AgeSubmitted: "AgeGate.Events.Submitted"
};
return AgeGate;
})();
ControlsView = (function() {
function ControlsView() {
this.hideFullscreenButton = __bind(this.hideFullscreenButton, this);
this.showFullscreenButton = __bind(this.showFullscreenButton, this);
this._triggerDocumentMouseUp = __bind(this._triggerDocumentMouseUp, this);
this._triggerDocumentMouseMove = __bind(this._triggerDocumentMouseMove, this);
this._triggerSeekBarTouchStart = __bind(this._triggerSeekBarTouchStart, this);
this._triggerSeekBarMouseDown = __bind(this._triggerSeekBarMouseDown, this);
this._triggerSeekBarClick = __bind(this._triggerSeekBarClick, this);
this.element = $('#main-controls');
this.pause_btn = this.element.find('.pause-btn');
this.fullscreen_btn = this.element.find('.fullscreen-btn');
this.seek_bar_container = this.element.find('.seekbar-container');
this.seek_bar = this.element.find('.seekbar');
this.current_bar = this.element.find('.current-bar');
this.breaks_holder = this.element.find('.breaks-holder');
this.time_remaining = this.element.find('.time-remaining');
this._is_shown = false;
this.start_drag_x = null;
this.is_dragging = false;
this._initEvents();
}
ControlsView.prototype._initEvents = function() {
var _this = this;
this.pause_btn.on("click", function(event) {
return $(_this).trigger(ControlsView.Events.PauseBtnClick);
});
this.fullscreen_btn.on("click", function(event) {
return $(_this).trigger(ControlsView.Events.FullscreenBtnClick);
});
this.seek_bar_container.on("click", this._triggerSeekBarClick);
this.seek_bar_container.on("mousedown", this._triggerSeekBarMouseDown);
return this.seek_bar_container.on("touchstart", this._triggerSeekBarTouchStart);
};
ControlsView.prototype._triggerSeekBarClick = function(event) {
return EventBus.trigger(ControlsView.Events.Seek, {
'percent': this._ensurePercent((event.pageX - this.seek_bar.offset().left) / this.seek_bar.width())
});
};
ControlsView.prototype._triggerSeekBarMouseDown = function(event) {
this.start_drag_x = event.pageX;
$(document).on("mousemove", this._triggerDocumentMouseMove);
$(document).on("mouseup", this._triggerDocumentMouseUp);
return $(this).trigger(ControlsView.Events.ShowControls);
};
ControlsView.prototype._triggerSeekBarTouchStart = function(event) {
if (event.originalEvent.touches.length === 1 && event.originalEvent.targetTouches.length === 1) {
this.start_drag_x = event.originalEvent.targetTouches.item(0).pageX;
}
$(document).on("touchmove", this._triggerDocumentMouseMove);
$(document).on("touchend", this._triggerDocumentMouseUp);
event.stopImmediatePropagation();
return event.preventDefault();
};
ControlsView.prototype._triggerDocumentMouseMove = function(event) {
var prct, x_coord;
$(this).trigger(ControlsView.Events.ShowControls);
event.stopImmediatePropagation();
event.preventDefault();
switch (event.type.toLowerCase()) {
case "mousemove":
x_coord = event.pageX;
break;
case "touchmove":
x_coord = event.originalEvent.touches.item(0).pageX;
break;
default:
return;
}
prct = 100 * (x_coord - this.seek_bar.offset().left) / this.seek_bar.width();
prct = Math.min(100, Math.max(0, prct));
this.current_bar.width(prct + '%');
if (Math.abs(this.start_drag_x - x_coord) > 10) {
return this.is_dragging = true;
}
};
ControlsView.prototype._triggerDocumentMouseUp = function(event) {
var prct, x_coord;
this.reset();
switch (event.type.toLowerCase()) {
case "mouseup":
x_coord = event.pageX;
break;
case "touchend":
if (event.originalEvent.touches.length === 0 && event.originalEvent.changedTouches.length === 1) {
x_coord = event.originalEvent.changedTouches.item(0).pageX;
} else {
return;
}
break;
default:
return;
}
prct = (x_coord - this.seek_bar.offset().left) / this.seek_bar.width();
prct = this._ensurePercent(prct);
if (this.is_dragging || event.type.toLowerCase() === "touchend") {
EventBus.trigger(ControlsView.Events.Seek, {
'percent': prct
});
this.is_dragging = false;
}
return $(this).trigger(ControlsView.Events.ShowControls);
};
ControlsView.prototype._ensurePercent = function(percent) {
return Math.min(0.99, Math.max(0, percent));
};
ControlsView.prototype.reset = function() {
$(document).off("mousemove", this._triggerDocumentMouseMove);
$(document).off("mouseup", this._triggerDocumentMouseUp);
$(document).off("touchmove", this._triggerDocumentMouseMove);
return $(document).off("touchend", this._triggerDocumentMouseUp);
};
ControlsView.prototype.isShown = function() {
return this._is_shown;
};
ControlsView.prototype.show = function() {
if (!this._is_shown) {
this._is_shown = true;
if (AppHelper.isAndroid()) {
this.element.css('z-index', '1050');
}
return this.element.css('display', 'block');
}
};
ControlsView.prototype.hide = function(skipAnimation) {
if (skipAnimation == null) {
skipAnimation = false;
}
if (this._is_shown) {
this._is_shown = false;
this.element.css('display', 'none');
if (AppHelper.isAndroid()) {
return this.element.css('z-index', '');
}
}
};
ControlsView.prototype.showFullscreenButton = function() {
return this.fullscreen_btn.show();
};
ControlsView.prototype.hideFullscreenButton = function() {
return this.fullscreen_btn.hide();
};
ControlsView.prototype.setTimeRemaining = function(secs) {
var divisor_for_minutes, divisor_for_seconds, hours, minutes, seconds, time;
secs = Math.round(secs);
time = "";
hours = Math.floor(secs / (60 * 60));
if (hours > 0) {
time += "" + hours + ":";
}
divisor_for_minutes = secs % (60 * 60);
minutes = Math.floor(divisor_for_minutes / 60);
if (minutes < 10 && hours > 0) {
time += "0";
}
time += "" + minutes + ":";
divisor_for_seconds = divisor_for_minutes % 60;
seconds = Math.ceil(divisor_for_seconds);
if (seconds < 10) {
time += "0";
}
time += "" + seconds;
return this.time_remaining.html(time);
};
ControlsView.prototype.setSeekPercentage = function(percent) {
if (!this.is_dragging) {
return this.current_bar.width(percent + "%");
}
};
ControlsView.prototype.drawBreakDots = function(breaks) {
var b, newElement, _i, _len, _results;
_results = [];
for (_i = 0, _len = breaks.length; _i < _len; _i++) {
b = breaks[_i];
newElement = $("<div class='break-dot'></div>");
newElement.css('left', b.location + "%");
if (b.active) {
newElement.addClass('active');
}
_results.push(this.breaks_holder.append(newElement));
}
return _results;
};
ControlsView.prototype.clearBreakDots = function() {
return this.breaks_holder.html("");
};
ControlsView.Events = {
PauseBtnClick: "ControlsView.Events.PauseBtnClick",
FullscreenBtnClick: "ControlsView.Events.FullscreenBtnClick",
ShowControls: "ControlsView.Events.ShowControls",
Seek: "ControlsView.Events.SeekBarClick"
};
return ControlsView;
})();
EndCard = (function() {
function EndCard(app_model, player_view, element) {
this.app_model = app_model;
this.player_view = player_view;
this._getPlusTrackParams = __bind(this._getPlusTrackParams, this);
this._goToPlus = __bind(this._goToPlus, this);
this._triggerResetEvent = __bind(this._triggerResetEvent, this);
this._triggerReplayBtnClick = __bind(this._triggerReplayBtnClick, this);
this.element = $(element);
this._count_to_show_plus_upsell = 0;
}
EndCard.prototype.init = function() {
this._removeListeners();
if (this.app_model.isEmbed()) {
this._buildEmbedEndCard();
return this.element.on("click", this._triggerReplayBtnClick);
} else {
this._buildWatchPageEndCard();
this.element.find('.replay-box').on("click", this._triggerReplayBtnClick);
return this.element.find('.plus-link').on("click", this._goToPlus);
}
};
EndCard.prototype.show = function(end_card_ad_model) {
var logo_img,
_this = this;
this.player_view.showPoster();
this.element.show();
if (this.app_model.isEmbed()) {
return;
}
if (this._count_to_show_plus_upsell <= 0) {
this._count_to_show_plus_upsell = 2;
this.element.find('.plus-upsell').show();
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLUS_TRACKING, Constants.BEACONS.EVENTS.DRIVER_LOAD), {
'specificParams': this._getPlusTrackParams()
});
if ((end_card_ad_model != null ? end_card_ad_model.cb_url : void 0) != null) {
logo_img = $("<img></img>", {
src: end_card_ad_model.cb_url,
"class": 'logo'
});
logo_img.bind("load", function() {
if (_this.visible()) {
return end_card_ad_model.companionViewed();
}
});
logo_img.bind("click", function() {
if (end_card_ad_model.cb_clickthrough != null) {
end_card_ad_model.companionClicked();
return window.open(end_card_ad_model.cb_clickthrough, "_blank");
}
});
return this.element.find('.companion-logo-container').append(logo_img);
}
} else {
this._count_to_show_plus_upsell--;
return this.element.find('.plus-upsell').hide();
}
};
EndCard.prototype.hide = function() {
return this.element.hide();
};
EndCard.prototype.visible = function() {
return this.element.is(':visible');
};
EndCard.prototype._removeListeners = function() {
this.element.find('.replay-box').off("click", this._triggerReplayBtnClick);
this.element.find('.plus_link').off("click", this._goToPlus);
return this.element.off("click", this._triggerResetEvent);
};
EndCard.prototype._triggerReplayBtnClick = function() {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.END_WATCH_AGAIN), {});
return this._triggerResetEvent();
};
EndCard.prototype._triggerResetEvent = function() {
return EventBus.trigger(GeneralEvent.WATCH_AGAIN);
};
EndCard.prototype._goToPlus = function() {
var _ref;
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.END_UPSELL), {});
if ((_ref = window.Player) != null) {
if (typeof _ref.setPlusDriverCookie === "function") {
_ref.setPlusDriverCookie(this._getPlusTrackParams());
}
}
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.PLUS_TRACKING, Constants.BEACONS.EVENTS.DRIVER_CLICK), {
'specificParams': this._getPlusTrackParams()
});
return window.location = Constants.PLUS_UPSELL_BASE_URL;
};
EndCard.prototype._getPlusTrackParams = function() {
return {
'driverpage': this.app_model.getPageType(),
'drivertype': "endcard",
'driverid1': this.app_model.content_id
};
};
EndCard.prototype._buildEmbedEndCard = function() {
return this.element.html('<div class="scrim"></div>\
<div class="card-info">\
<div class="replay-icon"></div>\
</div>');
};
EndCard.prototype._buildWatchPageEndCard = function() {
return this.element.html('<div class="scrim"></div>\
<div class="card-info center-align">\
<dic class="card-elements-container">\
<div class="plus-upsell">\
<div class="message">Watch more of TV\'s best moments and full episodes.</div>\
<div class="plus-link"></div>\
</div>\
<div class="companion-logo-container"></div>\
<div class="replay-box">\
</div>\
</div>\
</div>');
};
return EndCard;
})();
MediaPlayerView = (function() {
MediaPlayerView.SEEK_TIMEOUT_HLS = 1500;
MediaPlayerView.SEEK_TIMEOUT_MP4 = 800;
function MediaPlayerView(player_model, element) {
this.player_model = player_model;
this._onEnded = __bind(this._onEnded, this);
this._onSuspend = __bind(this._onSuspend, this);
this._fullScreenChange = __bind(this._fullScreenChange, this);
this._finishSeek = __bind(this._finishSeek, this);
this._onSeeked = __bind(this._onSeeked, this);
this._onSeeking = __bind(this._onSeeking, this);
this._onFireEndedTimeout = __bind(this._onFireEndedTimeout, this);
this._onTimeUpdate = __bind(this._onTimeUpdate, this);
this._onPause = __bind(this._onPause, this);
this._onPlaying = __bind(this._onPlaying, this);
this._onCanPlayThrough = __bind(this._onCanPlayThrough, this);
this._onCanPlay = __bind(this._onCanPlay, this);
this._onLoadedMetadata = __bind(this._onLoadedMetadata, this);
this._onStalled = __bind(this._onStalled, this);
this._onLoadStart = __bind(this._onLoadStart, this);
this._onError = __bind(this._onError, this);
this._onVideoEvent = __bind(this._onVideoEvent, this);
this._onFullscreenChange = __bind(this._onFullscreenChange, this);
this._onWebKitEndFullscreen = __bind(this._onWebKitEndFullscreen, this);
this._onWebKitBeginFullscreen = __bind(this._onWebKitBeginFullscreen, this);
this.element = $(element);
this.raw_element = this.element.get(0);
try {
this.raw_element.currentTime = 0;
this.raw_element.pause();
} catch (_error) {}
this._pendingStateAfterSeek = MediaPlayerView.States.Paused;
this._current_url = void 0;
this._src_set = false;
this._ready_for_async_playback = false;
this._metadata_loaded = false;
this._content_duration = 0;
this._can_play_through = false;
this._pause_pending = false;
this._start_marker = 0;
this._invalid_time_marker = false;
this._is_seekable_content = false;
this._requested_seek_pos = null;
this._seek_pending_timeout = void 0;
this._initEvents();
this._last_time_update = 0;
this._last_sent_time_update = 0;
this._check_for_false_start = false;
this._need_ended_event_hack = AppHelper.isAndroid();
this._timer_to_fire_ended = -1;
this._ended_event_fired = false;
this.triggered_by_user = true;
this._setState(MediaPlayerView.States.Init);
}
MediaPlayerView.prototype.setStartMarker = function(value) {
return this._start_marker = value;
};
MediaPlayerView.prototype.reset = function() {
var ios_version, _ended_event_fired;
this._last_time_update = 0;
this._last_sent_time_update = 0;
this._start_marker = 0;
this.triggered_by_user = true;
this._clear_ended_timer();
_ended_event_fired = false;
ios_version = AppHelper.getIOSVersion();
if (AppHelper.isPhone() && ios_version >= 6 && this.player_model.app_model.video_eid !== null) {
try {
this.seek(0, false, true);
if (this._seek_pending_timeout != null) {
clearTimeout(this._seek_pending_timeout);
this._seek_pending_timeout = void 0;
try {
this.raw_element.pause();
this.raw_element.play();
} catch (_error) {}
}
} catch (_error) {}
}
if (!AppHelper.isPhone() || ios_version === 0 || ios_version >= 6) {
return this.hide();
}
};
MediaPlayerView.prototype._setState = function(_state) {
this._state = _state;
return this.player_model.setMediaPlayerViewState(this._state);
};
MediaPlayerView.prototype._getState = function() {
return this._state;
};
MediaPlayerView.prototype.setIsSeekable = function(seekable) {
if (seekable == null) {
seekable = false;
}
return this._is_seekable_content = seekable;
};
MediaPlayerView.prototype.setDuration = function(value) {
return this._content_duration = value;
};
MediaPlayerView.prototype.show = function() {
return this.element.show();
};
MediaPlayerView.prototype.hide = function() {
return this.element.hide();
};
MediaPlayerView.prototype._initEvents = function() {
this.element.on(VideoEvent.ERROR, this._onError);
this.element.on(VideoEvent.LOAD_START, this._onLoadStart);
this.element.on(VideoEvent.STALLED, this._onStalled);
this.element.on(VideoEvent.LOADED_METADATA, this._onLoadedMetadata);
this.element.on(VideoEvent.CAN_PLAY, this._onCanPlay);
this.element.on(VideoEvent.CAN_PLAY_THROUGH, this._onCanPlayThrough);
this.element.on(VideoEvent.PLAYING, this._onPlaying);
this.element.on(VideoEvent.TIME_UPDATE, this._onTimeUpdate);
this.element.on(VideoEvent.SEEKING, this._onSeeking);
this.element.on(VideoEvent.SEEKED, this._onSeeked);
this.element.on(VideoEvent.SUSPEND, this._onSuspend);
this.element.on(VideoEvent.PAUSE, this._onPause);
this.element.on(VideoEvent.ENDED, this._onEnded);
this.element.on("fullscreenchange", this._onFullscreenChange);
this.element.on("mozfullscreenchange", this._onFullscreenChange);
this.element.on("webkitfullscreenchange", this._onFullscreenChange);
this.element.on("webkitbeginfullscreen", this._onWebKitBeginFullscreen);
return this.element.on("webkitendfullscreen", this._onWebKitEndFullscreen);
};
MediaPlayerView.prototype._onWebKitBeginFullscreen = function() {
return this._in_webkit_fullscreen = true;
};
MediaPlayerView.prototype._onWebKitEndFullscreen = function() {
return this._in_webkit_fullscreen = false;
};
MediaPlayerView.prototype._onFullscreenChange = function() {
if (this.triggered_by_user) {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, AppHelper.isFullScreen() ? Constants.BEACONS.EVENTS.FULLSCREEN_OPEN : Constants.BEACONS.EVENTS.FULLSCREEN_CLOSE), {});
}
return this.triggered_by_user = true;
};
MediaPlayerView.prototype._onVideoEvent = function(event) {
if (Constants.PRODUCTION) {
return;
}
if (event.type !== VideoEvent.TIME_UPDATE) {
Logger.info("[VIDEO EVENT] " + event.type, this.raw_element.currentTime);
}
switch (event.type) {
case VideoEvent.DURATION_CHANGE:
return Logger.info("[VIDEO EVENT] durationchange:", this._duration, this.raw_element.duration);
case VideoEvent.LOADED_METADATA:
return Logger.info("[VIDEO EVENT] LOADED_METADATA:", event.originalEvent);
case VideoEvent.ERROR:
return Logger.info("[VIDEO EVENT] ERROR", this.raw_element.error.code, this.raw_element.src);
}
};
MediaPlayerView.prototype.setSource = function(url, position, duration) {
if (position == null) {
position = 0;
}
if (duration == null) {
duration = void 0;
}
this._clear_ended_timer();
this._ended_event_fired = false;
if (this._current_url !== url) {
this._current_url = url;
try {
this.raw_element.src = url;
this.raw_element.load();
this._check_for_false_start = true;
} catch (_error) {}
this._last_sent_time_update = 0;
this._src_set = true;
return $(this).trigger(MediaPlayerView.Events.SourceChanged);
}
};
MediaPlayerView.prototype.seek = function(position, check_seekable, force) {
var can_seek, seek_timeout;
if (check_seekable == null) {
check_seekable = true;
}
if (force == null) {
force = false;
}
if (!(position != null)) {
return;
}
if (!this._is_seekable_content && check_seekable) {
return;
}
if (this._start_marker >= position) {
position = this._start_marker + 0.6;
}
can_seek = false;
try {
if (Math.abs(this.raw_element.currentTime - position) < 1 && !force) {
return;
}
if ((this._requested_seek_pos != null) && Math.abs(this._requested_seek_pos - position) < 1 && !force) {
return;
}
this._requested_seek_pos = position;
this.triggered_by_user = false;
if (!isNaN(this.raw_element.duration) && this.raw_element.duration >= position) {
this.raw_element.currentTime = position;
can_seek = true;
}
} catch (_error) {}
if (this._seek_pending_timeout != null) {
clearTimeout(this._seek_pending_timeout);
}
if (can_seek) {
seek_timeout = AppHelper.isPlaylistCompatible() ? MediaPlayerView.SEEK_TIMEOUT_HLS : MediaPlayerView.SEEK_TIMEOUT_MP4;
return this._seek_pending_timeout = AppHelper.setTimeout(seek_timeout, this._finishSeek);
}
};
MediaPlayerView.prototype.play = function() {
var _this = this;
try {
this.triggered_by_user = false;
this.raw_element.play();
if (AppHelper.isAndroid()) {
return AppHelper.setTimeout(Constants.PLAY_TIMEOUT, function() {
return _this._checkPlaying();
});
}
} catch (e) {
return AppHelper.setTimeout(Constants.PLAY_TIMEOUT, function() {
return _this.play();
});
}
};
MediaPlayerView.prototype._checkPlaying = function() {
if (!this.player_model.isPlaying() || this._last_time_update === 0) {
return this.play();
}
};
MediaPlayerView.prototype.pause = function() {
this.triggered_by_user = false;
this._pause_pending = true;
try {
return this.raw_element.pause();
} catch (_error) {}
};
MediaPlayerView.prototype.ensureReadyForAsyncPlayback = function() {
if (!this._ready_for_async_playback && !this._src_set) {
try {
this.raw_element.play();
} catch (_error) {}
return this._ready_for_async_playback = true;
}
};
MediaPlayerView.prototype._onError = function(event) {
this._clear_ended_timer();
event.preventDefault();
this._setState(MediaPlayerView.States.Error);
return $(this).trigger(MediaPlayerView.Events.Error, {
event: event
});
};
MediaPlayerView.prototype._onLoadStart = function() {
return this._setState(MediaPlayerView.States.Loading);
};
MediaPlayerView.prototype._onStalled = function() {
if (this._getState() === MediaPlayerView.States.Loading) {
return this.raw_element.play();
}
};
MediaPlayerView.prototype._onLoadedMetadata = function() {
return this._duration = this.raw_element.duration;
};
MediaPlayerView.prototype._onCanPlay = function() {
if (this._getState() === MediaPlayerView.States.Loading) {
return this._setState(MediaPlayerView.States.Ready);
}
};
MediaPlayerView.prototype._onCanPlayThrough = function() {
if (this._getState() === MediaPlayerView.States.Loading) {
return this._setState(MediaPlayerView.States.Ready);
}
};
MediaPlayerView.prototype._onPlaying = function() {
var is_false_start;
is_false_start = false;
try {
if (this._check_for_false_start && this.raw_element.paused) {
is_false_start = true;
}
} catch (_error) {}
if (is_false_start) {
$(this).trigger(MediaPlayerView.Events.FalseStart);
return;
}
this._check_for_false_start = false;
if (this._requested_seek_pos != null) {
clearTimeout(this._seek_pending_timeout);
this._seek_pending_timeout = void 0;
if (Math.abs(this.raw_element.currentTime - this._requested_seek_pos) > 2) {
this.raw_element.currentTime = this._requested_seek_pos;
} else {
this._requested_seek_pos = void 0;
}
}
if (this.triggered_by_user) {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.PLAY), {});
}
this.triggered_by_user = true;
this._setState(MediaPlayerView.States.Playing);
return $(this).trigger(MediaPlayerView.Events.Playing);
};
MediaPlayerView.prototype._onPause = function() {
if (this.raw_element.currentTime === this.raw_element.duration) {
return;
}
this._setState(MediaPlayerView.States.Paused);
if (this._pause_pending) {
this._pause_pending = false;
}
if (this._getState() !== MediaPlayerView.States.Ended) {
if (this.triggered_by_user) {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.PAUSE), {});
}
this.triggered_by_user = true;
return $(this).trigger(MediaPlayerView.Events.Paused);
}
};
MediaPlayerView.prototype._onTimeUpdate = function() {
var current_time;
if (this._getState() === MediaPlayerView.States.Seeking) {
return;
}
if (AppHelper.isAndroidVersion2() && !AppHelper.isFullScreen() && !this.previousTimeUpdateFullscreen && !this._in_webkit_fullscreen && !this.raw_element.seeking && this.raw_element.currentTime === 0 && this.previousTimeUpdate > 0) {
this.raw_element.pause();
$(this).trigger(MediaPlayerView.Events.FalseStart);
}
if (!this.raw_element.paused) {
this._setState(MediaPlayerView.States.Playing);
}
if (this.raw_element.currentTime + 2 < this._start_marker && !this.raw_element.paused) {
if (!this._invalid_time_marker) {
this._invalid_time_marker = true;
try {
this.raw_element.currentTime = this._start_marker + 0.6;
} catch (_error) {}
}
} else {
this._invalid_time_marker = false;
current_time = this.raw_element.currentTime;
if (Math.abs(this._last_time_update - current_time) < 2 && !this.raw_element.paused) {
this._last_sent_time_update = current_time;
$(this).trigger(MediaPlayerView.Events.TimeUpdate, {
currentTime: this._last_sent_time_update
});
}
this._last_time_update = current_time;
}
this.previousTimeUpdate = this.raw_element.currentTime;
this.previousTimeUpdateFullscreen = AppHelper.isFullScreen();
if (this._need_ended_event_hack && !this._ended_event_fired && this._timer_to_fire_ended < 0 && (this.raw_element.duration - this.raw_element.currentTime) <= 0.5) {
return this._timer_to_fire_ended = setTimeout(this._onFireEndedTimeout, 1500);
}
};
MediaPlayerView.prototype._onFireEndedTimeout = function() {
this._clear_ended_timer();
return this._onEnded();
};
MediaPlayerView.prototype._clear_ended_timer = function() {
if (this._timer_to_fire_ended >= 0) {
clearTimeout(this._timer_to_fire_ended);
return this._timer_to_fire_ended = -1;
}
};
MediaPlayerView.prototype._onSeeking = function() {
if (this.triggered_by_user) {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.SEEK), {
'specificParams': {
selectedposition: parseInt(this._requested_seek_pos),
src: "controlbar"
}
});
}
this.triggered_by_user = true;
if (this._getState() !== MediaPlayerView.States.Seeking) {
this._pendingStateAfterSeek = this._getState();
return this._setState(MediaPlayerView.States.Seeking);
}
};
MediaPlayerView.prototype._onSeeked = function() {
return this._finishSeek(true);
};
MediaPlayerView.prototype._finishSeek = function(from_seeked) {
this._requested_seek_pos = void 0;
if (this._seek_pending_timeout != null) {
clearTimeout(this._seek_pending_timeout);
this._seek_pending_timeout = void 0;
if (from_seeked !== true) {
try {
this.raw_element.pause();
this.raw_element.play();
} catch (_error) {}
}
this._requested_seek_pos = void 0;
}
this._setState(this._pendingStateAfterSeek);
return this._onTimeUpdate();
};
MediaPlayerView.prototype._fullScreenChange = function() {
return Logger.info("full screen changed");
};
MediaPlayerView.prototype._onSuspend = function() {
return Logger.info("on suspend");
};
MediaPlayerView.prototype._onEnded = function() {
this._clear_ended_timer();
if (this._ended_event_fired) {
return;
}
this._ended_event_fired = true;
if (this._seek_pending_timeout != null) {
clearTimeout(this._seek_pending_timeout);
this._seek_pending_timeout = void 0;
this._requested_seek_pos = void 0;
}
this._setState(MediaPlayerView.States.Ended);
this.raw_element.pause();
return $(this).trigger(MediaPlayerView.Events.Ended);
};
MediaPlayerView.States = {
Error: -1,
Init: 0,
Loading: 1,
Ready: 2,
Paused: 3,
Buffering: 4,
Seeking: 5,
Playing: 6,
Ended: 7
};
MediaPlayerView.Events = {
SourceChanged: 'MediaPlayer.Events.SourceChanged',
Playing: 'MediaPlayer.Events.Playing',
TimeUpdate: 'MediaPlayer.Events.TimeUpdate',
Buffering: 'MediaPlayer.Events.Buffering',
Ended: 'MediaPlayer.Events.Ended',
Stalled: 'MediaPlayer.Events.Stalled',
Error: 'MediaPlayer.Events.Error',
FalseStart: 'MediaPlayer.Events.FalseStart',
BufferFinished: "MediaPlayer.Events.BufferFinished",
Paused: 'MediaPlayer.Events.Paused'
};
return MediaPlayerView;
})();
PlayerView = (function() {
function PlayerView(app_model, player_model, ui) {
this.app_model = app_model;
this.player_model = player_model;
this.ui = ui;
this._handlePlayerError = __bind(this._handlePlayerError, this);
this._triggerBufferFinished = __bind(this._triggerBufferFinished, this);
this._triggerBuffering = __bind(this._triggerBuffering, this);
this._triggerError = __bind(this._triggerError, this);
this._triggerTimeUpdate = __bind(this._triggerTimeUpdate, this);
this._triggerEnded = __bind(this._triggerEnded, this);
this._triggerShowControls = __bind(this._triggerShowControls, this);
this.triggerStartPlayClick = __bind(this.triggerStartPlayClick, this);
this.reset = __bind(this.reset, this);
this._onFalseStart = __bind(this._onFalseStart, this);
this._onPauseFromVideo = __bind(this._onPauseFromVideo, this);
this._onPlayFromVideo = __bind(this._onPlayFromVideo, this);
this.play = __bind(this.play, this);
this._triggerPlay = __bind(this._triggerPlay, this);
this.element = $('#main-player');
this.cards_container = $('.cards-container');
this.poster_element = this.element.find('.poster');
this.error_card = this.element.find('.error-card');
this.start_play_card = this.element.find('.start-play-card');
this.loading_card = this.element.find('.loading-card');
this.paused_card = this.element.find('.paused-card');
this.age_gate_card = this.element.find('.age-gate-card');
this.ad_top_bar = this.element.find('.ad-top-bar');
this.ad_num = this.ad_top_bar.find('.ad-num');
this.ad_num_total = this.ad_top_bar.find('.ad-num-total');
this.ad_seconds = this.ad_top_bar.find('.ad-seconds');
this.network_bug_holder = this.element.find('.network-bug');
this.end_card = new EndCard(this.app_model, this, this.element.find('.end-card'));
if (AppHelper.isIOS() && !AppHelper.isTablet()) {
this.paused_card.find(".start-play-btn").hide();
}
this.media_player_view = new MediaPlayerView(this.player_model, this.element.find('video'));
$(this.media_player_view).on(MediaPlayerView.Events.Playing, this._onPlayFromVideo);
$(this.media_player_view).on(MediaPlayerView.Events.Paused, this._onPauseFromVideo);
$(this.media_player_view).on(MediaPlayerView.Events.Ended, this._triggerEnded);
$(this.media_player_view).on(MediaPlayerView.Events.TimeUpdate, this._triggerTimeUpdate);
$(this.media_player_view).on(MediaPlayerView.Events.Error, this._triggerError);
$(this.media_player_view).on(MediaPlayerView.Events.Buffering, this._triggerBuffering);
$(this.media_player_view).on(MediaPlayerView.Events.BufferFinished, this._triggerBufferFinished);
$(this.media_player_view).on(MediaPlayerView.Events.FalseStart, this._onFalseStart);
this._initEvents();
this.showLoading();
}
PlayerView.prototype._initEvents = function() {
this.element.on("mousemove", this._triggerShowControls);
this.start_play_card.on("click", this.triggerStartPlayClick);
return this.paused_card.on("click", this._triggerPlay);
};
PlayerView.prototype.ensureReadyForAsyncPlayback = function() {
return this.media_player_view.ensureReadyForAsyncPlayback();
};
PlayerView.prototype._triggerPlay = function() {
this.media_player_view.play();
return this.setTriggeredByUser(true);
};
PlayerView.prototype._hideAll = function() {
$('.card').hide();
this.hideBug();
return $(this).trigger(PlayerView.Events.HideControls);
};
PlayerView.prototype.showError = function(message) {
if (message == null) {
message = Constants.DEFAULT_ERROR_MESSAGE;
}
this.error_card.find('.error-message').html("<div>" + message + "</div>");
this._hideAll();
this.showPoster();
return this.error_card.show();
};
PlayerView.prototype.showAgeGate = function() {
var _this = this;
$('.card').hide();
this.showPoster();
this.age_gate = new AgeGate(this.age_gate_card);
return $(this.age_gate).on(AgeGate.Events.AgeSubmitted, function(event, object) {
return $(_this).trigger(AgeGate.Events.AgeSubmitted, object);
});
};
PlayerView.prototype.hideAgeGate = function() {
return this.age_gate_card.hide();
};
PlayerView.prototype.showAgeGateDenied = function() {
return this.age_gate.showAgeGateDenied();
};
PlayerView.prototype.setPosterSource = function(url) {
return this.poster_url = url;
};
PlayerView.prototype.showPoster = function(fadeSpeed) {
var _this = this;
if (fadeSpeed == null) {
fadeSpeed = 0;
}
if (fadeSpeed > 0) {
return this.poster_element.fadeOut(fadeSpeed, function() {
_this.poster_element.attr("src", _this.poster_url);
return _this.poster_element.fadeIn(fadeSpeed);
});
} else {
this.poster_element.attr("src", this.poster_url);
return this.poster_element.show();
}
};
PlayerView.prototype.initEndCard = function() {
return this.end_card.init();
};
PlayerView.prototype.setCardData = function(show_name, episode_name, duration) {
var chars, ellip, max_height, min, parts, sec, time_str, _results;
if (this.app_model.isAdZone()) {
parts = episode_name.split(':');
if (parts.length >= 2) {
show_name = parts[0];
episode_name = parts[1];
}
}
chars = show_name.length + 1 + episode_name.length;
min = Math.floor(duration / (60 * 1000));
sec = Math.floor((duration / 1000) % 60);
time_str = " (" + min + ":" + (sec < 10 ? "0" : "") + sec + ")";
ellip = "&hellip;";
this.element.find('.show-name').html(show_name);
this.element.find('.episode-name').html(episode_name + time_str);
max_height = Constants.TITLE_HEIGHT * AppHelper.devicePixelRatio();
_results = [];
while (this.element.find('.program-info').height() > max_height && episode_name.length > 0) {
if (episode_name.length > 0) {
episode_name = episode_name.substr(0, episode_name.length - 1);
} else if (show_name.length > 0) {
show_name = show_name.substr(0, show_name.length - 1);
}
_results.push(this.element.find('.episode-name').html(episode_name + ellip + time_str));
}
return _results;
};
PlayerView.prototype.setTimeRemaining = function(time_remaining) {
var min_left, sec_left, time_str;
min_left = Math.floor(time_remaining / 60);
sec_left = Math.floor(time_remaining);
if (min_left > 0) {
time_str = min_left + " " + (min_left === 1 ? "minute" : "minutes") + " left";
} else {
time_str = sec_left + " " + (sec_left === 1 ? "second" : "seconds") + " left";
}
return this.paused_card.find('.time-remaining').html(time_str);
};
PlayerView.prototype.showMediaPlayer = function() {
this.media_player_view.show();
this.poster_element.hide();
return this.start_play_card.hide();
};
PlayerView.prototype.setBug = function(bug, url) {
switch (bug) {
case PlayerView.Bugs.Network:
return this.network_bug_holder.html(url !== void 0 ? "<img src=\"" + url + "\">" : "");
}
};
PlayerView.prototype.showBug = function(bug) {
if (bug == null) {
bug = null;
}
switch (bug) {
case PlayerView.Bugs.Hulu:
if (this.app_model.isEmbed()) {
$('.hulu-bug').show();
return $('.hulu-bug').addClass('big');
}
break;
case PlayerView.Bugs.Network:
return $('.network-bug').show();
case PlayerView.Bugs.Partner:
if (this.app_model.isEmbed()) {
return $('.partner-bug').show();
}
}
};
PlayerView.prototype.hideBug = function(bug) {
if (bug == null) {
bug = null;
}
switch (bug) {
case PlayerView.Bugs.Hulu:
return $('.hulu-bug').hide();
case PlayerView.Bugs.Network:
return $('.network-bug').hide();
case PlayerView.Bugs.Partner:
return $('.partner-bug').hide();
case null:
return $('.bug').hide();
}
};
PlayerView.prototype.play = function(url, position, duration, seekable) {
this.media_player_view.setSource(url, position);
this.media_player_view.setDuration(duration);
this.media_player_view.setIsSeekable(seekable);
if (position != null) {
this.showLoading();
this.media_player_view.seek(position);
}
return this.media_player_view.play();
};
PlayerView.prototype._onPlayFromVideo = function() {
this._false_start = false;
this.end_card.hide();
this.paused_card.hide();
if (AppHelper.isAndroid()) {
this.cards_container.css('z-index', '');
}
this.hideLoading();
this.start_play_card.hide();
return $(this).trigger(PlayerView.Events.Playing);
};
PlayerView.prototype.pause = function() {
return this.media_player_view.pause();
};
PlayerView.prototype._onPauseFromVideo = function() {
if (!this.end_card.visible() && !this.app_model.changing_video && !this._false_start) {
if (AppHelper.isAndroid()) {
this.cards_container.css('z-index', '1002');
}
this.paused_card.show();
return $(this).trigger(PlayerView.Events.Paused);
}
};
PlayerView.prototype._onFalseStart = function() {
this._false_start = true;
this.paused_card.hide();
this.loading_card.hide();
this.showPoster();
return this.start_play_card.show();
};
PlayerView.prototype.setStartMarker = function(value) {
return this.media_player_view.setStartMarker(value);
};
PlayerView.prototype.reset = function() {
this._false_start = false;
if (this.app_model.changing_video) {
this.setPosterSource(null);
}
this.media_player_view.reset();
this.loading_card.show();
this.pause();
this.loading_card.show();
this.hideAdTopBar();
$('.hulu-bug').removeClass('big');
this.paused_card.hide();
this.end_card.hide();
this.error_card.hide();
this.age_gate_card.hide();
return this.start_play_card.show();
};
PlayerView.prototype.showLoading = function() {
return this.loading_card.show();
};
PlayerView.prototype.hideLoading = function() {
return this.loading_card.hide();
};
PlayerView.prototype.show = function() {
return this.element.show();
};
PlayerView.prototype.hide = function() {
return this.element.hide();
};
PlayerView.prototype.isInBreak = function(value) {
if (value) {
return this.element.addClass('in-break');
} else {
return this.element.removeClass('in-break');
}
};
PlayerView.prototype.showAdTopBar = function(ad_num, ad_num_total, seconds_remaining) {
if (ad_num == null) {
ad_num = null;
}
if (ad_num_total == null) {
ad_num_total = null;
}
if (seconds_remaining == null) {
seconds_remaining = null;
}
if (ad_num != null) {
this.ad_num.html(ad_num);
}
if (ad_num_total != null) {
this.ad_num_total.html(ad_num_total);
}
if (seconds_remaining != null) {
this.ad_seconds.html(Math.max(0, seconds_remaining));
}
return this.ad_top_bar.show();
};
PlayerView.prototype.hideAdTopBar = function() {
return this.ad_top_bar.hide();
};
PlayerView.prototype.showEndCard = function(end_card_ad_model) {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.CONTENT_INTERACTION, Constants.BEACONS.EVENTS.SHOW_END_CARD), {});
this._hideAll();
this.end_card.show(end_card_ad_model);
this.media_player_view.hide();
return this.media_player_view.pause();
};
PlayerView.prototype.toggleFullScreen = function() {
var video_player;
this.media_player_view.show();
video_player = this.element.find("video").get(0);
if (video_player.webkitEnterFullscreen) {
if (AppHelper.isFullScreen()) {
this.exitFullScreen();
}
return video_player.webkitEnterFullscreen();
} else {
return this.element.parent().addClass('fullscreen');
}
};
PlayerView.prototype.exitFullScreen = function() {
var video_player;
this.media_player_view.auto_control = true;
video_player = this.element.find("video").get(0);
if (document.exitFullscreen) {
return document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
return document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
return document.webkitCancelFullScreen();
} else if (video_player.webkitExitFullscreen) {
return video_player.webkitExitFullscreen();
} else {
return this.element.parent().removeClass('fullscreen');
}
};
PlayerView.prototype.setTriggeredByUser = function(triggered_by_user) {
return this.media_player_view.triggered_by_user = triggered_by_user;
};
PlayerView.prototype.triggerStartPlayClick = function(event) {
$(this).trigger(PlayerView.Events.StartPlayClick);
if (this.app_model.first_play) {
EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.SESSION, Constants.BEACONS.EVENTS.STARTUP), {});
return this.app_model.first_play = false;
}
};
PlayerView.prototype._triggerShowControls = function(event) {
if (this.player_model.isPlaying() || this.player_model.isPlaybackPending()) {
return $(this).trigger(PlayerView.Events.ShowControls, event);
}
};
PlayerView.prototype._triggerEnded = function(event, data) {
return $(this).trigger(PlayerView.Events.Ended, data);
};
PlayerView.prototype._triggerTimeUpdate = function(event, data) {
if (this.loading_card.is(':visible')) {
this.loading_card.hide();
}
return $(this).trigger(PlayerView.Events.TimeUpdate, data);
};
PlayerView.prototype._triggerError = function(event, data) {
$(this).trigger(PlayerView.Events.Error, data);
return this._handlePlayerError(data);
};
PlayerView.prototype._triggerBuffering = function(event) {
return $(this).trigger(PlayerView.Events.Buffering);
};
PlayerView.prototype._triggerBufferFinished = function(event) {
return $(this).trigger(PlayerView.Events.BufferFinished);
};
PlayerView.prototype._handlePlayerError = function(data) {
var b_event, error;
error = data['event'].originalEvent.target.error;
switch (error.code) {
case error.MEDIA_ERR_ABORTED:
b_event = Constants.BEACONS.EVENTS.NET_CONNECTION_CLOSED;
break;
case error.MEDIA_ERR_NETWORK:
b_event = Constants.BEACONS.EVENTS.NET_STREAM_NO_TRACK_SUPPORT;
break;
case error.MEDIA_ERR_DECODE:
b_event = Constants.BEACONS.EVENTS.NET_STREAM_FILE_INVALID;
break;
case error.MEDIA_ERR_SRC_NOT_SUPPORTED:
b_event = Constants.BEACONS.EVENTS.NET_STREAM_NO_TRACK_SUPPORT;
break;
default:
b_event = Constants.BEACONS.EVENTS.IOS_PLAYER_ERROR;
}
return EventBus.trigger(BeaconHelper.getBeaconEventName(Constants.BEACONS.TYPES.ERROR, b_event), {
server_beacons: {
error_code: error.code,
fatal_failure: 1
}
});
};
PlayerView.Events = {
StartPlayClick: "PlayerView.Events.StartPlayClick",
ShowControls: "PlayerView.Events.ShowControls",
HideControls: "PlayerView.Events.HideControls",
Paused: "PlayerView.Events.Paused",
Resumed: "PlayerView.Events.Resumed",
Ended: "PlayerView.Events.Ended",
TimeUpdate: "PlayerView.Events.TimeUpdate",
Playing: "PlayerView.Events.Playing",
Error: "PlayerView.Events.Error",
Buffering: "PlayerView.Events.Buffering",
BufferFinished: "PlayerView.Events.BufferFinished"
};
PlayerView.Bugs = {
Hulu: "PlayerView.Bugs.Hulu",
Network: "PlayerView.Bugs.Network",
Partner: "PlayerView.Bugs.Partner"
};
return PlayerView;
})();
window.HTML5Player = (function() {
function HTML5Player(parent_div, params) {
this.app_model = new AppModel(params);
if (this.app_model.isEmbed()) {
GlobalErrorHandler.initialize(this.app_model);
}
if (!Constants.PRODUCTION) {
Logger.initialize();
if (this.app_model.getLoggingContainer() != null) {
Logger.setOutputContainer(this.app_model.getLoggingContainer());
}
}
this.app_controller = new AppController(this.app_model, parent_div);
this._trackGoogleAnalyticsView();
}
HTML5Player.prototype.setVideo = function(video_id) {
this.app_controller.setVideo(video_id);
return this._trackGoogleAnalyticsView();
};
HTML5Player.prototype.playVideo = function(video_id, start, end, config) {
if (config) {
this.app_model.updateParams(config);
}
this.app_controller.setVideo(video_id, true);
return this._trackGoogleAnalyticsView();
};
HTML5Player.prototype.stopVideo = function() {
return this.app_controller.stopVideo();
};
HTML5Player.prototype.pauseEverything = function() {
return this.app_controller.pauseEverything();
};
HTML5Player.prototype.changePlayerSize = function(width, height) {
return this.app_controller.changePlayerSize(width, height);
};
HTML5Player.prototype.getCurrentVideoId = function() {
return this.app_controller.getCurrentVideoId();
};
HTML5Player.prototype.isPlaying = function() {
return this.app_controller.isPlaying();
};
HTML5Player.prototype.isPlaybackPending = function() {
return this.app_controller.isPlaybackPending();
};
HTML5Player.prototype._trackGoogleAnalyticsView = function() {
if (typeof _gaq !== "undefined" && _gaq !== null) {
_gaq.push(['_trackEvent', 'HTML5_Player', 'Load', (this.app_model.isEmbed() != null ? 'Embed' : 'Normal')]);
_gaq.push(['_trackEvent', 'HTML5_Player', 'Playback', (AppHelper.isPlayerAllowed() ? 'Yes' : 'No')]);
}
return true;
};
return HTML5Player;
})();
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment