123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818 |
- /*
- * SoundCloud Custom Player jQuery Plugin
- * Author: Matas Petrikas, matas@soundcloud.com
- * Copyright (c) 2009 SoundCloud Ltd.
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/mit-license.php
- *
- * Usage:
- * <a href="http://soundcloud.com/matas/hobnotropic" class="sc-player">My new dub track</a>
- * The link will be automatically replaced by the HTML based player
- */
- (function($) {
- // Convert milliseconds into Hours (h), Minutes (m), and Seconds (s)
- var timecode = function(ms) {
- var hms = function(ms) {
- return {
- h: Math.floor(ms/(60*60*1000)),
- m: Math.floor((ms/60000) % 60),
- s: Math.floor((ms/1000) % 60)
- };
- }(ms),
- tc = []; // Timecode array to be joined with '.'
- if (hms.h > 0) {
- tc.push(hms.h);
- }
- tc.push((hms.m < 10 && hms.h > 0 ? "0" + hms.m : hms.m));
- tc.push((hms.s < 10 ? "0" + hms.s : hms.s));
- return tc.join(':');
- };
- // shuffle the array
- var shuffle = function(arr) {
- arr.sort(function() { return 1 - Math.floor(Math.random() * 3); } );
- return arr;
- };
- var debug = true,
- useSandBox = false,
- $doc = $(document),
- log = function(args) {
- try {
- if(debug && window.console && window.console.log){
- window.console.log.apply(window.console, arguments);
- }
- } catch (e) {
- // no console available
- }
- },
- domain = useSandBox ? 'sandbox-soundcloud.com' : 'soundcloud.com',
- secureDocument = (document.location.protocol === 'https:'),
- // convert a SoundCloud resource URL to an API URL
- scApiUrl = function(url, apiKey) {
- // var resolver = ( secureDocument || (/^https/i).test(url) ? 'https' : 'http') + '://api.' + domain + '/resolve?url=',
- // params = 'format=json&consumer_key=' + apiKey +'&callback=?';
- var resolver = ( secureDocument || (/^https/i).test(url) ? 'https' : 'http') + '://api.' + domain + '/resolve?url=',
- params = 'format=json&callback=?';
- // debugger;
- // force the secure url in the secure environment
- if( secureDocument ) {
- url = url.replace(/^http:/, 'https:');
- }
- // check if it's already a resolved api url
- if ( (/api\./).test(url) ) {
- return url + '?' + params;
- } else {
- return resolver + url + '&' + params;
- }
- };
- // TODO Expose the audio engine, so it can be unit-tested
- var audioEngine = function() {
- var html5AudioAvailable = function() {
- var state = false;
- try{
- var a = new Audio();
- state = a.canPlayType && (/maybe|probably/).test(a.canPlayType('audio/mpeg'));
- // uncomment the following line, if you want to enable the html5 audio only on mobile devices
- // state = state && (/iPad|iphone|mobile|pre\//i).test(navigator.userAgent);
- }catch(e){
- // there's no audio support here sadly
- }
- return state;
- }(),
- callbacks = {
- onReady: function() {
- $doc.trigger('paScPlayer:onAudioReady');
- },
- onPlay: function() {
- $doc.trigger('paScPlayer:onMediaPlay');
- },
- onPause: function() {
- $doc.trigger('paScPlayer:onMediaPause');
- },
- onEnd: function() {
- $doc.trigger('paScPlayer:onMediaEnd');
- },
- onBuffer: function(percent) {
- $doc.trigger({type: 'paScPlayer:onMediaBuffering', percent: percent});
- }
- };
- var html5Driver = function() {
- var player = new Audio(),
- onTimeUpdate = function(event){
- var obj = event.target,
- buffer = ((obj.buffered.length && obj.buffered.end(0)) / obj.duration) * 100;
- // ipad has no progress events implemented yet
- callbacks.onBuffer(buffer);
- // anounce if it's finished for the clients without 'ended' events implementation
- if (obj.currentTime === obj.duration) { callbacks.onEnd(); }
- },
- onProgress = function(event) {
- var obj = event.target,
- buffer = ((obj.buffered.length && obj.buffered.end(0)) / obj.duration) * 100;
- callbacks.onBuffer(buffer);
- };
- $('<div class="pa-sc-player-engine-container"></div>').appendTo(document.body).append(player);
- // prepare the listeners
- player.addEventListener('play', callbacks.onPlay, false);
- player.addEventListener('pause', callbacks.onPause, false);
- // handled in the onTimeUpdate for now untill all the browsers support 'ended' event
- // player.addEventListener('ended', callbacks.onEnd, false);
- player.addEventListener('timeupdate', onTimeUpdate, false);
- player.addEventListener('progress', onProgress, false);
- return {
- load: function(track, apiKey) {
- player.pause();
- player.src = track.stream_url + (/\?/.test(track.stream_url) ? '&' : '?') + 'consumer_key=' + apiKey;
- player.load();
- player.play();
- },
- play: function() {
- player.play();
- },
- pause: function() {
- player.pause();
- },
- stop: function(){
- if (player.currentTime) {
- player.currentTime = 0;
- player.pause();
- }
- },
- seek: function(relative){
- player.currentTime = player.duration * relative;
- player.play();
- },
- getDuration: function() {
- return player.duration * 1000;
- },
- getPosition: function() {
- return player.currentTime * 1000;
- },
- setVolume: function(val) {
- player.volume = val / 100;
- }
- };
- };
- var flashDriver = function() {
- var engineId = 'paScPlayerEngine',
- player,
- flashHtml = function(url) {
- var swf = (secureDocument ? 'https' : 'http') + '://player.' + domain +'/player.swf?url=' + url +'&enable_api=true&player_type=engine&object_id=' + engineId;
- if ($.browser.msie) {
- return '<object height="100%" width="100%" id="' + engineId + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" data="' + swf + '">'+
- '<param name="movie" value="' + swf + '" />'+
- '<param name="allowscriptaccess" value="always" />'+
- '</object>';
- } else {
- return '<object height="100%" width="100%" id="' + engineId + '">'+
- '<embed allowscriptaccess="always" height="100%" width="100%" src="' + swf + '" type="application/x-shockwave-flash" name="' + engineId + '" />'+
- '</object>';
- }
- };
- // listen to audio engine events
- // when the loaded track is ready to play
- soundcloud.addEventListener('onPlayerReady', function(flashId, data) {
- player = soundcloud.getPlayer(engineId);
- callbacks.onReady();
- });
- // when the loaded track finished playing
- soundcloud.addEventListener('onMediaEnd', callbacks.onEnd);
- // when the loaded track is still buffering
- soundcloud.addEventListener('onMediaBuffering', function(flashId, data) {
- callbacks.onBuffer(data.percent);
- });
- // when the loaded track started to play
- soundcloud.addEventListener('onMediaPlay', callbacks.onPlay);
- // when the loaded track is was paused
- soundcloud.addEventListener('onMediaPause', callbacks.onPause);
- return {
- load: function(track) {
- var url = track.uri;
- if(player){
- player.api_load(url);
- }else{
- // create a container for the flash engine (IE needs this to operate properly)
- $('<div class="pa-sc-player-engine-container"></div>').appendTo(document.body).html(flashHtml(url));
- }
- },
- play: function() {
- player && player.api_play();
- },
- pause: function() {
- player && player.api_pause();
- },
- stop: function(){
- player && player.api_stop();
- },
- seek: function(relative){
- player && player.api_seekTo((player.api_getTrackDuration() * relative));
- },
- getDuration: function() {
- return player && player.api_getTrackDuration && player.api_getTrackDuration() * 1000;
- },
- getPosition: function() {
- return player && player.api_getTrackPosition && player.api_getTrackPosition() * 1000;
- },
- setVolume: function(val) {
- if(player && player.api_setVolume){
- player.api_setVolume(val);
- }
- }
- };
- };
- return html5AudioAvailable? html5Driver() : flashDriver();
- }();
- var apiKey,
- didAutoPlay = false,
- players = [],
- updates = {},
- currentUrl,
- loadTracksData = function($player, links, key) {
- var index = 0,
- playerObj = {node: $player, tracks: []},
- loadUrl = function(link) {
- var apiUrl = scApiUrl(link.url, apiKey);
- // $.getJSON(apiUrl, function(data) {
- // // log('data loaded', link.url, data);
- // index += 1;
- // // added by Bach for MJ
- // data.href = link.href;
- // if(data.tracks){
- // // log('data.tracks', data.tracks);
- // playerObj.tracks = playerObj.tracks.concat(data.tracks);
- // }else if(data.duration){
- // // a secret link fix, till the SC API returns permalink with secret on secret response
- // data.permalink_url = link.url;
- // // if track, add to player
- // playerObj.tracks.push(data);
- // }else if(data.creator){
- // // it's a group!
- // links.push({url:data.uri + '/tracks'});
- // }else if(data.username){
- // // if user, get his tracks or favorites
- // if(/favorites/.test(link.url)){
- // links.push({url:data.uri + '/favorites'});
- // }else{
- // links.push({url:data.uri + '/tracks'});
- // }
- // }else if($.isArray(data)){
- // playerObj.tracks = playerObj.tracks.concat(data);
- // }
- // if(links[index]){
- // // if there are more track to load, get them from the api
- // loadUrl(links[index]);
- // }else{
- // // if loading finishes, anounce it to the GUI
- // playerObj.node.trigger({type:'onTrackDataLoaded', playerObj: playerObj, url: apiUrl});
- // }
- // });
- // https://developers.soundcloud.com/docs/api/guide#authentication
- // # obtain the access token
- // $ curl -X POST "https://api.soundcloud.com/oauth2/token" \
- // -H "accept: application/json; charset=utf-8" \
- // -H "Content-Type: application/x-www-form-urlencoded" \
- // --data-urlencode "grant_type=client_credentials" \
- // --data-urlencode "client_id=YOUR_CLIENT_ID" \
- // --data-urlencode "client_secret=YOUR_CLIENT_SECRET"
- $.ajax({
- method: 'POST',
- url: 'https://api.soundcloud.com/oauth2/token',
- data: {
- 'grant_type' : "client_credentials",
- 'client_id' : "965bd4363fdd909723749b003be67125",
- 'client_secret': "bb68647335a47f104a86dcddf4e70fa8"
- },
- headers: {
- "accept" : "application/json; charset=utf-8",
- "Content-Type" : "application/x-www-form-urlencoded"
- }
- }).done(function (data) {
- console.log('Token', data);
- });
- // $.ajax({
- // "dataType": "json",
- // "url": apiUrl,
- // "data": {},
- // "headers": {
- // "Authorization": "OAuth bb68647335a47f104a86dcddf4e70fa8"
- // },
- // "success": function(data) {
- // // log('data loaded', link.url, data);
- // index += 1;
- // // added by Bach for MJ
- // data.href = link.href;
- // if(data.tracks){
- // // log('data.tracks', data.tracks);
- // playerObj.tracks = playerObj.tracks.concat(data.tracks);
- // }else if(data.duration){
- // // a secret link fix, till the SC API returns permalink with secret on secret response
- // data.permalink_url = link.url;
- // // if track, add to player
- // playerObj.tracks.push(data);
- // }else if(data.creator){
- // // it's a group!
- // links.push({url:data.uri + '/tracks'});
- // }else if(data.username){
- // // if user, get his tracks or favorites
- // if(/favorites/.test(link.url)){
- // links.push({url:data.uri + '/favorites'});
- // }else{
- // links.push({url:data.uri + '/tracks'});
- // }
- // }else if($.isArray(data)){
- // playerObj.tracks = playerObj.tracks.concat(data);
- // }
- // if(links[index]){
- // // if there are more track to load, get them from the api
- // loadUrl(links[index]);
- // }else{
- // // if loading finishes, anounce it to the GUI
- // playerObj.node.trigger({type:'onTrackDataLoaded', playerObj: playerObj, url: apiUrl});
- // }
- // },
- // "error": function(errorThrown) {
- // console.error(JSON.stringify(errorThrown.error()));
- // }
- // });
-
- };
- // update current API key
- apiKey = key;
- // update the players queue
- players.push(playerObj);
- // load first tracks
- loadUrl(links[index]);
- },
- artworkImage = function(track, usePlaceholder) {
- if(usePlaceholder){
- return '<div class="sc-loading-artwork">Loading Artwork</div>';
- }else if (track.artwork_url) {
- return '<img src="' + track.artwork_url.replace('-large', '-t300x300') + '"/>';
- }else{
- return '<div class="sc-no-artwork">No Artwork</div>';
- }
- },
- updateTrackInfo = function($player, track) {
- // update the current track info in the player
- // log('updateTrackInfo', track);
- // $('.sc-info', $player).each(function(index) {
- // $('h3', this).html('<a href="' + track.permalink_url +'">' + track.title + '</a>');
- // $('h4', this).html('by <a href="' + track.user.permalink_url +'">' + track.user.username + '</a>');
- // $('p', this).html(track.description || 'no Description');
- // });
- // update the artwork
- // $('.sc-artwork-list li', $player).each(function(index) {
- // var $item = $(this),
- // itemTrack = $item.data('sc-track');
- //
- // if (itemTrack === track) {
- // // show track artwork
- // $item
- // .addClass('active')
- // .find('.sc-loading-artwork')
- // .each(function(index) {
- // // if the image isn't loaded yet, do it now
- // $(this).removeClass('sc-loading-artwork').html(artworkImage(track, false));
- // });
- // }else{
- // // reset other artworks
- // $item.removeClass('active');
- // }
- // });
- // update the track duration in the progress bar
- $('.sc-duration', $player).html(timecode(track.duration));
- // put the waveform into the progress bar
- $('.sc-waveform-container', $player).html('<img src="' + track.waveform_url +'" />');
- $player.trigger('onPlayerTrackSwitch.paScPlayer', [track]);
- },
- play = function(track) {
- var url = track.permalink_url;
- if(currentUrl === url){
- // log('will play');
- audioEngine.play();
- }else{
- currentUrl = url;
- // log('will load', url);
- audioEngine.load(track, apiKey);
- }
- },
- getPlayerData = function(node) {
- return players[$(node).data('pa-sc-player').id];
- },
- updatePlayStatus = function(player, status) {
- if(status){
- // reset all other players playing status
- $('div.pa-sc-player.playing').removeClass('playing');
- }
- $(player)
- .toggleClass('playing', status)
- .trigger((status ? 'onPlayerPlay' : 'onPlayerPause'));
- },
- onPlay = function(player, id) {
- var track = getPlayerData(player).tracks[id || 0];
- updateTrackInfo(player, track);
- // cache the references to most updated DOM nodes in the progress bar
- updates = {
- $buffer: $('.sc-buffer', player),
- $played: $('.sc-played', player),
- position: $('.sc-position', player)[0]
- };
- updatePlayStatus(player, true);
- play(track);
- },
- onPause = function(player) {
- updatePlayStatus(player, false);
- audioEngine.pause();
- },
- onFinish = function() {
- var $player = updates.$played.closest('.pa-sc-player'),
- $nextItem;
- // update the scrubber width
- updates.$played.css('width', '0%');
- // show the position in the track position counter
- updates.position.innerHTML = timecode(0);
- // reset the player state
- updatePlayStatus($player, false);
- // stop the audio
- audioEngine.stop();
- $player.trigger('onPlayerTrackFinish');
- },
- onSeek = function(player, relative) {
- audioEngine.seek(relative);
- $(player).trigger('onPlayerSeek');
- },
- onSkip = function(player) {
- var $player = $(player);
- // continue playing through all players
- log('track finished get the next one');
- $nextItem = $('.sc-trackslist li.active', $player).next('li');
- // try to find the next track in other player
- if(!$nextItem.length){
- $nextItem = $player.nextAll('div.pa-sc-player:first').find('.sc-trackslist li.active');
- }
- $nextItem.click();
- },
- soundVolume = function() {
- var vol = 80,
- cooks = document.cookie.split(';'),
- volRx = new RegExp('paScPlayer_volume=(\\d+)');
- for(var i in cooks){
- if(volRx.test(cooks[i])){
- vol = parseInt(cooks[i].match(volRx)[1], 10);
- break;
- }
- }
- return vol;
- }(),
- onVolume = function(volume) {
- var vol = Math.floor(volume);
- // save the volume in the cookie
- var date = new Date();
- date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000));
- soundVolume = vol;
- document.cookie = ['paScPlayer_volume=', vol, '; expires=', date.toUTCString(), '; path="/"'].join('');
- // update the volume in the engine
- audioEngine.setVolume(soundVolume);
- },
- positionPoll;
- // listen to audio engine events
- $doc
- .bind('paScPlayer:onAudioReady', function(event) {
- log('onPlayerReady: audio engine is ready');
- audioEngine.play();
- // set initial volume
- onVolume(soundVolume);
- })
- // when the loaded track started to play
- .bind('paScPlayer:onMediaPlay', function(event) {
- clearInterval(positionPoll);
- positionPoll = setInterval(function() {
- var duration = audioEngine.getDuration(),
- position = audioEngine.getPosition(),
- relative = (position / duration);
- // update the scrubber width
- updates.$played.css('width', (100 * relative) + '%');
- // show the position in the track position counter
- updates.position.innerHTML = timecode(position);
- // announce the track position to the DOM
- $doc.trigger({
- type: 'onMediaTimeUpdate.paScPlayer',
- duration: duration,
- position: position,
- relative: relative
- });
- }, 500);
- })
- // when the loaded track is was paused
- .bind('paScPlayer:onMediaPause', function(event) {
- clearInterval(positionPoll);
- positionPoll = null;
- })
- // change the volume
- // .bind('paScPlayer:onVolumeChange', function(event) {
- // onVolume(event.volume);
- // })
- .bind('paScPlayer:onMediaEnd', function(event) {
- onFinish();
- })
- .bind('paScPlayer:onMediaBuffering', function(event) {
- updates.$buffer.css('width', event.percent + '%');
- });
- // Generate custom skinnable HTML/CSS/JavaScript based SoundCloud players from links to SoundCloud resources
- $.paScPlayer = function(options, node) {
- var opts = $.extend({}, $.paScPlayer.defaults, options),
- playerId = players.length,
- $source = node && $(node),
- sourceClasses = $source[0].className.replace('pa-sc-player', ''),
- links =
- opts.links
- || $.map($('a', $source)
- .add($source.filter('a')), function(val) {
- //log('val', val);
- return {href: val.href, url: $(val).attr('scurl') || val.href, title: val.innerHTML};
- // return {url: val.href, title: val.innerHTML};
- }),
- $player = $('<div class="pa-sc-player loading"></div>').data('pa-sc-player', {id: playerId}),
- // $artworks = $('<ol class="sc-artwork-list"></ol>').appendTo($player),
- // $info = $('<div class="sc-info"><h3></h3><h4></h4><p></p><a href="#" class="sc-info-close">X</a></div>').appendTo($player),
- $list = $('<ul class="sc-trackslist"></ul>').appendTo($player),
- $controls = $('<div class="sc-controls"></div>').appendTo($player);
- // add the classes of the source node to the player itself
- // the players can be indvidually styled this way
- if(sourceClasses || opts.customClass){
- $player.addClass(sourceClasses).addClass(opts.customClass);
- }
- log('$source', $source);
- log('links', links);
- // adding controls to the player
- $player
- .find('.sc-controls')
- .append('<a href="#play" class="sc-play"><span>play</span></a> <a href="#pause" class="sc-pause"><span>pause</span></a>')
- .end()
- // .append('<a href="#info" class="sc-info-toggle">Info</a>')
- // .append('<div class="sc-scrubber"></div>')
- // .find('.sc-scrubber')
- // .append('<div class="sc-volume-slider"><span class="sc-volume-status" style="width:' + soundVolume +'%"></span></div>')
- .append('<div class="sc-time-indicators"><span class="sc-position">00.00</span> | <span class="sc-duration"></span></div>')
- .append('<div class="sc-time-span"><div class="sc-buffer"></div><div class="sc-played"></div></div>'); // <div class="sc-waveform-container"></div>
- // load and parse the track data from SoundCloud API
- loadTracksData($player, links, opts.apiKey);
- // init the player GUI, when the tracks data was laoded
- $player.bind('onTrackDataLoaded.paScPlayer', function(event) {
- log('onTrackDataLoaded.paScPlayer', event, playerId);
- // var tracks = event.playerObj.tracks;
- // if (opts.randomize) {
- // tracks = shuffle(tracks);
- // }
- // create the playlist
- $.each(event.playerObj.tracks, function(index, track) {
- log('track', track);
- var active = index === 0;
- // create an item in the playlist
- $('<li>')
- .append($('<a>').attr('href', track.href).html(links[index].title))
- .data('sc-track', {id:index})
- .toggleClass('active', active)
- .appendTo($list);
- // create an item in the artwork list
- // $('<li></li>')
- // .append(artworkImage(track, index >= opts.loadArtworks))
- // .appendTo($artworks)
- // .toggleClass('active', active)
- // .data('sc-track', track);
- });
- // update the element before rendering it in the DOM
- $player.each(function() {
- if($.isFunction(opts.beforeRender)){
- opts.beforeRender.call(this, event.playerObj.tracks);
- }
- });
- // set the first track's duration
- $('.sc-duration', $player)[0].innerHTML = timecode(event.playerObj.tracks[0].duration);
- $('.sc-position', $player)[0].innerHTML = timecode(0);
- // set up the first track info
- updateTrackInfo($player, event.playerObj.tracks[0]);
- // if continous play enabled always skip to the next track after one finishes
- if (opts.continuePlayback) {
- $player.bind('onPlayerTrackFinish', function(event) {
- onSkip($player);
- });
- }
- // announce the succesful initialization
- $player
- .removeClass('loading')
- .trigger('onPlayerInit');
- // if auto play is enabled and it's the first player, start playing
- if(opts.autoPlay && !didAutoPlay){
- onPlay($player);
- didAutoPlay = true;
- }
- });
- // replace the DOM source (if there's one)
- $source.each(function(index) {
- $(this).replaceWith($player);
- });
- return $player;
- };
- // stop all players, might be useful, before replacing the player dynamically
- $.paScPlayer.stopAll = function() {
- $('.pa-sc-player.playing a.sc-pause').click();
- };
- // destroy all the players and audio engine, usefull when reloading part of the page and audio has to stop
- $.paScPlayer.destroy = function() {
- $('.pa-sc-player, .pa-sc-player-engine-container').remove();
- };
- // plugin wrapper
- $.fn.paScPlayer = function(options) {
- // reset the auto play
- didAutoPlay = false;
- // create the players
- this.each(function() {
- $.paScPlayer(options, this);
- });
- return this;
- };
- // default plugin options
- $.paScPlayer.defaults = $.fn.paScPlayer.defaults = {
- customClass: null,
- // do something with the dom object before you render it, add nodes, get more data from the services etc.
- beforeRender : function(tracksData) {
- var $player = $(this);
- },
- // initialization, when dom is ready
- onDomReady : function() {
- $('a.pa-sc-player, div.pa-sc-player').paScPlayer();
- },
- autoPlay: false,
- continuePlayback: true,
- randomize: false,
- loadArtworks: 5,
- // the default Api key should be replaced by your own one
- // get it here http://soundcloud.com/you/apps/new
- apiKey: '965bd4363fdd909723749b003be67125'
- };
- // the GUI event bindings
- //--------------------------------------------------------
- // toggling play/pause
- $('a.sc-play, a.sc-pause').live('click', function(event) {
- var $list = $(this).closest('.pa-sc-player').find('ul.sc-trackslist');
- // simulate the click in the tracklist
- $list.find('li.active').click();
- return false;
- });
- // displaying the info panel in the player
- // $('a.sc-info-toggle, a.sc-info-close').live('click', function(event) {
- // var $link = $(this);
- // $link.closest('.pa-sc-player')
- // .find('.sc-info').toggleClass('active').end()
- // .find('a.sc-info-toggle').toggleClass('active');
- // return false;
- // });
- // selecting tracks in the playlist
- $('.sc-trackslist li').live('click', function(event) {
- var $track = $(this),
- $player = $track.closest('.pa-sc-player'),
- trackId = $track.data('sc-track').id,
- play = $player.is(':not(.playing)') || $track.is(':not(.active)');
- if (play) {
- onPlay($player, trackId);
- }else{
- onPause($player);
- }
- $track.addClass('active').siblings('li').removeClass('active');
- // $('.artworks li', $player).each(function(index) {
- // $(this).toggleClass('active', index === trackId);
- // });
- return false;
- });
- var scrub = function(node, xPos) {
- var $scrubber = $(node).closest('.sc-time-span'),
- $buffer = $scrubber.find('.sc-buffer'),
- // $available = $scrubber.find('.sc-waveform-container img'),
- $player = $scrubber.closest('.pa-sc-player'),
- relative = Math.min($buffer.width(), (xPos - $scrubber.offset().left)) / $scrubber.width();
- onSeek($player, relative);
- };
- var onTouchMove = function(ev) {
- if (ev.targetTouches.length === 1) {
- scrub(ev.target, ev.targetTouches && ev.targetTouches.length && ev.targetTouches[0].clientX);
- ev.preventDefault();
- }
- };
- // seeking in the loaded track buffer
- $('.sc-time-span')
- .live('click', function(event) {
- scrub(this, event.pageX);
- return false;
- })
- .live('touchstart', function(event) {
- this.addEventListener('touchmove', onTouchMove, false);
- event.originalEvent.preventDefault();
- })
- .live('touchend', function(event) {
- this.removeEventListener('touchmove', onTouchMove, false);
- event.originalEvent.preventDefault();
- });
- // changing volume in the player
- // var startVolumeTracking = function(node, startEvent) {
- // var $node = $(node),
- // originX = $node.offset().left,
- // originWidth = $node.width(),
- // getVolume = function(x) {
- // return Math.floor(((x - originX)/originWidth)*100);
- // },
- // update = function(event) {
- // $doc.trigger({type: 'paScPlayer:onVolumeChange', volume: getVolume(event.pageX)});
- // };
- // $node.bind('mousemove.pa-sc-player', update);
- // update(startEvent);
- // };
- // var stopVolumeTracking = function(node, event) {
- // $(node).unbind('mousemove.pa-sc-player');
- // };
- // $('.sc-volume-slider')
- // .live('mousedown', function(event) {
- // startVolumeTracking(this, event);
- // })
- // .live('mouseup', function(event) {
- // stopVolumeTracking(this, event);
- // });
- // $doc.bind('paScPlayer:onVolumeChange', function(event) {
- // $('span.sc-volume-status').css({width: event.volume + '%'});
- // });
- // -------------------------------------------------------------------
- // the default Auto-Initialization
- $(function() {
- if($.isFunction($.paScPlayer.defaults.onDomReady)){
- $.paScPlayer.defaults.onDomReady();
- }
- });
- })(jQuery);
|