From d77497aaa755b8b26661c6fb33adf496e4d340c2 Mon Sep 17 00:00:00 2001 From: calzoneman Date: Thu, 23 Apr 2015 22:24:43 -0500 Subject: [PATCH] Work on YouTube player --- player/base.coffee | 6 ++- player/youtube.coffee | 67 +++++++++++++++++++++++++++++++- www/js/player-new.js | 89 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 155 insertions(+), 7 deletions(-) diff --git a/player/base.coffee b/player/base.coffee index 76b581be..a973cbea 100644 --- a/player/base.coffee +++ b/player/base.coffee @@ -1,11 +1,15 @@ class Player constructor: (data) -> - @load(data) + @setMediaProperties(data) @paused = false load: (data) -> + @setMediaProperties(data) + + setMediaProperties: (data) -> @mediaId = data.id @mediaType = data.type + @mediaLength = data.seconds play: -> @paused = false diff --git a/player/youtube.coffee b/player/youtube.coffee index 2a33f375..867c6148 100644 --- a/player/youtube.coffee +++ b/player/youtube.coffee @@ -1,6 +1,9 @@ class YouTubePlayer extends Player constructor: (data) -> - super() + @setMediaProperties(data) + @qualityRaceCondition = true + @pauseSeekRaceCondition = true + waitUntilDefined(window, 'YT', => removeOld() @@ -11,7 +14,7 @@ class YouTubePlayer extends Player autohide: 1 autoplay: 1 controls: 1 - iv_load_policy: 3 + iv_load_policy: 3 # iv_load_policy 3 indicates no annotations rel: 0 wmode: wmode events: @@ -20,8 +23,68 @@ class YouTubePlayer extends Player ) ) + load: (data) -> + super(data) + if @yt + @yt.loadVideoById(data.id, data.currentTime) + @qualityRaceCondition = true + if USEROPTS.default_quality + @yt.setPlaybackQuality(USEROPTS.default_quality) + onReady: -> @yt.setVolume(VOLUME) onStateChange: (ev) -> + # For some reason setting the quality doesn't work + # until the first event has fired. + if @qualityRaceCondition + @qualityRaceCondition = false + @yt.setPlaybackQuality(USEROPTS.default_quality) + # Similar to above, if you pause the video before the first PLAYING + # event is emitted, weird things happen. + if ev.data == YT.PlayerState.PLAYING and @pauseSeekRaceCondition + @pause() + @pauseSeekRaceCondition = false + + if (ev.data == YT.PlayerState.PAUSED and not @paused) or + (ev.data == YT.PlayerState.PLAYING and @paused) + @paused = (ev.data == YT.PlayerState.PAUSED) + if CLIENT.leader + sendVideoUpdate() + + if ev.data == YT.PlayerState.ENDED and CLIENT.leader + socket.emit('playNext') + + play: -> + super() + if @yt + @yt.playVideo() + + pause: -> + super() + if @yt + @yt.pauseVideo() + + seekTo: (time) -> + if @yt + @yt.seekTo(time, true) + + setVolume: (volume) -> + if @yt + if volume > 0 + # If the player is muted, even if the volume is set, + # the player remains muted + @yt.unMute() + @yt.setVolume(volume * 100) + + getTime: (cb) -> + if @yt + cb(@yt.getCurrentTime()) + + getVolume: (cb) -> + if @yt + if @yt.isMuted() + return 0 + else + return @yt.getVolume() / 100.0 diff --git a/www/js/player-new.js b/www/js/player-new.js index 40caf653..dbf9cd04 100644 --- a/www/js/player-new.js +++ b/www/js/player-new.js @@ -5,13 +5,18 @@ Player = (function() { function Player(data) { - this.load(data); + this.setMediaProperties(data); this.paused = false; } Player.prototype.load = function(data) { + return this.setMediaProperties(data); + }; + + Player.prototype.setMediaProperties = function(data) { this.mediaId = data.id; - return this.mediaType = data.type; + this.mediaType = data.type; + return this.mediaLength = data.seconds; }; Player.prototype.play = function() { @@ -74,7 +79,9 @@ extend(YouTubePlayer, superClass); function YouTubePlayer(data) { - YouTubePlayer.__super__.constructor.call(this); + this.setMediaProperties(data); + this.qualityRaceCondition = true; + this.pauseSeekRaceCondition = true; waitUntilDefined(window, 'YT', (function(_this) { return function() { var wmode; @@ -99,11 +106,85 @@ })(this)); } + YouTubePlayer.prototype.load = function(data) { + YouTubePlayer.__super__.load.call(this, data); + if (this.yt) { + this.yt.loadVideoById(data.id, data.currentTime); + this.qualityRaceCondition = true; + if (USEROPTS.default_quality) { + return this.yt.setPlaybackQuality(USEROPTS.default_quality); + } + } + }; + YouTubePlayer.prototype.onReady = function() { return this.yt.setVolume(VOLUME); }; - YouTubePlayer.prototype.onStateChange = function(ev) {}; + YouTubePlayer.prototype.onStateChange = function(ev) { + if (this.qualityRaceCondition) { + this.qualityRaceCondition = false; + this.yt.setPlaybackQuality(USEROPTS.default_quality); + } + if (ev.data === YT.PlayerState.PLAYING && this.pauseSeekRaceCondition) { + this.pause(); + this.pauseSeekRaceCondition = false; + } + if ((ev.data === YT.PlayerState.PAUSED && !this.paused) || (ev.data === YT.PlayerState.PLAYING && this.paused)) { + this.paused = ev.data === YT.PlayerState.PAUSED; + if (CLIENT.leader) { + sendVideoUpdate(); + } + } + if (ev.data === YT.PlayerState.ENDED && CLIENT.leader) { + return socket.emit('playNext'); + } + }; + + YouTubePlayer.prototype.play = function() { + YouTubePlayer.__super__.play.call(this); + if (this.yt) { + return this.yt.playVideo(); + } + }; + + YouTubePlayer.prototype.pause = function() { + YouTubePlayer.__super__.pause.call(this); + if (this.yt) { + return this.yt.pauseVideo(); + } + }; + + YouTubePlayer.prototype.seekTo = function(time) { + if (this.yt) { + return this.yt.seekTo(time, true); + } + }; + + YouTubePlayer.prototype.setVolume = function(volume) { + if (this.yt) { + if (volume > 0) { + this.yt.unMute(); + } + return this.yt.setVolume(volume * 100); + } + }; + + YouTubePlayer.prototype.getTime = function(cb) { + if (this.yt) { + return cb(this.yt.getCurrentTime()); + } + }; + + YouTubePlayer.prototype.getVolume = function(cb) { + if (this.yt) { + if (this.yt.isMuted()) { + return 0; + } else { + return this.yt.getVolume() / 100.0; + } + } + }; return YouTubePlayer;