diff --git a/player/twitch.coffee b/player/twitch.coffee
new file mode 100644
index 00000000..57419ec5
--- /dev/null
+++ b/player/twitch.coffee
@@ -0,0 +1,50 @@
+window.twitchEventCallback = (events) ->
+ if not (PLAYER instanceof TwitchPlayer)
+ return false
+
+ events.forEach((event) ->
+ if event.event == 'playerInit'
+ PLAYER.twitch.unmute()
+ PLAYER.twitch.ready = true
+ )
+
+window.TwitchPlayer = class TwitchPlayer extends Player
+ constructor: (data) ->
+ if not (this instanceof TwitchPlayer)
+ return new TwitchPlayer(data)
+
+ @load(data)
+
+ load: (data) ->
+ @setMediaProperties(data)
+
+ object = $('').attr(
+ # NOTE: Must be protocol-relative or else flash throws errors when
+ # you try to call API functions.
+ data: '//www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf'
+ type: 'application/x-shockwave-flash'
+ )
+ $('').attr(
+ name: 'allowScriptAccess'
+ value: 'always'
+ ).appendTo(object)
+ $('').attr(
+ name: 'allowFullScreen'
+ value: 'true'
+ ).appendTo(object)
+ # NOTE: start_volume can be used to set the initial player volume,
+ # however it is impossible to manipulate or query it from the player
+ # later.
+ $('').attr(
+ name: 'flashvars'
+ value: "embed=1&\
+ hostname=localhost&\
+ channel=#{data.id}&
+ eventsCallback=twitchEventCallback&\
+ auto_play=true&\
+ start_volume=#{Math.floor(VOLUME * 100)}"
+ ).appendTo(object)
+
+ removeOld(object)
+
+ @twitch = object[0]
diff --git a/player/update.coffee b/player/update.coffee
index bfd4d6b4..842d6c95 100644
--- a/player/update.coffee
+++ b/player/update.coffee
@@ -6,6 +6,7 @@ TYPE_MAP =
gp: VideoJSPlayer
sc: SoundCloudPlayer
li: LivestreamPlayer
+ tw: TwitchPlayer
window.loadMediaPlayer = (data) ->
if data.type of TYPE_MAP
diff --git a/www/js/player-new.js b/www/js/player-new.js
index 46f11029..3eb19df5 100644
--- a/www/js/player-new.js
+++ b/www/js/player-new.js
@@ -1,5 +1,5 @@
(function() {
- var DailymotionPlayer, LivestreamPlayer, Player, SoundCloudPlayer, TYPE_MAP, VideoJSPlayer, VimeoPlayer, YouTubePlayer, sortSources,
+ var DailymotionPlayer, LivestreamPlayer, Player, SoundCloudPlayer, TYPE_MAP, TwitchPlayer, VideoJSPlayer, VimeoPlayer, YouTubePlayer, sortSources,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
@@ -737,6 +737,55 @@
})(Player);
+ window.twitchEventCallback = function(events) {
+ if (!(PLAYER instanceof TwitchPlayer)) {
+ return false;
+ }
+ return events.forEach(function(event) {
+ if (event.event === 'playerInit') {
+ PLAYER.twitch.unmute();
+ return PLAYER.twitch.ready = true;
+ }
+ });
+ };
+
+ window.TwitchPlayer = TwitchPlayer = (function(superClass) {
+ extend(TwitchPlayer, superClass);
+
+ function TwitchPlayer(data) {
+ if (!(this instanceof TwitchPlayer)) {
+ return new TwitchPlayer(data);
+ }
+ this.load(data);
+ }
+
+ TwitchPlayer.prototype.load = function(data) {
+ var object;
+ this.setMediaProperties(data);
+ object = $('').attr({
+ data: '//www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf',
+ type: 'application/x-shockwave-flash'
+ });
+ $('').attr({
+ name: 'allowScriptAccess',
+ value: 'always'
+ }).appendTo(object);
+ $('').attr({
+ name: 'allowFullScreen',
+ value: 'true'
+ }).appendTo(object);
+ $('').attr({
+ name: 'flashvars',
+ value: "embed=1&hostname=localhost&channel=" + data.id + "& eventsCallback=twitchEventCallback&auto_play=true&start_volume=" + (Math.floor(VOLUME * 100))
+ }).appendTo(object);
+ removeOld(object);
+ return this.twitch = object[0];
+ };
+
+ return TwitchPlayer;
+
+ })(Player);
+
TYPE_MAP = {
yt: YouTubePlayer,
vi: VimeoPlayer,
@@ -744,7 +793,8 @@
gd: VideoJSPlayer,
gp: VideoJSPlayer,
sc: SoundCloudPlayer,
- li: LivestreamPlayer
+ li: LivestreamPlayer,
+ tw: TwitchPlayer
};
window.loadMediaPlayer = function(data) {