Initial soundcloud implementation

This commit is contained in:
calzoneman 2015-06-16 07:39:39 -04:00
parent ce8ac4591e
commit 480497bea4
4 changed files with 231 additions and 332 deletions

105
player/soundcloud.coffee Normal file
View File

@ -0,0 +1,105 @@
window.SoundCloudPlayer = class SoundCloudPlayer extends Player
constructor: (data) ->
if not (this instanceof SoundCloudPlayer)
return new SoundCloudPlayer(data)
@setMediaProperties(data)
waitUntilDefined(window, 'SC', =>
removeOld()
# For tracks that are private, but embeddable, the API returns a
# special URL to load into the player.
# TODO: rename scuri?
if data.meta.scuri
soundUrl = data.meta.scuri
else
soundUrl = data.id
widget = $('<iframe/>').appendTo($('#ytapiplayer'))
widget.attr(
id: 'scplayer'
src: "https://w.soundcloud.com/player/?url=#{soundUrl}"
)
# Soundcloud embed widget doesn't have a volume control.
volumeSlider = $('<div/>').attr('id', 'widget-volume')
.css('top', '170px')
.insertAfter(widget)
.slider(
range: 'min'
value: VOLUME * 100
stop: (event, ui) =>
@setVolume(ui.value / 100)
)
@soundcloud = SC.Widget(widget[0])
@soundcloud.bind(SC.Widget.Events.READY, =>
@soundcloud.ready = true
@setVolume(VOLUME)
@play()
@soundcloud.bind(SC.Widget.Events.PAUSE, =>
@paused = true
if CLIENT.leader
sendVideoUpdate()
)
@soundcloud.bind(SC.Widget.Events.PLAY, =>
@paused = false
if CLIENT.leader
sendVideoUpdate()
)
@soundcloud.bind(SC.Widget.Events.FINISH, =>
if CLIENT.leader
socket.emit('playNext')
)
)
)
load: (data) ->
@setMediaProperties(data)
if @soundcloud and @soundcloud.ready
if data.meta.scuri
soundUrl = data.meta.scuri
else
soundUrl = data.id
@soundcloud.load(soundUrl, auto_play: true)
else
console.error('SoundCloudPlayer::load() called but soundcloud is not ready')
play: ->
@paused = false
if @soundcloud and @soundcloud.ready
@soundcloud.play()
pause: ->
@paused = true
if @soundcloud and @soundcloud.ready
@soundcloud.pause()
seekTo: (time) ->
if @soundcloud and @soundcloud.ready
# SoundCloud measures time in milliseconds while CyTube uses seconds.
@soundcloud.seekTo(time * 1000)
setVolume: (volume) ->
# NOTE: SoundCloud's documentation claims that setVolume() accepts
# volumes in the range [0, 100], however it *actually* accepts volumes
# in the range [0, 1] (anything larger than 1 is treated as 1). I
# emailed them about this 2 years ago and they still haven't fixed
# their documentation.
if @soundcloud and @soundcloud.ready
@soundcloud.setVolume(volume)
getTime: (cb) ->
if @soundcloud and @soundcloud.ready
# Returned time is in milliseconds; CyTube expects seconds
@soundcloud.getPosition((time) -> cb(time / 1000))
else
cb(0)
getVolume: (cb) ->
if @soundcloud and @soundcloud.ready
@soundcloud.getVolume(cb)
else
cb(VOLUME)

View File

@ -4,6 +4,7 @@ TYPE_MAP =
dm: DailymotionPlayer dm: DailymotionPlayer
gd: VideoJSPlayer gd: VideoJSPlayer
gp: VideoJSPlayer gp: VideoJSPlayer
sc: SoundCloudPlayer
window.loadMediaPlayer = (data) -> window.loadMediaPlayer = (data) ->
if data.type of TYPE_MAP if data.type of TYPE_MAP

View File

