From a291836a99466fedb9d8751ac946da286796cc6c Mon Sep 17 00:00:00 2001 From: calzoneman Date: Sat, 2 May 2015 17:55:00 -0500 Subject: [PATCH] Change USEROPTS.default_quality values --- player/youtube.coffee | 52 ++++++++++++++++++++--------- templates/useroptions.jade | 12 +++---- www/js/data.js | 18 +++++++++- www/js/player-new.js | 68 +++++++++++++++++++++++++++----------- www/js/ui.js | 4 +-- 5 files changed, 110 insertions(+), 44 deletions(-) diff --git a/player/youtube.coffee b/player/youtube.coffee index 7f0db37c..bd3e1dcb 100644 --- a/player/youtube.coffee +++ b/player/youtube.coffee @@ -8,21 +8,25 @@ window.YouTubePlayer = class YouTubePlayer extends Player @pauseSeekRaceCondition = false waitUntilDefined(window, 'YT', => - removeOld() + # Even after window.YT is defined, YT.Player may not be, which causes a + # "YT.Player is not a constructor" error occasionally + waitUntilDefined(YT, 'Player', => + removeOld() - wmode = if USEROPTS.wmode_transparent then 'transparent' else 'opaque' - @yt = new YT.Player('ytapiplayer', - videoId: data.id - playerVars: - autohide: 1 - autoplay: 1 - controls: 1 - iv_load_policy: 3 # iv_load_policy 3 indicates no annotations - rel: 0 - wmode: wmode - events: - onReady: @onReady.bind(this) - onStateChange: @onStateChange.bind(this) + wmode = if USEROPTS.wmode_transparent then 'transparent' else 'opaque' + @yt = new YT.Player('ytapiplayer', + videoId: data.id + playerVars: + autohide: 1 + autoplay: 1 + controls: 1 + iv_load_policy: 3 # iv_load_policy 3 indicates no annotations + rel: 0 + wmode: wmode + events: + onReady: @onReady.bind(this) + onStateChange: @onStateChange.bind(this) + ) ) ) @@ -32,7 +36,7 @@ window.YouTubePlayer = class YouTubePlayer extends Player @yt.loadVideoById(data.id, data.currentTime) @qualityRaceCondition = true if USEROPTS.default_quality - @yt.setPlaybackQuality(USEROPTS.default_quality) + @setQuality(USEROPTS.default_quality) else console.error('WTF? YouTubePlayer::load() called but yt is not ready') @@ -46,7 +50,7 @@ window.YouTubePlayer = class YouTubePlayer extends Player if @qualityRaceCondition @qualityRaceCondition = false if USEROPTS.default_quality - @yt.setPlaybackQuality(USEROPTS.default_quality) + @setQuality(USEROPTS.default_quality) # Similar to above, if you pause the video before the first PLAYING # event is emitted, weird things happen. @@ -85,6 +89,22 @@ window.YouTubePlayer = class YouTubePlayer extends Player @yt.unMute() @yt.setVolume(volume * 100) + setQuality: (quality) -> + if not @yt or not @yt.ready + return + + ytQuality = switch String(quality) + when "240" then "small" + when "360" then "medium" + when "480" then "large" + when "720" then "hd720" + when "1080" then "hd1080" + when "best" then "highres" + else "auto" + + if ytQuality != "auto" + @yt.setPlaybackQuality(ytQuality) + getTime: (cb) -> if @yt and @yt.ready cb(@yt.getCurrentTime()) diff --git a/templates/useroptions.jade b/templates/useroptions.jade index cff8dd95..4a427b1d 100644 --- a/templates/useroptions.jade +++ b/templates/useroptions.jade @@ -83,12 +83,12 @@ mixin us-playback .col-sm-8 select#us-default-quality.form-control option(value="auto") Auto - option(value="small") 240p - option(value="medium") 360p - option(value="large") 480p - option(value="hd720") 720p - option(value="hd1080") 1080p - option(value="highres") Highest Available + option(value="240") 240p + option(value="360") 360p + option(value="480") 480p + option(value="720") 720p + option(value="1080") 1080p + option(value="best") Highest Available mixin us-chat #us-chat.tab-pane diff --git a/www/js/data.js b/www/js/data.js index 7f29ddd0..ca0d0309 100644 --- a/www/js/data.js +++ b/www/js/data.js @@ -111,7 +111,7 @@ var USEROPTS = { ignore_channeljs : getOrDefault("ignore_channeljs", false), sort_rank : getOrDefault("sort_rank", true), sort_afk : getOrDefault("sort_afk", false), - default_quality : getOrDefault("default_quality", ""), + default_quality : getOrDefault("default_quality", "auto"), boop : getOrDefault("boop", "never"), secure_connection : getOrDefault("secure_connection", false), show_shadowchat : getOrDefault("show_shadowchat", false) @@ -137,6 +137,22 @@ if (["never", "onlyping", "always"].indexOf(USEROPTS.boop) === -1) { USEROPTS.boop = "onlyping"; } +// As of 3.8, preferred quality names are different +(function () { + var fix = { + small: "240", + medium: "360", + large: "480", + hd720: "720", + hd1080: "1080", + highres: "best" + }; + + if (fix.hasOwnProperty(USEROPTS.default_quality)) { + USEROPTS.default_quality = fix[USEROPTS.default_quality]; + } +})(); + var VOLUME = parseFloat(getOrDefault("volume", 1)); var NO_WEBSOCKETS = USEROPTS.altsocket; diff --git a/www/js/player-new.js b/www/js/player-new.js index bbb3204d..543a3234 100644 --- a/www/js/player-new.js +++ b/www/js/player-new.js @@ -162,23 +162,25 @@ this.pauseSeekRaceCondition = false; waitUntilDefined(window, 'YT', (function(_this) { return function() { - var wmode; - removeOld(); - wmode = USEROPTS.wmode_transparent ? 'transparent' : 'opaque'; - return _this.yt = new YT.Player('ytapiplayer', { - videoId: data.id, - playerVars: { - autohide: 1, - autoplay: 1, - controls: 1, - iv_load_policy: 3, - rel: 0, - wmode: wmode - }, - events: { - onReady: _this.onReady.bind(_this), - onStateChange: _this.onStateChange.bind(_this) - } + return waitUntilDefined(YT, 'Player', function() { + var wmode; + removeOld(); + wmode = USEROPTS.wmode_transparent ? 'transparent' : 'opaque'; + return _this.yt = new YT.Player('ytapiplayer', { + videoId: data.id, + playerVars: { + autohide: 1, + autoplay: 1, + controls: 1, + iv_load_policy: 3, + rel: 0, + wmode: wmode + }, + events: { + onReady: _this.onReady.bind(_this), + onStateChange: _this.onStateChange.bind(_this) + } + }); }); }; })(this)); @@ -190,7 +192,7 @@ this.yt.loadVideoById(data.id, data.currentTime); this.qualityRaceCondition = true; if (USEROPTS.default_quality) { - return this.yt.setPlaybackQuality(USEROPTS.default_quality); + return this.setQuality(USEROPTS.default_quality); } } else { return console.error('WTF? YouTubePlayer::load() called but yt is not ready'); @@ -206,7 +208,7 @@ if (this.qualityRaceCondition) { this.qualityRaceCondition = false; if (USEROPTS.default_quality) { - this.yt.setPlaybackQuality(USEROPTS.default_quality); + this.setQuality(USEROPTS.default_quality); } } if (ev.data === YT.PlayerState.PLAYING && this.pauseSeekRaceCondition) { @@ -253,6 +255,34 @@ } }; + YouTubePlayer.prototype.setQuality = function(quality) { + var ytQuality; + if (!this.yt || !this.yt.ready) { + return; + } + ytQuality = (function() { + switch (String(quality)) { + case "240": + return "small"; + case "360": + return "medium"; + case "480": + return "large"; + case "720": + return "hd720"; + case "1080": + return "hd1080"; + case "best": + return "highres"; + default: + return "auto"; + } + })(); + if (ytQuality !== "auto") { + return this.yt.setPlaybackQuality(ytQuality); + } + }; + YouTubePlayer.prototype.getTime = function(cb) { if (this.yt && this.yt.ready) { return cb(this.yt.getCurrentTime()); diff --git a/www/js/ui.js b/www/js/ui.js index deb79303..a156c1f6 100644 --- a/www/js/ui.js +++ b/www/js/ui.js @@ -296,8 +296,8 @@ $("#userpl_save").click(function() { /* video controls */ $("#mediarefresh").click(function() { - PLAYER.type = ""; - PLAYER.id = ""; + PLAYER.mediaType = ""; + PLAYER.mediaId = ""; // playerReady triggers the server to send a changeMedia. // the changeMedia handler then reloads the player socket.emit("playerReady");