├── README ├── examples ├── example_basic.html ├── example_jquery.html └── example_prototype.html ├── soundcloud.player.api.js └── tests └── test_methods.html /README: -------------------------------------------------------------------------------- 1 | JavaScript based API for the SoundCloud player widget. 2 | Includes jQuery and Prototype.js support. 3 | 4 | soundcloud.addEventListener('onPlayerReady', function(player, data) { 5 | console.log('player ready'); 6 | }); 7 | 8 | 9 | The Documentation: 10 | http://wiki.github.com/soundcloud/Widget-JS-API 11 | 12 | 13 | Also check out the examples in the source. 14 | http://github.com/soundcloud/Widget-JS-API/tree/master/examples/ 15 | 16 | 17 | The project is published under MIT license: 18 | Copyright © 2009 SoundCloud Ltd. -------------------------------------------------------------------------------- /examples/example_basic.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | SC Player JS API 7 | 8 | 9 | 10 | 11 |

Player JavaScript API - simple listener implementation (JS Library agnostic)

12 | 13 | 24 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 |     
43 |       soundcloud.addEventListener('onPlayerReady', function(flashId, data) {
44 |         // please refer to the documentation for the full list of available methods
45 |         // btw, here the flash can be accessed too as 'this' like in 'this.api_play()'
46 |         soundcloud.getPlayer(flashId).api_play();
47 |       });
48 |     
49 |   
50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/example_jquery.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | SC Player JS API 7 | 8 | 9 | 10 | 11 | 12 | 13 | 37 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /examples/example_prototype.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | SC Player JS API 7 | 8 | 9 | 10 | 11 | 12 | 13 | 65 | 76 | 77 | 78 | 79 | 80 | 81 |

Track info

82 |
83 | 84 |
 85 |     
 86 |       // ------- an example of Prototype integration ----------
 87 |         $(document)
 88 |           .observe('soundcloud:onPlayerReady', function(event) {
 89 |             // the soundcloud.player.api.js wrapper triggers custom events
 90 |             // please refer to JS API wrapper for full the event list
 91 |             var flash = event.target,
 92 |                 playing;
 93 |             // insert a 'play' link
 94 |             $('controls').insert('<a href="#" id="play">Click to Play'</a>');
 95 |             var link= $('play');
 96 | 
 97 |             // toggle button
 98 |             var toggleLink = function(event) {
 99 |               playing = !playing;
100 |               if(playing){
101 |                 link.innerHTML = 'Click to Pause';
102 |               }else{
103 |                 link.innerHTML = 'Click to Play';
104 |               }
105 |             };
106 |             // listen to click on 'play' link
107 |             link.observe('click', function(event){
108 |               if(playing){
109 |                 flash.api_pause();
110 |               }else{
111 |                 flash.api_play();
112 |               }
113 |               Event.stop(event);
114 |             });
115 | 
116 |             // listen to events from the player, display infos and toggle the button state
117 |             $(document)
118 |             .observe('soundcloud:onMediaPlay', function(event) {
119 |               var mediaUri = event.memo.mediaUri,
120 |                   mediaId   = event.memo.mediaId;
121 |               $('info').innerHTML = mediaUri + ' is playing';
122 |               toggleLink();
123 |             })
124 |             .observe('soundcloud:onMediaPause', function(event) {
125 |               var mediaUri = event.memo.mediaUri,
126 |                   mediaId   = event.memo.mediaId,
127 |                   // please refer to JS API documention for the full list of player's public methods
128 |                   currentPosition = event.target.api_getTrackPosition();
129 |               $('info').innerHTML = mediaUri + ' was paused at ' + currentPosition + 's';
130 |               toggleLink();
131 |             });
132 |           });
133 |       
134 |     
135 |   
136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /soundcloud.player.api.js: -------------------------------------------------------------------------------- 1 | /* 2 | * JavaScript interface for the SoundCloud Player widget 3 | * Author: Matas Petrikas, matas@soundcloud.com 4 | * Copyright (c) 2009 SoundCloud Ltd. 5 | * Licensed under the MIT license: 6 | * http://www.opensource.org/licenses/mit-license.php 7 | */ 8 | (function(){ 9 | var isIE = (/msie (6|7|8)/i).test(navigator.userAgent) && !(/opera/i).test(navigator.userAgent); 10 | 11 | var soundcloud = window.soundcloud = { 12 | version: "0.1", 13 | debug: false, 14 | _listeners: [], 15 | // re-dispatches widget events in the DOM, using JS library support, the events also should bubble up the DOM 16 | _redispatch: function(eventType, flashId, data) { 17 | var playerNode, 18 | lsnrs = this._listeners[eventType] || [], 19 | // construct the custom eventType e.g. 'soundcloud:onPlayerReady' 20 | customEventType = 'soundcloud:' + eventType; 21 | 22 | try{ 23 | // find the flash player, might throw an exception 24 | playerNode = this.getPlayer(flashId); 25 | }catch(e){ 26 | if(this.debug && window.console){ 27 | console.error('unable to dispatch widget event ' + eventType + ' for the widget id ' + flashId, data, e); 28 | } 29 | return; 30 | } 31 | // re-dispatch SoundCloud events up in the DOM 32 | if(window.jQuery){ 33 | // if jQuery is available, trigger the custom event 34 | jQuery(playerNode).trigger(customEventType, [data]); 35 | }else if(window.Prototype){ 36 | // if Prototype.js is available, fire the custom event 37 | $(playerNode).fire(customEventType, data); 38 | }else{ 39 | // TODO add more JS libraries that support custom DOM events 40 | } 41 | // if there are any listeners registered to this event, trigger them all 42 | for(var i = 0, l = lsnrs.length; i < l; i += 1) { 43 | lsnrs[i].apply(playerNode, [playerNode, data]); 44 | } 45 | // log the events in debug mode 46 | if(this.debug && window.console){ 47 | console.log(customEventType, eventType, flashId, data); 48 | } 49 | 50 | }, 51 | // you can add multiple listeners to a certain event 52 | // e.g. soundcloud.addEventListener('onPlayerReady', myFunctionOne); 53 | // soundcloud.addEventListener('onPlayerReady', myFunctionTwo); 54 | addEventListener: function(eventType, callback) { 55 | if(!this._listeners[eventType]){ 56 | this._listeners[eventType] = []; 57 | } 58 | this._listeners[eventType].push(callback); 59 | }, 60 | // you can also remove the function listener if e.g you want to trigger it only once 61 | // soundcloud.removeEventListener('onMediaPlay', myFunctionOne); 62 | removeEventListener: function(eventType, callback) { 63 | var lsnrs = this._listeners[eventType] || []; 64 | for(var i = 0, l = lsnrs.length; i < l; i += 1) { 65 | if(lsnrs[i] === callback){ 66 | lsnrs.splice(i, 1); 67 | } 68 | } 69 | }, 70 | // get widget node based on its id (if object tag) or name (if embed tag) 71 | // if you're using SWFObject or other dynamic Flash generators, please make sure that you set the id parameter 72 | // only if the DOM has an id/name it's possible to call player's methods. 73 | // Important!: because of the bug in Opera browser, the Flash can't get its own id 74 | // so the generator should set it additionally through flashvars parameter 'object_id' 75 | getPlayer: function(id){ 76 | var flash; 77 | try{ 78 | if(!id){ 79 | throw "The SoundCloud Widget DOM object needs an id atribute, please refer to SoundCloud Widget API documentation."; 80 | } 81 | flash = isIE ? window[id] : document[id]; 82 | if(flash){ 83 | if(flash.api_getFlashId){ 84 | return flash; 85 | }else{ 86 | throw "The SoundCloud Widget External Interface is not accessible. Check that allowscriptaccess is set to 'always' in embed code"; 87 | } 88 | }else{ 89 | throw "The SoundCloud Widget with an id " + id + " couldn't be found"; 90 | } 91 | }catch(e){ 92 | if (console && console.error) { 93 | console.error(e); 94 | } 95 | throw e; 96 | } 97 | }, 98 | // fired when widget has loaded its data and is ready to accept calls from outside 99 | // the widget will call these functions only if in it's flashvars there's a parameter enable_api=true 100 | // @flashId: the widget id, basically the Flash node should be accessible to JS with soundcloud.getPlayer(flashId) 101 | // @data: an object containing .mediaUri (eg. 'http://api.soundcloud.com/tracks/49931') .mediaId (e.g. '4532') 102 | // in buffering events data contains also .percent = (e.g. '99') 103 | onPlayerReady: function(flashId, data) { 104 | this._redispatch('onPlayerReady', flashId, data); 105 | }, 106 | // fired when widget starts playing current track (fired only once per track) 107 | onMediaStart : function(flashId, data) { 108 | this._redispatch('onMediaStart', flashId, data); 109 | }, 110 | // fired when the track/playlist has finished playing 111 | onMediaEnd : function(flashId, data) { 112 | this._redispatch('onMediaEnd', flashId, data); 113 | }, 114 | // fired when widget starts playing current track (fired on every play, seek) 115 | onMediaPlay : function(flashId, data) { 116 | this._redispatch('onMediaPlay', flashId, data); 117 | }, 118 | // fired when track was paused 119 | onMediaPause : function(flashId, data) { 120 | this._redispatch('onMediaPause', flashId, data); 121 | }, 122 | // fired when the widget is still buffering, means you can't seek in the track fully yet 123 | onMediaBuffering : function(flashId, data) { 124 | this._redispatch('onMediaBuffering', flashId, data); 125 | }, 126 | // fired when the user seeks in the track 127 | onMediaSeek : function(flashId, data) { 128 | this._redispatch('onMediaSeek', flashId, data); 129 | }, 130 | // fired when the widget is done buffering and the whole track length is seekable 131 | onMediaDoneBuffering : function(flashId, data) { 132 | this._redispatch('onMediaDoneBuffering', flashId, data); 133 | }, 134 | // fired when the widget can't get the requested data from the server (the resource is removed, hidden, etc.) 135 | onPlayerError : function(flashId, data) { 136 | this._redispatch('onPlayerError', flashId, data); 137 | } 138 | }; 139 | 140 | })(); 141 | -------------------------------------------------------------------------------- /tests/test_methods.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | SC Player JS API 7 | 8 | 9 | 10 | 11 |

Player JavaScript API - test public methods

12 | 17 | 18 | 19 | 44 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
MethodStatus
63 | 64 | 65 | --------------------------------------------------------------------------------