summaryrefslogtreecommitdiff
path: root/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere')
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/break.js49
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/common.js123
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/dailymotion.js42
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/facebook.js31
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/metacafe.js57
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/vimeo.js98
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/youtube-formats.js33
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/youtube.js200
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/break.js10
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/dailymotion.js10
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/facebook.js8
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/main.js96
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/metacafe.js12
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/vimeo.js12
-rw-r--r--data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/youtube.js21
15 files changed, 802 insertions, 0 deletions
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/break.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/break.js
new file mode 100644
index 0000000..207dc00
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/break.js
@@ -0,0 +1,49 @@
+(function() {
+ "use strict";
+
+ onReady(() => {
+ var url_r = /"uri":\s*"([^"]*)"/;
+ var width_r = /"width":\s*([^\s,]*),/;
+ var height_r = /"height":\s*([^\s,]*),/;
+ var fmts = {};
+ var data = document.head.innerHTML.match(/"media": \[\s[^\]]*\s\],/);
+ if (!data)
+ return;
+ data = data[0].match(/\{[^}]*\}/g);
+ data.forEach(it =>
+ fmts[it.match(width_r)[1] + "x" + it.match(height_r)[1]] = it.match(url_r)[1]
+ );
+ var url = getPreferredFmt(fmts, {
+ "higher/mp4": "1280x720",
+ "high/mp4": "848x480",
+ "medium/mp4": "640x360",
+ "low/mp4": "301x232" // there is 300x220 too which is audio only
+ });
+ if (url === undefined && !(url = fallback()))
+ return;
+ injectPlayer(url);
+ });
+
+ function injectPlayer(url) {
+ var player = createNode("video", {
+ controls: true,
+ autoplay: autoPlay(true),
+ preload: preLoad(),
+ src: url
+ }, {
+ width: "100%",
+ heigth: "100%"
+ });
+
+ document.body.innerHTML = "";
+ document.head.innerHTML = "";
+ document.body.appendChild(player);
+ }
+
+ function fallback() {
+ // Just fallback method if the first one didn't work
+ var url_r = /"videoUri":\s*"([^"]*)"/;
+ var url = (document.head.innerHTML.match(url_r) || ["", ""])[1];
+ return url;
+ }
+}()); \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/common.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/common.js
new file mode 100644
index 0000000..637cc00
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/common.js
@@ -0,0 +1,123 @@
+/* global OPTIONS:true, onPrefChange:true, getPreferredFmt:true */
+/* global createNode:true, asyncGet:true, onReady:true, onInit:true, logify:true */
+/* global preLoad:true, autoPlay:true, HANDLE_VOL_PREF_CHANGE:true */
+// the following jshint global rule is only because jshint support for ES6 arrow
+// functions is limited
+/* global wrapper:true, args:true, auto:true */
+"use strict";
+
+//This Addons Preferences
+var OPTIONS = {};
+// push your prefernces change listner function to this table, yah the old way
+const onPrefChange = [];
+const Qlt = [
+ "higher",
+ "high",
+ "medium",
+ "low"
+];
+// set it to false if the module uses custom listener
+var HANDLE_VOL_PREF_CHANGE = true;
+const Cdc = ["webm", "mp4"];
+self.port.on("preferences", function(prefs) {
+ OPTIONS = prefs;
+ onPrefChange.forEach(f => f());
+});
+
+self.port.on("prefChanged", function(pref) {
+ OPTIONS[pref.name] = pref.value;
+ if (pref.name === "volume" && HANDLE_VOL_PREF_CHANGE === true)
+ Array.forEach(document.getElementsByTagName("video"), el => {
+ el.volume = OPTIONS.volume / 100;
+ });
+ onPrefChange.forEach(f => f(pref.name));
+});
+
+const getPreferredFmt = (fmts, wrapper = {}) => {
+ // for example of the optional wrapper, see data/youtube-formats.js
+ var i, j, slct;
+ var _cdc = [
+ Cdc[OPTIONS.prefCdc],
+ Cdc[(OPTIONS.prefCdc + 1 % 2)]
+ ];
+ i = OPTIONS.prefQlt;
+ while (i > -1) {
+ for (j = 0; j < 2; j++) {
+ slct = Qlt[i] + "/" + _cdc[j];
+ slct = wrapper[slct] || slct;
+ if (fmts[slct])
+ return fmts[slct];
+ }
+ i = (i >= OPTIONS.prefQlt) ? i + 1 : i - 1;
+ if (i > 3)
+ i = OPTIONS.prefQlt - 1;
+ }
+ logify("Error on getPreferredFmt", fmts, wrapper);
+};
+
+const createNode = (type, prprt, style, data) => {
+ logify("createNode", type, prprt);
+ var node = document.createElement(type);
+ if (prprt)
+ Object.keys(prprt).forEach(p => node[p] = prprt[p]);
+ if (style)
+ Object.keys(style).forEach(s => node.style[s] = style[s]);
+ if (data)
+ Object.keys(data).forEach(d => node.dataset[d] = data[d]);
+ return node;
+};
+
+const asyncGet = (url, headers, mimetype) => {
+ logify("asyncGet", url);
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url, true);
+ if (headers)
+ Object.keys(headers).forEach(h => xhr.setRequestHeader(h, headers[h]));
+ if (mimetype && xhr.overrideMimeType)
+ xhr.overrideMimeType(mimetype);
+ xhr.onload = function() {
+ if (this.status !== 200) {
+ reject(this.status);
+ logify("Error on asyncGet", url, headers, this.status);
+ return;
+ }
+ resolve(this.responseText);
+ };
+ xhr.onerror = function() {
+ reject();
+ };
+ xhr.send();
+ });
+};
+
+const logify = (...args) =>
+ console.log.apply(console, args.map(s => JSON.stringify(s, null, 2)));
+
+const onReady = f => {
+ //TODO: document readyState is "loading" (and DOMECotentLoaded) even DOM elements are
+ //accessible
+ try {
+ if (document.readyState !== "loading") {
+ f();
+ } else {
+ document.addEventListener("DOMContentLoaded", f);
+ }
+ } catch (e) {
+ console.error("Exception", e.lineNumber, e.columnNumber, e.message, e.stack);
+ }
+};
+
+const onInit = f => {
+ // code running on when="ready" mode or does not need until onReady
+ // execc but depend on preferences, need to wrapped to this funct.
+ // need
+ document.onafterscriptexecute = function() {
+ document.onafterscriptexecute = undefined;
+ f();
+ };
+};
+const autoPlay = (auto = false) => ((OPTIONS.autoplay === 1 || auto === true) &&
+ OPTIONS.autoplay !== 0);
+const preLoad = (auto = false) => ((OPTIONS.preload === 1 || auto === true) &&
+ OPTIONS.preload !== 0) ? "auto" : "metadata"; \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/dailymotion.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/dailymotion.js
new file mode 100644
index 0000000..7732ec4
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/dailymotion.js
@@ -0,0 +1,42 @@
+(function() {
+ "use strict";
+
+ onReady(() => {
+
+ // VIDEO_ID = location.pathname.match(/\/embed\/video\/([^_]+)/)[1];
+ // asyncGet http://www.dailymotion.com/json/video/<VIDEO_ID>?fields=stream_audio_url,stream_h264_hd1080_url,stream_h264_hd_url,stream_h264_hq_url,stream_h264_ld_url,stream_h264_url,stream_hls_url,stream_live_hls_url,thumbnail_120_url,thumbnail_240_url,thumbnail_url
+ // returns a json
+ var streams_r = /"stream_h264[^"]*_url":"[^"]*"/g;
+ var url_r = /"(stream_h264[^"]*_url)":"([^"]*)"/;
+ var streams = document.body.innerHTML.match(streams_r);
+ var url, urls = {};
+ streams.forEach(u => {
+ var r = u.match(url_r);
+ urls[r[1]] = r[2].replace("\\/", "/", "g");
+ });
+ var types = [];
+ url = getPreferredFmt(urls, {
+ // stream_h264_hd1080_url
+ "higher/mp4": "stream_h264_hd_url", // H264 1280x720
+ "high/mp4": "stream_h264_hq_url", // H264 848x480
+ "medium/mp4": "stream_h264_url", // H264 512x384
+ "low/mp4": "stream_h264_ld_url" // H264 320x240
+ });
+ if (url === undefined)
+ return;
+ var poster = (document.body.innerHTML.match(/"thumbnail_url":"([^"]*)"/) || ["", ""])[1].replace("\\/", "/", "g");
+ var player = createNode("video", {
+ controls: true,
+ autoplay: autoPlay(),
+ preload: preLoad(),
+ poster: poster,
+ src: url
+ }, {
+ width: "100%",
+ heigth: "100%"
+ });
+
+ document.body.innerHTML = "";
+ document.body.appendChild(player);
+ });
+}()); \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/facebook.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/facebook.js
new file mode 100644
index 0000000..136b1b9
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/facebook.js
@@ -0,0 +1,31 @@
+(function() {
+ "use strict";
+ // Facebook module is injected when page is "ready", so onReady() will exec
+ // the code directly, even before addon preferences are fetched. Because
+ // they are needed by the following code, we use onInit() instead of
+ // onReady() so our code get Executed after the prefernces get fetched.
+ // Waw! seems the longest code documentation I ever wrote o.0
+ onInit(() => {
+ var params = document.body.innerHTML.match(/\"params\",(\"[^\"]*\")/)[1];
+ params = JSON.parse(decodeURIComponent(JSON.parse(params)));
+ var url = getPreferredFmt({
+ "medium/mp4": params.video_data[0].sd_src,
+ "high/mp4": params.video_data[0].hd_src
+ });
+ if (url === undefined)
+ return;
+ var player = createNode("video", {
+ // preload: true,
+ controls: true,
+ autoplay: autoPlay(true),
+ preload: preLoad(),
+ src: url
+ }, {
+ width: "100%",
+ heigth: "100%"
+ });
+
+ document.getElementsByClassName("_53j5")[0].innerHTML = "";
+ document.getElementsByClassName("_53j5")[0].appendChild(player);
+ });
+}()); \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/metacafe.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/metacafe.js
new file mode 100644
index 0000000..022d811
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/metacafe.js
@@ -0,0 +1,57 @@
+(function() {
+ "use strict";
+
+ onReady(() => {
+ if (/watch\/\d+\/.*/.test(location.pathname))
+ watchPage();
+ else if (/[^\/]+\/?$/.test(location.pathname))
+ channelPage();
+ });
+
+ function watchPage() {
+ var ob = document.getElementById("flashVars");
+ if (!ob)
+ return;
+ var url = getURL(ob.value);
+ var player = createNode("video", {
+ autoplay: autoPlay(true),
+ preload: preLoad(),
+ controls: true,
+ src: url
+ });
+
+ var container = document.getElementById("ItemContainer");
+ if (!container)
+ return;
+ container.innerHTML = "";
+ container.appendChild(player);
+ }
+
+ function channelPage() {
+ var embed = document.getElementsByTagName("embed");
+ if (!embed)
+ return;
+ embed = embed[0];
+ var page = embed.src;
+ page = page.replace("/fplayer/", "/watch/").replace(/.swf$/, "");
+ asyncGet(page).then((data) => {
+ var url = getURL(data);
+ var player = createNode("video", {
+ autoplay: autoPlay(false),
+ preload: preLoad(),
+ controls: true,
+ src: url
+ });
+ var container = embed.parentElement;
+ container.innerHTML = "";
+ container.appendChild(player);
+
+ });
+ }
+
+ function getURL(e) {
+ var data = decodeURIComponent(e.match(/&mediaData=([^&]*)&/)[1]);
+ return JSON.parse(data).MP4.mediaURL;
+ }
+
+}()); \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/vimeo.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/vimeo.js
new file mode 100644
index 0000000..b3d3e43
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/vimeo.js
@@ -0,0 +1,98 @@
+(function() {
+ "use strict";
+
+ onReady(() =>
+ getConfig().then(getVideoInfo)
+ );
+
+ function injectPlayer(conf) {
+ try {
+ let player_container, player;
+ if (conf.isEmbed) {
+ player_container = document.body;
+ player_container.innerHTML = "";
+ } else if (conf.isWatch) {
+ player_container = document.getElementById("video");
+ player_container.children[1].remove();
+ } else {
+ player_container = document.getElementById("clip_" + conf.id);
+ player_container.innerHTML = "";
+ }
+ if (!player_container)
+ return;
+ player = createNode("video", {
+ className: conf.className,
+ autoplay: autoPlay(),
+ preload: preLoad(),
+ controls: true,
+ poster: conf.poster,
+ volume: OPTIONS.volume / 100
+ });
+ player.appendChild(createNode("source", {
+ src: conf.url
+ }));
+ player_container.appendChild(player);
+ } catch (e) {
+ console.error("Exception on changePlayer()", e.lineNumber, e.columnNumber, e.message, e.stack);
+ }
+ }
+
+ function getConfig() {
+ return new Promise((resolve, reject) => {
+ var isWatch = /https?:\/\/vimeo.com\/[\d]+/.test(location.href);
+ var isEmbed = /https?:\/\/player.vimeo.com\/video/.test(location.href);
+ var isChannel = /https?:\/\/vimeo.com\/(channels\/|)\w+/.test(location.href);
+ if (!isWatch && !isChannel && !isEmbed)
+ reject();
+ var player_id, player_class;
+ if (isWatch) {
+ player_id = location.pathname.match(/^\/([\d]+)/)[1];
+ player_class = "player";
+ } else if (isEmbed) {
+ player_id = location.pathname.match(/video\/([\d]+)/)[1];
+ player_class = "fallback";
+ } else if (isChannel) {
+ player_class = "player";
+ }
+ if (!player_id && !isChannel)
+ reject();
+ resolve({
+ isWatch: isWatch,
+ isEmbed: isEmbed,
+ isChannel: isChannel,
+ id: player_id,
+ className: player_class
+ });
+ });
+ }
+
+ function getVideoInfo(conf) {
+ const processData = (conf) => (data) => {
+ data = JSON.parse(data);
+ var fmt = getPreferredFmt(data.request.files.h264, {
+ "high/mp4": "hd",
+ "medium/mp4": "sd",
+ "low/mp4": "mobile"
+ });
+ if (fmt === undefined)
+ return Promise.reject();
+ conf.poster = data.video.thumbs.base;
+ conf.url = fmt.url;
+ return Promise.resolve(conf);
+ };
+ const INFO_URL = "https://player.vimeo.com/video/";
+ if (conf.isChannel) {
+ return Array.map(document.getElementsByClassName("player_container"), (el) => {
+ var _conf = {};
+ for (var va in conf)
+ _conf[va] = conf[va];
+ _conf.id = el.id.replace("clip_", "");
+ return asyncGet(INFO_URL + _conf.id + "/config").then(processData(_conf))
+ .then(injectPlayer);
+ });
+ } else {
+ return asyncGet(INFO_URL + conf.id + "/config").then(processData(conf))
+ .then(injectPlayer);
+ }
+ }
+}()); \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/youtube-formats.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/youtube-formats.js
new file mode 100644
index 0000000..e23cf83
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/youtube-formats.js
@@ -0,0 +1,33 @@
+// wrap getPreferedFmt selector to YT itag eq, as we the passed fmts object
+// later has itags as keys not getPreferredFmt known keys
+var FMT_WRAPPER = {
+ "high/mp4": "22",
+ "medium/mp4": "18",
+ "medium/webm": "43"
+};
+/*
++----+-----------+------------+---------+-------------------------------------------
+|FMT | container | resolution | profile | type
++----+-----------+------------+---------+-------------------------------------------
+| 18 | mp4 | 360p | normal | "video/mp4; codecs=\"avc1.42001E, mp4a.40.2\""
+| 22 | mp4 | 720p | normal | "video/mp4; codecs=\"avc1.64001F, mp4a.40.2\""
+| 43 | webm | 360p | normal | "video/webm; codecs=\"vp8.0, vorbis\""
++----+-----------+------------+---------+------------------------------------------
+| 82 | mp4 | 360p | 3D |
+| 83 | mp4 | 240p | 3D |
+| 84 | mp4 | 720p | 3D |
+| 85 | mp4 | 1080p | 3D |
+|100 | webm | 360p | 3D |
+|101 | webm | 360p | 3D |
+|102 | webm | 700p | 3D |
+|133 | mp4 | 240p | DASH V |
+|134 | mp4 | 360p | DASH V |
+|135 | mp4 | 480p | DASH V |
+|136 | mp4 | 720p | DASH V |
+|137 | mp4 | 1080p | DASH V |
+|160 | mp4 | 144p | DASH V |
+|264 | mp4 | 1440p | DASH V |
+|. | . | . | . |
++----+-----------+------------+---------+----------------------------------------
+MORE FROM: http://en.wikipedia.org/wiki/YouTube
+*/ \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/youtube.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/youtube.js
new file mode 100644
index 0000000..431ad9d
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/data/youtube.js
@@ -0,0 +1,200 @@
+/*globals FMT_WRAPPER*/
+(function() {
+ "use strict";
+ var player, player_container;
+
+ onReady(() => {
+ player = createNode("video");
+ changePlayer();
+ window.addEventListener("spfrequest", function() {
+ if (player)
+ player.src = "";
+ });
+ window.addEventListener("spfdone", function() {
+ changePlayer();
+ });
+ });
+
+ function changePlayer() {
+ getConfig()
+ .then(getVideoInfo)
+ .then((conf) => {
+ try {
+ if (player_container)
+ player_container.innerHTML = "";
+ player_container = getPlayerContainer(conf);
+ if (!player_container)
+ return;
+ player_container.innerHTML = "";
+ player_container.className = conf.className || "";
+ player = createNode("video", {
+ id: "video_player",
+ className: conf.className || "",
+ autoplay: autoPlay(!conf.isEmbed),
+ preload: preLoad(),
+ controls: true,
+ poster: conf.poster || "",
+ volume: OPTIONS.volume / 100
+ }, {
+ position: "relative"
+ });
+ player.appendChild(createNode("source", {
+ src: conf.url,
+ type: conf.type
+ }));
+ player_container.appendChild(player);
+ } catch (e) {
+ console.error("Exception on changePlayer()", e.lineNumber, e.columnNumber, e.message, e.stack);
+ }
+ })
+ .catch((rej) => {
+ if (rej === undefined)
+ return;
+ switch (rej.error) {
+ case "VIDEO_URL_UNACCESSIBLE":
+ var error = rej.data.match(/reason=([^&]*)&/);
+ if (error)
+ errorMessage("Failed to load video url with the following error message: " +
+ error[1].replace("+", " ", "g"));
+ break;
+ case "NO_SUPPORTED_VIDEO_FOUND":
+ errorMessage("Failed to find any playable video url." +
+ (rej.unsig ? " All urls are not signed" : ""), rej.conf);
+ break;
+ }
+ });
+ }
+
+ function errorMessage(msg, conf) {
+ logify("errorMessage", msg, conf);
+ var error_container;
+ if (conf)
+ error_container = getPlayerContainer(conf);
+ if (!error_container)
+ error_container = document.getElementById("player-unavailable") || document.getElementById("player");
+ if (!error_container)
+ return;
+ if (conf && conf.isWatch)
+ error_container.className += " player-height player-width";
+ if (conf && conf.isChannel)
+ error_container.className += " html5-main-video";
+ if (conf && conf.isEmbed) {
+ error_container.className += " full-frame";
+ }
+ error_container.style.background = "linear-gradient(to bottom, #383838 0px, #131313 100%) repeat scroll 0% 0% #262626";
+ error_container.innerHTML = "";
+ error_container.appendChild(createNode("p", {
+ textContent: "Ooops! :("
+ }, {
+ padding: "15px",
+ fontSize: "20px"
+ }));
+ error_container.appendChild(createNode("p", {
+ textContent: msg
+ }, {
+ fontSize: "20px"
+ }));
+ }
+
+ function getPlayerContainer(conf) {
+ if (conf.isWatch)
+ return document.getElementById("player-mole-container");
+ if (conf.isEmbed)
+ return document.body;
+ if (conf.isChannel)
+ return document.getElementsByClassName("c4-player-container")[0];
+ }
+
+ function getConfig() {
+ return new Promise((resolve, reject) => {
+ var isEmbed = location.href.search("youtube.com/embed/") > -1;
+ var isWatch = location.href.search("youtube.com/watch?") > -1;
+ var isChannel = location.href.search("youtube.com/channel/") > -1 || location.href.search("youtube.com/user/") > -1;
+ if (!isEmbed && !isWatch && !isChannel)
+ reject();
+ var player_id, player_class;
+ if (isEmbed) {
+ player_id = location.pathname.match(/^\/embed\/([^?#/]*)/)[1];
+ player_class = "full-frame";
+ } else if (isChannel) {
+ var upsell = document.getElementById("upsell-video");
+ if (!upsell)
+ reject();
+ player_id = upsell.dataset["videoId"];
+ player_class = "html5-main-video";
+ } else {
+ player_id = location.search.slice(1).match(/v=([^/?#]*)/)[1];
+ player_class = "player-width player-height";
+ }
+ if (!player_id)
+ reject({
+ error: "PLAYER_ID_NOT_FOUND"
+ });
+ resolve({
+ isEmbed: isEmbed,
+ isWatch: isWatch,
+ isChannel: isChannel,
+ id: player_id,
+ className: player_class
+ });
+ });
+ }
+
+ function getVideoInfo(conf) {
+ var INFO_URL = "https://www.youtube.com/get_video_info?html5=1&hl=en_US&el=detailpage&video_id=";
+ return asyncGet(INFO_URL + conf.id, {}, "text/plain").then((data) => {
+ if (data.endsWith("="))
+ try {
+ data = atob(data);
+ } catch (_) {}
+ if (/status=fail/.test(data)) {
+ return Promise.reject({
+ error: "VIDEO_URL_UNACCESSIBLE",
+ data: data
+ });
+ }
+ // get the poster url
+ var poster = data.match(/iurlhq=([^&]*)/);
+ if (poster)
+ conf.poster = decodeURIComponent(poster[1]);
+ // extract avalable formats to fmts object
+ var info = data.match(/url_encoded_fmt_stream_map=([^&]*)/)[1];
+ info = decodeURIComponent(info);
+ var fmt, fmts = {},
+ unsignedVideos;
+ info.split(",")
+ .map(it1 => {
+ var oo = {};
+ it1.split("&")
+ .map(it2 => it2.split("="))
+ .map(it3 => [it3[0], decodeURIComponent(it3[1])])
+ .forEach(it4 => oo[it4[0]] = it4[1]);
+ return oo;
+ })
+ .filter(it5 => (player.canPlayType(
+ (it5.type = it5.type.replace("+", " ", "g"))
+ ) === "probably"))
+ .filter(it6 => {
+ if (it6.url.search("signature=") > 0)
+ return true;
+ unsignedVideos = true;
+ logify("Url without signature!!", it6.itag);
+ return false;
+ })
+ .forEach(fmt => fmts[fmt.itag] = fmt);
+ // choose best format from fmts onject
+ fmt = getPreferredFmt(fmts, FMT_WRAPPER);
+ if (fmt === undefined) {
+ return Promise.reject({
+ error: "NO_SUPPORTED_VIDEO_FOUND",
+ unsig: unsignedVideos,
+ conf: conf
+ });
+ } else {
+ conf.url = fmt.url;
+ conf.type = fmt.type;
+ return Promise.resolve(conf);
+ }
+ });
+ }
+}()); \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/break.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/break.js
new file mode 100644
index 0000000..79f1a8b
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/break.js
@@ -0,0 +1,10 @@
+"use strict";
+var match = [/https?:\/\/www.break.com\/embed\/.*/];
+var inject = [
+ "common.js",
+ "break.js"
+];
+var when = "start";
+exports.when = when;
+exports.match = match;
+exports.inject = inject; \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/dailymotion.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/dailymotion.js
new file mode 100644
index 0000000..e2c5761
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/dailymotion.js
@@ -0,0 +1,10 @@
+"use strict";
+var match = [/https?:\/\/(www.)dailymotion.com\/embed\/video\/.*/];
+var inject = [
+ "common.js",
+ "dailymotion.js"
+];
+var when = "start";
+exports.when = when;
+exports.match = match;
+exports.inject = inject; \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/facebook.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/facebook.js
new file mode 100644
index 0000000..a229268
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/facebook.js
@@ -0,0 +1,8 @@
+"use strict";
+var match = [/https?:\/\/(www\.|beta\.)?facebook.com\/video.php\?.*/];
+var inject = [
+ "common.js",
+ "facebook.js"
+];
+exports.match = match;
+exports.inject = inject; \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/main.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/main.js
new file mode 100644
index 0000000..8240ede
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/main.js
@@ -0,0 +1,96 @@
+/* jshint esnext:true, node:true*/
+"use strict";
+const {
+ Cc, Ci, Cr
+} = require("chrome");
+const {
+ add, remove
+} = require("sdk/util/array");
+const data = require("sdk/self").data;
+const pageMod = require("sdk/page-mod");
+const events = require("sdk/system/events");
+const utils = require("sdk/window/utils");
+var prefs = require("sdk/simple-prefs").prefs;
+// list of current workers
+const workers = [];
+const drivers = [
+ require("./youtube.js"),
+ require("./vimeo.js"),
+ require("./dailymotion.js"),
+ require("./break.js"),
+ require("./metacafe.js"),
+ require("./facebook.js")
+];
+
+for (let driver of drivers) {
+ if (driver.match === void(0))
+ continue;
+ pageMod.PageMod({
+ include: driver.match,
+ contentScriptFile: driver.inject.map(i => data.url(i)),
+ contentScriptWhen: driver.when || "ready",
+ onAttach: onWorkerAttach
+ });
+}
+
+function listener(event) {
+ var channel = event.subject.QueryInterface(Ci.nsIHttpChannel);
+ var url = event.subject.URI.spec;
+ for (let driver of drivers) {
+ for (let redirect of(driver.redirect || [])) {
+ if (redirect.src.test(url)) {
+ channel.redirectTo(Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService).newURI(
+ String.replace(url, redirect.src, redirect.funct),
+ null,
+ null));
+ console.log("Redirect:", url);
+ return;
+ }
+ }
+ for (let block of(driver.block || [])) {
+ if (block.test(url)) {
+ channel.cancel(Cr.NS_BINDING_ABORTED);
+ console.log("Block:", url);
+ return;
+ }
+ }
+ }
+}
+
+//on Addon prefernces change, send the changes to content-script
+require("sdk/simple-prefs").on("", function prefChangeHandler(pref) {
+ if (pref === "volume" && prefs.volume > 100)
+ prefs.volume = 100;
+ else if (pref === "volume" && prefs.volume < 0)
+ prefs.volume = 0;
+ else
+ workersPrefHandler(pref);
+});
+
+function workersPrefHandler(pref) {
+ for (let worker of workers)
+ worker.port.emit("prefChanged", {
+ name: pref,
+ value: prefs[pref]
+ });
+}
+
+function onWorkerAttach(worker) {
+ console.log("onAttach", worker);
+ //send current Addon preferences to content-script
+ let _prefs = {};
+ for (let pref in prefs)
+ _prefs[pref] = prefs[pref];
+ worker.port.emit("preferences", _prefs);
+ add(workers, worker);
+ worker.on("detach", function(e) {
+ remove(workers, this);
+
+ });
+}
+exports.main = function() {
+ events.on("http-on-modify-request", listener);
+};
+exports.onUnload = function(reason) {
+ events.off("http-on-modify-request", listener);
+}; \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/metacafe.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/metacafe.js
new file mode 100644
index 0000000..ca6d179
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/metacafe.js
@@ -0,0 +1,12 @@
+"use strict";
+var match = [/https?:\/\/www.metacafe.com\/watch\/.*/,
+ /https?:\/\/www.metacafe.com\/[^\/]+\/?/
+];
+var inject = [
+ "common.js",
+ "metacafe.js"
+];
+var when = "start";
+exports.when = when;
+exports.match = match;
+exports.inject = inject; \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/vimeo.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/vimeo.js
new file mode 100644
index 0000000..1475d1d
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/vimeo.js
@@ -0,0 +1,12 @@
+"use strict";
+var when = "start";
+var match = [/https?:\/\/vimeo.com\/.+/,
+ /https?:\/\/player.vimeo.com\/video.*/
+];
+var inject = [
+ "common.js",
+ "vimeo.js"
+];
+exports.when = when;
+exports.match = match;
+exports.inject = inject; \ No newline at end of file
diff --git a/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/youtube.js b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/youtube.js
new file mode 100644
index 0000000..e054233
--- /dev/null
+++ b/data/extensions/html5-video-everywhere@lejenome.me/resources/html5-video-everywhere/lib/youtube.js
@@ -0,0 +1,21 @@
+"use strict";
+var YOUTUBE_FLASH_REGEX = /https?:\/\/(www.)?youtube.com\/v\/([^#?\/]*)/;
+var YT_BIN_REGEX = /https:\/\/s.ytimg.com\/yts\/jsbin\/[^\/]*\/base.js/;
+var YT_PLAYER_REGEX = /https?:\/\/s.ytimg.com\/yts\/jsbin\/[^\/]*\/html5player.js/;
+var when = "start";
+var match = ["*.www.youtube.com"];
+var inject = [
+ "common.js",
+ "youtube-formats.js",
+ "youtube.js"
+];
+var redirect = [{
+ src: /https?:\/\/(www.)?youtube.com\/v\/([^#?\/]*)/,
+ funct: (_1, _2, v) => "https://www.youtube.com/embed/" + v
+}];
+var block = [/https?:\/\/s.ytimg.com\/yts\/jsbin\/[^\/]*\/html5player.js/];
+exports.when = when;
+exports.match = match;
+exports.inject = inject;
+exports.redirect = redirect;
+exports.block = block; \ No newline at end of file