Created
January 27, 2014 19:48
-
-
Save aradnom/8655947 to your computer and use it in GitHub Desktop.
Chunk of JS from a larger project illustrating how to use the SoundCloud API to construct a basic player with playlist, seek and basic control functionality.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Initialize the Soundcloud API and set up player functionality | |
Soundcloud: { | |
// Start the API up | |
Init: function () { | |
SC.initialize({ | |
client_id: app.Config.soundcloudClient | |
}); | |
// For each audio player, bind soundcloud functionality | |
$('.audio-player').each( function () { | |
var player = $(this); | |
// Retrieve the soundcloud URL from the content | |
if ( $(this).find('.audio-url').length ) { | |
var url = $(this).find('.audio-url').text(); | |
// If the URL is valid, get the correct API resource | |
if ( url ) { | |
// Resolve the passed URL into an API-usable URL and play the resulting ID | |
app.Component.Soundcloud.Resolve( url, function ( track_info ) { | |
// If that went well, set up player (handled differently for sets/tracks) | |
// 'user' is also a potential type that could be played but isn't handled | |
// currently | |
if ( track_info ) { | |
if ( track_info.kind == 'playlist' ) { | |
// Build the playlist | |
var playlist = _.template( app.Templates.soundcloud_playlist, { | |
tracks: track_info.tracks | |
}); | |
// Append the playlist to the player | |
if ( playlist ) { | |
player.find('.playlist').append( playlist ); | |
// Refresh the layout because the height will have changed | |
app.Component.Stackery.Init(); | |
// Set up individual track controls | |
player.find('.playlist li').click( function () { | |
app.Component.Soundcloud.PlayTrack( $(this), player ); | |
}); | |
} | |
} else if ( track_info.kind == 'track' ) { | |
// Placeholder for single-track functionality (may need later) | |
} | |
// Bind generic audio controls | |
player.find('.progress-bar').click( function ( event ) { | |
var track = App.Config.currentTrack; | |
if ( track ) { | |
var offset = event.offsetX; | |
if ( offset ) { | |
var new_position = Math.floor( ( offset / $(this).width() ) * track.duration ); | |
if ( new_position && new_position <= track.duration ) { | |
track.setPosition( new_position ); | |
} | |
} | |
} | |
}); | |
player.find('.controls .play-pause').click( function () { | |
var track = App.Config.currentTrack; | |
// Usual play/oause functionality if there's a track loaded | |
if ( track ) { | |
$(this).toggleClass( 'play' ); | |
if ( $(this).hasClass( 'play' ) ) { | |
track.pause(); | |
} else { | |
track.play(); | |
} | |
// Otherwise load the first track if not | |
} else { | |
app.Component.Soundcloud.PlayTrack( player.find('.soundcloud-playlist li').first(), player ); | |
} | |
}); | |
player.find('.controls .previous').click( function () { | |
// Find and play previous track only if it exists | |
var playing = player.find('.playlist .playing'); | |
if ( playing.length && playing.prev('li').length ) { | |
var previous = playing.prev('li'); | |
// And away we go | |
app.Component.Soundcloud.PlayTrack( previous, player ); | |
} | |
}); | |
player.find('.controls .next').click( function () { | |
// Find and play next track only if it exists | |
var playing = player.find('.playlist .playing'); | |
if ( playing.length && playing.next('li').length ) { | |
var next = playing.next('li'); | |
// And away we go | |
app.Component.Soundcloud.PlayTrack( next, player ); | |
} | |
}); | |
player.find('.volume-bar').click( function ( event ) { | |
var track = App.Config.currentTrack; | |
if ( track ) { | |
var offset = event.offsetX; | |
if ( offset ) { | |
var new_position = Math.floor( ( offset / $(this).width() ) * 100 ); | |
if ( new_position ) { | |
// Gate the new value to valid values | |
if ( new_position < 0 ) new_position = 0; | |
if ( new_position > 100 ) new_position = 100; | |
track.setVolume( new_position ); | |
$(this).find('.inner').css( 'width', new_position.toString() + '%' ); | |
} | |
} | |
} | |
}); | |
player.find('.volume-icon').click( function () { | |
var track = App.Config.currentTrack; | |
if ( track ) { | |
$(this).toggleClass( 'muted' ); | |
if ( $(this).hasClass('muted') ) { | |
track.mute(); | |
} else { | |
track.unmute(); | |
} | |
} | |
}); | |
} | |
}); | |
} | |
} | |
}); | |
}, | |
// Retrieve track/user/set information for a specified soundcloud URL | |
Resolve: function ( url, callback ) { | |
$.getJSON( 'http://api.soundcloud.com/resolve.json?callback=?', { | |
url: url, | |
client_id: app.Config.soundcloudClient | |
}, function ( response ) { | |
if ( callback ) callback( response ); | |
}); | |
}, | |
// Play an audio track utilizing Soundcloud functions below | |
PlayTrack: function ( track_element, player ) { | |
var stream_url = track_element.find('.stream-url').text(); | |
if ( stream_url ) { | |
// Update the track duration | |
player.find('.total-time').text( app.__.MillisecondsToMinutes( track_element.find('.duration').text() ) ); | |
// Play the track and update progress while playing | |
app.Component.Soundcloud.StreamTrack( stream_url, function ( sound ) { | |
// Set volume to default level on load | |
sound.setVolume( 75 ); | |
// Update playing icon | |
player.find('.controls .play-pause').removeClass( 'play' ); | |
}, | |
// While playing, update progress | |
function ( sound ) { | |
// Progress bar | |
var progress = player.find('.progress-bar'), | |
inner = progress.children('.inner'), | |
position = Math.ceil( progress.width() * ( sound.position / sound.duration ) ); | |
inner.width( position ); | |
// Current play time | |
var current_time = player.find('.current-time'), | |
converted = app.__.MillisecondsToMinutes( sound.position ); | |
current_time.text( converted ); | |
}, | |
// On finish, jump to next track if it exists | |
function ( sound ) { | |
// Find and play next track only if it exists | |
var playing = player.find('.playlist .playing'); | |
if ( playing.length && playing.next('li').length ) { | |
var next = playing.next('li'); | |
// And away we go | |
app.Component.Soundcloud.PlayTrack( next, player ); | |
} | |
}); | |
// Update track's playing status | |
track_element.addClass( 'playing' ).siblings().removeClass( 'playing' ); | |
} | |
}, | |
// Play a single track over the Soundcloud API with the specified stream_url. | |
// Will provide the created SoundManager object in App.Config.CurrentTrack | |
StreamTrack: function ( stream_url, loaded, playing, finished ) { | |
if ( SC ) { | |
SC.stream( stream_url, function ( sound ) { | |
// If an existing track exists, null it out before switching | |
if ( app.Config.currentTrack ) app.Config.currentTrack.destruct(); | |
// Save a reference to the current track and play the track | |
app.Config.currentTrack = sound; | |
sound.play({ | |
whileplaying: function () { | |
if ( playing ) playing( this ); | |
}, | |
onload: function () { | |
if ( loaded ) loaded( this ); | |
}, | |
onfinish: function () { | |
if ( finished ) finished( this ); | |
} | |
}); | |
}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment