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) { + $("
").insertBefore($("#ytapiplayer")).attr("id", "ytapiplayer"); + $("video").each(function () { + killVideoUntilItIsDead($(this)); + }); + data.type = "fl"; + data.url = data.direct.sd.url; + PLAYER.player = undefined; + PLAYER = new FlashPlayer(data); + if ($("#ytapiplayer").height() != VHEIGHT) { + resizeStuff(); + } + + handleMediaUpdate(data); +}