@ -1,5 +1,5 @@
(function() { (function() {
var DailymotionPlayer, Player, TYPE_MAP, VideoJSPlayer, VimeoPlayer, YouTubePlayer, sortSources, var DailymotionPlayer, Player, SoundCloudPlayer, TYPE_MAP, 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; }, 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; hasProp = {}.hasOwnProperty;
@ -593,12 +593,134 @@
})(Player); })(Player);
window.SoundCloudPlayer = SoundCloudPlayer = (function(superClass) {
extend(SoundCloudPlayer, superClass);
function SoundCloudPlayer(data) {
if (!(this instanceof SoundCloudPlayer)) {
return new SoundCloudPlayer(data);
}
this.setMediaProperties(data);
waitUntilDefined(window, 'SC', (function(_this) {
return function() {
var soundUrl, volumeSlider, widget;
removeOld();
if (data.meta.scuri) {
soundUrl = data.meta.scuri;
} else {
soundUrl = data.id;
}
widget = $('<iframe/>').appendTo($('#ytapiplayer'));
widget.attr({
id: 'scplayer',
src: "https://w.soundcloud.com/player/?url=" + soundUrl
});
volumeSlider = $('<div/>').attr('id', 'widget-volume').css('top', '170px').insertAfter(widget).slider({
range: 'min',
value: VOLUME * 100,
stop: function(event, ui) {
return _this.setVolume(ui.value / 100);
}
});
_this.soundcloud = SC.Widget(widget[0]);
return _this.soundcloud.bind(SC.Widget.Events.READY, function() {
_this.soundcloud.ready = true;
_this.setVolume(VOLUME);
_this.play();
_this.soundcloud.bind(SC.Widget.Events.PAUSE, function() {
_this.paused = true;
if (CLIENT.leader) {
return sendVideoUpdate();
}
});
_this.soundcloud.bind(SC.Widget.Events.PLAY, function() {
_this.paused = false;
if (CLIENT.leader) {
return sendVideoUpdate();
}
});
return _this.soundcloud.bind(SC.Widget.Events.FINISH, function() {
if (CLIENT.leader) {
return socket.emit('playNext');
}
});
});
};
})(this));
}
SoundCloudPlayer.prototype.load = function(data) {
var soundUrl;
this.setMediaProperties(data);
if (this.soundcloud && this.soundcloud.ready) {
if (data.meta.scuri) {
soundUrl = data.meta.scuri;
} else {
soundUrl = data.id;
}
return this.soundcloud.load(soundUrl, {
auto_play: true
});
} else {
return console.error('SoundCloudPlayer::load() called but soundcloud is not ready');
}
};
SoundCloudPlayer.prototype.play = function() {
this.paused = false;
if (this.soundcloud && this.soundcloud.ready) {
return this.soundcloud.play();
}
};
SoundCloudPlayer.prototype.pause = function() {
this.paused = true;
if (this.soundcloud && this.soundcloud.ready) {
return this.soundcloud.pause();
}
};
SoundCloudPlayer.prototype.seekTo = function(time) {
if (this.soundcloud && this.soundcloud.ready) {
return this.soundcloud.seekTo(time * 1000);
}
};
SoundCloudPlayer.prototype.setVolume = function(volume) {
if (this.soundcloud && this.soundcloud.ready) {
return this.soundcloud.setVolume(volume);
}
};
SoundCloudPlayer.prototype.getTime = function(cb) {
if (this.soundcloud && this.soundcloud.ready) {
return this.soundcloud.getPosition(function(time) {
return cb(time / 1000);
});
} else {
return cb(0);
}
};
SoundCloudPlayer.prototype.getVolume = function(cb) {
if (this.soundcloud && this.soundcloud.ready) {
return this.soundcloud.getVolume(cb);
} else {
return cb(VOLUME);
}
};
return SoundCloudPlayer;
})(Player);
TYPE_MAP = { TYPE_MAP = {
yt: YouTubePlayer, yt: YouTubePlayer,
vi: VimeoPlayer, vi: VimeoPlayer,
dm: DailymotionPlayer, dm: DailymotionPlayer,
gd: VideoJSPlayer, gd: VideoJSPlayer,
gp: VideoJSPlayer gp: VideoJSPlayer,
sc: SoundCloudPlayer
}; };
window.loadMediaPlayer = function(data) { window.loadMediaPlayer = function(data) {

File diff suppressed because one or more lines are too long