感谢其他人的问题,在DOM中点击时,我已经获得了AJAX链接来处理单个歌曲。我的问题是我需要找到一种方法来加载soundcloud上给定用户帐户下的所有曲目。我编辑了stratus.js文件,使其通过使用.delegate()来监听点击,但我无法弄清楚如何从soundcloud调用轨道列表并通过给定的iframe加载它。这是stratus.js文件。
(function() {
var $;
$ = jQuery;
(function($){var g,d,j=1,a,b=this,f=!1,h="postMessage",e="addEventListener",c,i=b[h]&&!$.browser.opera;$[h]=function(k,l,m){if(!l){return}k=typeof k==="string"?k:$.param(k);m=m||parent; if(i){m[h](k,l.replace(/([^:]+:\/\/[^\/]+).*/,"$1"))}else{if(l){m.location=l.replace(/#.*$/,"")+"#"+(+new Date)+(j++)+"&"+k}}};$.receiveMessage=c=function(l,m,k){if(i){if(l){a&&c(); a=function(n){if((typeof m==="string"&&n.origin!==m)||($.isFunction(m)&&m(n.origin)===f)){return f}l(n)}}if(b[e]){b[l?e:"removeEventListener"]("message",a,f)} else{b[l?"attachEvent":"detachEvent"]("onmessage",a)}}else{g&&clearInterval(g);g=null;if(l){k=typeof m==="number"?m:typeof k==="number"?k:100; g=setInterval(function(){var o=document.location.hash,n=/^#?\d+&/;if(o!==d&&n.test(o)){d=o;l({data:o.replace(n,"")})}},k)}}}})(jQuery);
$.fn.stratus = function(settings) {
return $.stratus(settings);
};
$.stratus = function(settings) {
var root_url, src;
root_url = settings.env === 'development' ? 'http://example.com:3000' : 'http://stratus.sc';
$('head').append("<link rel='stylesheet' href='" + root_url + "/stratus.css' type='text/css'/>");
if (settings.align === 'top') {
$('head').append("<style>#stratus{ top: 0; }</style>");
}
if (settings.position === 'absolute') {
$('head').append("<style>#stratus{ position: absolute; }</style>");
}
if (settings.offset) {
$('head').append("<style>#stratus{ " + settings.align + ": " + settings.offset + "px !important; }</style>");
}
$('body').append("<div id='stratus'><iframe allowtransparency='true' frameborder='0' scrolling='0'></div>");
src = root_url + '/player?' + $.param(settings, true) + '&link=' + encodeURIComponent(document.location.href);
$('#stratus iframe').attr({
src: src
});
$('#stratus iframe').load(function() {// /resolve?url=
return $(this).css({
visibility: 'visible'
});
});
$('#stratus').show();
$(document).delegate("a.stratus","click", function () {
$.postMessage($(this).attr('href'), src, $('#stratus iframe')[0].contentWindow);
return false;
});
return $.receiveMessage(function(e) {
return $('#stratus').toggleClass('open');
}, root_url);
};
}).call(this);
我认为通过Soundcloud API进行调用是必要的,然后通过iframe运行用于添加单个轨道的用户数据。这是player.js文件,我不确定这篇文章是否必要,但它帮助我开始了解从可自定义的链接字段中添加曲目的初步情况:
console.log("Stratus loading...");
$(function() {
var b, booleans, getScaledImageData, link, params, scApiUrl, source_origin, strtobool, timecode, _i, _len;
window.Track = Backbone.Model.extend({
initialize: function() {
var that, track;
that = this;
track = this.attributes;
track.timecode = timecode(track.duration);
return soundManager.createSound({
id: "sound_" + track.id,
multiShot: false,
url: track.stream_url + (/\?/.test(track.stream_url) ? '&' : '?') + 'consumer_key=' + Stratus.options.key,
volume: Stratus.options.volume,
whileplaying: function() {
Stratus.$('.played').width((this.position / track.duration * 100) + '%');
return Stratus.$('#player .duration').text(timecode(this.position) + ' / ' + timecode(track.duration));
},
whileloading: function() {
return Stratus.$('.loaded').width((this.bytesLoaded / this.bytesTotal * 100) + '%');
},
onplay: function() {
if (this.loaded) {
return Stratus.$('.loaded').width('100%');
}
},
onresume: function() {
if (this.loaded) {
return Stratus.$('.loaded').width('100%');
}
},
onfinish: function() {
return Stratus.nextTrack();
}
});
},
sound: function() {
return "sound_" + this.id;
},
play: function() {
return soundManager.play(this.sound());
},
pause: function() {
return soundManager.pause(this.sound());
},
seek: function(relative) {
return soundManager.setPosition(this.sound(), this.get('duration') * relative);
},
getWave: function(callback) {
var that;
that = this;
return $.getJSON('http://wave64.heroku.com/w?callback=?', {
url: this.get('waveform_url')
}, function(data) {
var waveform;
waveform = new Image();
waveform.src = data.data;
return waveform.onload = function() {
var waveform_data;
waveform_data = getScaledImageData(waveform);
that.set({
'waveform_data': waveform_data
});
return callback();
};
});
},
comment: function(text) {
return SC.post("/tracks/" + this.id + "/comments", {
"comment[body]": text
}, function() {
Stratus.$('#comment input').val('');
Stratus.toggleComment();
return alert("Comment posted!");
});
},
favorite: function() {
if (Stratus.$('.love').hasClass('loved')) {
return SC["delete"]("/me/favorites/" + this.id, function() {
return Stratus.$('.love').removeClass('loved');
});
} else {
return SC.put("/me/favorites/" + this.id, function() {
return Stratus.$('.love').addClass('loved');
});
}
},
isFavorite: function() {
return SC.get("/me/favorites/" + this.id, function(data) {
if (!(data.errors != null)) {
return Stratus.$('.love').addClass('loved');
}
});
}
});
window.TrackList = Backbone.Collection.extend({
model: Track,
select: function(track) {
this.stop();
this.current = track;
return this.trigger('player:select');
},
toggle: function(track) {
if (track && this.current !== track) {
this.select(track);
}
if (this.playing) {
return this.pause();
} else {
return this.play();
}
},
play: function(track) {
if (track && this.current !== track) {
this.select(track);
}
this.playing = true;
this.current.play();
return this.trigger('player:toggle');
},
pause: function() {
this.playing = false;
this.current.pause();
return this.trigger('player:toggle');
},
stop: function() {
this.playing = false;
return soundManager.stopAll();
},
prev: function() {
var i;
i = this.indexOf(this.current) - 1;
if (i > -1) {
return this.at(i);
} else {
return this.last();
}
},
next: function() {
var i;
i = this.indexOf(this.current) + 1;
if (i < _.size(this)) {
return this.at(i);
} else {
return this.first();
}
},
random: function() {
var i;
i = Math.round(Math.random() * _.size(this));
return this.at(i);
}
});
window.Tracks = new TrackList();
window.TrackView = Backbone.View.extend({
tagName: "li",
events: {
"click": "toggleTrack"
},
render: function() {
return $(this.el).html(ich.track(this.model.toJSON()));
},
toggleTrack: function() {
return Tracks.toggle(this.model);
}
});
window.AppView = Backbone.View.extend({
el: $('#stratus'),
defaults: {
align: 'bottom',
animate: 'slide',
auto_play: false,
buying: true,
color: 'F60',
download: true,
env: 'production',
key: 'ybtyKcnlhP3RKXpJ58fg',
links: ['http://soundcloud.com/qotsa/sets/test'],
random: false,
redirect: 'http://stratus.sc/callback.html',
user: true,
stats: true,
volume: 50
},
events: {
"dblclick": "showDrawer",
"click .prev": "prevTrack",
"click .toggle": "toggleCurrent",
"click .next": "nextTrack",
"click #time": "seekTrack",
"mousemove #time": "movePosition",
"click .share": "toggleShare",
"click .close.sharing": "toggleShare",
"click .comment": "toggleComment",
"click .close.commenting": "toggleComment",
"keypress #add input": "commentTrack",
"click .love": "favoriteTrack",
"click #avatar": "logout",
"click .popup": "popupPlayer"
},
initialize: function() {
var options, that;
console.log("Stratus initializing...");
that = this;
this.options = options = _.extend(this.defaults, this.options);
Tracks.bind('add', this.add, this);
Tracks.bind('player:select', this.render, this);
Tracks.bind('player:toggle', this.toggle, this);
SC.initialize({
client_id: options.key,
redirect_uri: options.redirect
});
return SC.whenStreamingReady(function() {
return that.loadTracks(options.links, function() {
Tracks.select(options.random ? Tracks.random() : Tracks.first());
if (options.auto_play) {
Tracks.play();
}
if (options.align === 'top') {
options.top = true;
}
options.color = {
base: tinycolor(options.color).toHexString(),
light: tinycolor.lighten(options.color).toHexString(),
dark: tinycolor.darken(options.color).toHexString()
};
$('head').append(ich.theme(options));
if (SC.isConnected()) {
that.updateUser();
}
return that.animate(function() {
return that.resize();
});
});
});
},
loadTracks: function(links, callback) {
var index, loadURL;
index = 0;
loadURL = function(link) {
var url;
console.log("Loading " + link + "...");
url = scApiUrl(link);
return SC.get(url, function(data) {
index += 1;
if (data.tracks) {
Tracks.add(data.tracks);
} else if (data.username || data.creator) {
links.push(data.uri + '/tracks');
} else {
Tracks.add(data);
}
if (links[index]) {
return loadURL(links[index]);
} else {
return callback();
}
});
};
return loadURL(links[index]);
},
render: function() {
var artwork, data, el, that, track;
that = this;
track = Tracks.current;
data = Tracks.current.toJSON();
el = this.$('#tracks .track_' + data.id);
this.$('#player .track').html(ich.current(data));
this.$('#buttons').html(ich.buttons(data));
this.$('#stats').html(ich.stats(data));
this.$('#share').html(ich.share(data));
artwork = data.artwork_url ? data.artwork_url : data.user.avatar_url;
this.$('#artwork img').attr({
src: artwork.replace('-large', '-t300x300')
});
el.addClass('current').siblings().removeClass('current');
if (track.has('waveform_data')) {
this.updateWave(track);
} else {
track.getWave(function() {
return that.updateWave(track);
});
}
if (SC.isConnected()) {
track.isFavorite();
}
return this.resize();
},
add: function(track) {
var view;
view = new TrackView({
model: track,
className: 'track track_' + track.id
});
return this.$("#tracks").append(view.render());
},
toggle: function() {
return this.$('#player').toggleClass('playing', Tracks.playing);
},
toggleCurrent: function() {
Tracks.toggle();
return false;
},
prevTrack: function() {
Tracks.play(Tracks.prev());
return false;
},
nextTrack: function() {
Tracks.play(Tracks.next());
return false;
},
seekTrack: function(e) {
var relative;
if (!Tracks.playing) {
Tracks.play();
}
relative = Math.min(this.$('.loaded').width(), (e.pageX - this.$('#time').offset().left) / this.$('#time').width());
Tracks.current.seek(relative);
return false;
},
movePosition: function(e) {
return this.$('.position').css({
"left": e.pageX - this.$('#time').offset().left
});
},
updateWave: function(track) {
var canvas, context;
canvas = this.$('#waveform').get(0);
context = canvas.getContext('2d');
canvas.setAttribute('width', 180);
canvas.setAttribute('height', 40);
context.clearRect(0, 0, 180, 40);
return context.putImageData(track.get('waveform_data'), 0, 0);
},
animate: function(callback) {
if (this.options.popup) {
this.$('#player, #drawer').fadeIn('slow');
}
switch (this.options.animate) {
case 'slide':
return this.$('#player').slideDown('slow', function() {
return callback();
});
case 'fade':
return this.$('#player').fadeIn('slow', function() {
return callback();
});
default:
return this.$('#player').show(0, function() {
return callback();
});
}
},
resize: function() {
this.$('#share').css({
"margin-right": this.$('#buttons').width() - 30
});
return this.$('#comment').css({
"margin-right": this.$('#buttons').width() - 60
});
},
showDrawer: function() {
this.$('#drawer').toggle();
return $.postMessage(true, source_origin, parent);
},
popupPlayer: function() {
Tracks.stop();
this.toggle();
return $.popupWindow($.url().attr('source') + '&popup=true', {
height: 199,
width: 800,
location: false
});
},
toggleShare: function() {
this.$('#share').toggle();
this.$('#share input').select();
return false;
},
toggleComment: function() {
var that;
that = this;
if (SC.isConnected()) {
this.$('#comment').toggle();
this.$('#comment input').select();
} else {
this.login(function() {
return that.toggleComment();
});
}
return false;
},
commentTrack: function(e) {
var text;
text = this.$('#comment input').val();
if (e.keyCode === 13) {
return Tracks.current.comment(text);
}
},
favoriteTrack: function() {
if (SC.isConnected()) {
Tracks.current.favorite();
} else {
this.login(function() {
return Tracks.current.favorite();
});
}
return false;
},
login: function(callback) {
var that;
that = this;
return SC.connect(function(user) {
that.updateUser();
return callback();
});
},
updateUser: function() {
var that;
that = this;
return SC.get("/me", function(user) {
return that.$('#avatar').attr({
src: user.avatar_url
});
});
},
logout: function() {
SC.disconnect();
return alert("Logged out.");
}
});
link = decodeURIComponent($.url().param('link'));
source_origin = $.url(link).attr('base');
$.receiveMessage(function(e) {
var result, url;
url = e.data;
result = Tracks.find(function(track) {
return track.get('permalink_url') === url;
});
if (result) {
return Tracks.toggle(result);
} else {
return SC.get("/resolve", {
url: url
}, function(track) {
Tracks.add(track);
return Tracks.play(Tracks.get(track.id));
});
}
}, source_origin);
scApiUrl = function(url) {
if (/api\./.test(url)) {
return url;
} else {
return "/resolve?url=" + url;
}
};
timecode = function(ms) {
return SC.Helper.millisecondsToHMS(ms);
};
strtobool = function(str) {
switch (str) {
case 'true':
return true;
case true:
return true;
default:
return false;
}
};
getScaledImageData = function(image) {
var color, height, isImageData, lastIndex, orig, origCtx, origImageData, origWidth, populateScaledImagedData, precise, scaleX, scaleY, scaled, scaledCtx, scaledImageData, width, x, y;
color = Stratus.$('#player').css('background-color');
color = tinycolor(color).toRgb();
precise = function(number, precision) {
precision = Math.pow(10, precision || 0);
return Math.round(number * precision) / precision;
};
populateScaledImagedData = function(x, y, srcImageData, indexOffset) {
var alpha, index, indexScaled, isOpaque;
indexOffset = indexOffset || 0;
index = (Math.floor(y / scaleY) * origWidth + Math.floor(x / scaleX)) * 4;
indexScaled = indexOffset + (y * width + x) * 4;
alpha = srcImageData.data[index + 3];
isOpaque = alpha === 255;
scaledImageData.data[indexScaled] = isOpaque ? color['r'] : 0;
scaledImageData.data[indexScaled + 1] = isOpaque ? color['g'] : 0;
scaledImageData.data[indexScaled + 2] = isOpaque ? color['b'] : 0;
scaledImageData.data[indexScaled + 3] = alpha;
return indexScaled;
};
height = 40;
width = 180;
origWidth = image.width;
scaleX = precise(width / image.width, 4);
scaleY = precise(height / image.height, 4);
try {
isImageData = !(image instanceof Image);
} catch (e) {
isImageData = image.hasOwnProperty("data") && image.data.hasOwnProperty("length");
}
orig = document.createElement("canvas");
orig.width = image.width;
orig.height = image.height;
origCtx = orig.getContext("2d");
if (!isImageData) {
origCtx.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height);
} else {
origCtx.putImageData(image, 0, 0);
}
origImageData = origCtx.getImageData(0, 0, image.width, image.height);
scaled = document.createElement("canvas");
scaled.width = width;
scaled.height = height;
scaledCtx = scaled.getContext("2d");
scaledImageData = scaledCtx.getImageData(0, 0, width, height);
y = 0;
while (y < height) {
x = 0;
while (x < width) {
lastIndex = populateScaledImagedData(x, y, origImageData, 0);
x++;
}
y++;
}
return scaledImageData;
};
params = $.url().param();
if (params.links) {
params.links = decodeURIComponent(params.links);
params.links = params.links.split(',');
}
if (params.redirect) {
params.redirect = decodeURIComponent(params.redirect);
}
booleans = ['auto_play', 'buying', 'download', 'random', 'user', 'stats', 'popup'];
for (_i = 0, _len = booleans.length; _i < _len; _i++) {
b = booleans[_i];
if (params[b]) {
params[b] = strtobool(params[b]);
}
}
return window.Stratus = new AppView(params);
});
我知道这是相当密集的,我为此道歉。只是抛出一个祈祷,我不会以负面的方式从根本上改变我的网站用户的体验。
答案 0 :(得分:0)
我不了解层云播放器,但总的来说 - 如果你想要检索特定用户的曲目列表 - 假设你知道用户的id,你确实必须制作调用soundcloud API。你可以这样做:
SC.initialize({
client_id: "YOUR_CLIENT_ID",
redirect_uri: "http://example.com/callback.html",
});
/**
Once that's done you are all set and ready to call the SoundCloud API.
**/
/**
Call to the SoundCloud API.
Retrieves list of tracks, and displays a list with links to the tracks showing 'tracktitle' and 'track duration'
**/
var userId = 39090345; // user_id of Prutsonic
SC.get("/tracks", {
user_id: userId,
limit: 100
}, function (tracks) {
for (var i = 0; i < tracks.length; i++) {
console.log(tracks[i].title);
}
});
你可以在这里试试我的小提琴:http://jsfiddle.net/tobiasbeuving/26pHX/5/
干杯, Ť