diff --git a/templates/useroptions.jade b/templates/useroptions.jade
index 1e7ea19e..c8689b55 100644
--- a/templates/useroptions.jade
+++ b/templates/useroptions.jade
@@ -59,10 +59,10 @@ mixin us-playback
.col-sm-4
.col-sm-8
p.text-info Setting wmode=transparent
allows objects to be displayed above the video player, but may cause performance issues on some systems.
- mixin rcheckbox("us-no-h264", "Use JWPlayer for h.264 playback")
+ mixin rcheckbox("us-no-h264", "Use flash for h.264 playback")
.col-sm-4
.col-sm-8
- p.text-info Some browsers (e.g. Firefox <=28) do not support native h.264 video playback. This option allows such content to be played using JWPlayer's flash player.
+ p.text-info CyTube will attempt to autodetect browsers that do not natively support h.264 playback and fall back on a flash player. This overrides that automatic detection and forces use of the flash player.
mixin rcheckbox("us-hidevideo", "Remove the video player")
mixin rcheckbox("us-playlistbuttons", "Hide playlist buttons by default")
mixin rcheckbox("us-oldbtns", "Old style playlist buttons")
diff --git a/www/StrobeMediaPlayback.swf b/www/StrobeMediaPlayback.swf
new file mode 100644
index 00000000..487d91c1
Binary files /dev/null and b/www/StrobeMediaPlayback.swf differ
diff --git a/www/js/callbacks.js b/www/js/callbacks.js
index 11ba5ab6..e00f5ee0 100644
--- a/www/js/callbacks.js
+++ b/www/js/callbacks.js
@@ -854,7 +854,7 @@ Callbacks = {
if (NO_VIMEO && data.type === "vi" && data.direct && data.direct.sd) {
// For browsers that don't support native h264 playback
if (USEROPTS.no_h264) {
- data.type = "jw";
+ data.type = "fl";
} else {
data.type = "rv";
}
@@ -863,6 +863,10 @@ Callbacks = {
data.url = data.direct.sd.url;
}
+ if (data.type === "rt") {
+ data.url = data.id;
+ }
+
if(data.type != PLAYER.type) {
loadMediaPlayer(data);
}
diff --git a/www/js/player.js b/www/js/player.js
index ee129dde..2204f7d8 100644
--- a/www/js/player.js
+++ b/www/js/player.js
@@ -148,7 +148,6 @@ var VimeoPlayer = function (data) {
iframe.css("border", "none");
iframe.width(VWIDTH);
iframe.height(VHEIGHT);
- console.log(iframe.width(), iframe.height());
$f(iframe[0]).addEvent("ready", function () {
self.player = $f(iframe[0]);
@@ -738,6 +737,126 @@ var RTMPPlayer = function (data) {
});
};
+function flashEventHandler(id, ev, data) {
+ switch (ev) {
+ case "timeupdate":
+ PLAYER.currentTime = data.currentTime;
+ break;
+ case "pause":
+ PLAYER.paused = data.paused;
+ if (CLIENT.leader)
+ sendVideoUpdate();
+ break;
+ case "play":
+ PLAYER.paused = data.paused;
+ if (CLIENT.leader)
+ sendVideoUpdate();
+ break;
+ case "volumechange":
+ PLAYER.volume = (data.muted ? 0 : data.volume);
+ break;
+ case "progress":
+ break;
+ case "onJavaScriptBridgeCreated":
+ PLAYER.player = $("#ytapiplayer")[0];
+ break;
+ default:
+ break;
+ }
+}
+
+var FlashPlayer = function (data) {
+ removeOld();
+ var self = this;
+ self.volume = VOLUME;
+ self.videoId = data.id;
+ self.videoUrl = data.url;
+ self.videoLength = data.seconds;
+ self.paused = false;
+ self.currentTime = 0;
+
+ self.init = function () {
+ var params = {
+ allowFullScreen: "true",
+ allowScriptAccess: "always",
+ allowNetworking: "all",
+ wMode: "direct"
+ };
+
+ var flashvars = {
+ src: encodeURIComponent(self.videoUrl),
+ // For some reason this param seems not to work
+ clipStartTime: Math.floor(data.currentTime),
+ javascriptCallbackFunction: "flashEventHandler",
+ autoPlay: true,
+ volume: VOLUME
+ };
+
+ if (self.videoUrl.indexOf("rtmp") === 0) {
+ flashvars.streamType = "live";
+ } else {
+ flashvars.streamType = "recorded";
+ }
+
+ swfobject.embedSWF("/StrobeMediaPlayback.swf",
+ "ytapiplayer",
+ VWIDTH, VHEIGHT,
+ "10.1.0",
+ null,
+ flashvars,
+ params,
+ { name: "ytapiplayer" }
+ );
+
+ self.player = $("#ytapiplayer")[0];
+ };
+
+ self.load = function (data) {
+ self.videoId = data.id;
+ self.videoUrl = data.url;
+ self.videoLength = data.seconds;
+ self.init();
+ };
+
+ self.pause = function () {
+ if (self.player && self.player.pause)
+ self.player.pause();
+ };
+
+ self.play = function () {
+ // Why is it play2? What happened to play1?
+ if (self.player && self.player.play2)
+ self.player.play2();
+ };
+
+ self.isPaused = function (cb) {
+ cb(self.paused);
+ };
+
+ self.getTime = function (cb) {
+ cb(self.currentTime);
+ };
+
+ self.seek = function (to) {
+ if (self.player && self.player.seek) {
+ self.player.seek(Math.floor(to));
+ }
+ };
+
+ self.getVolume = function (cb) {
+ cb(self.volume);
+ };
+
+ self.setVolume = function (vol) {
+ if (self.player && self.player.setVolume)
+ self.player.setVolume(vol);
+ };
+
+ waitUntilDefined(window, "swfobject", function () {
+ self.init();
+ });
+};
+
var JWPlayer = function (data) {
var self = this;
self.videoId = data.id;
@@ -1017,6 +1136,11 @@ function RawVideoPlayer(data) {
.attr("width", VWIDTH)
.attr("height", VHEIGHT)
.html("Your browser does not support HTML5 <video>
tags :(");
+ video.error(function (err) {
+ setTimeout(function () {
+ fallbackRaw(data);
+ }, 100);
+ });
removeOld(video);
self.player = video[0];
self.setVolume(VOLUME);
@@ -1168,12 +1292,13 @@ var constructors = {
"tw": TwitchTVPlayer,
"jt": JustinTVPlayer,
"us": UstreamPlayer,
- "rt": RTMPPlayer,
+ "rt": FlashPlayer,
"jw": JWPlayer,
"im": ImgurPlayer,
"cu": CustomPlayer,
"gd": GoogleDocsPlayer,
- "rv": RawVideoPlayer
+ "rv": RawVideoPlayer,
+ "fl": FlashPlayer
};
function loadMediaPlayer(data) {
diff --git a/www/js/util.js b/www/js/util.js
index 76cc410c..022c0e2f 100644
--- a/www/js/util.js
+++ b/www/js/util.js
@@ -1541,7 +1541,7 @@ function removeVideo() {
try {
PLAYER.setVolume(0);
if (PLAYER.type === "rv") {
- $(PLAYER.player).remove();
+ killVideoUntilItIsDead($(PLAYER.player));
}
} catch (e) {
}
@@ -2397,3 +2397,29 @@ function initPm(user) {
return pm;
}
+
+function killVideoUntilItIsDead(video) {
+ try {
+ video[0].volume = 0;
+ video[0].muted = true;
+ video.attr("src", "");
+ video.remove();
+ } catch (e) {
+ }
+}
+
+function fallbackRaw(data) {
+ $("