]> git.0d.be Git - panikweb.git/blob - panikweb_templates/static/js/audioPlayer.js
assorted changes to make it work in older browsers
[panikweb.git] / panikweb_templates / static / js / audioPlayer.js
1 (function($) {
2         var thePlaylist;
3         $.widget( "panik.playlist", {
4                 /*
5                         sound = {
6                                 source :{
7                                         ogg:"oggURL",
8                                         mp3:"mp3URL"
9                                 },
10                                 emission: "episode.slug",
11                                 episode: "episode.slug",
12                                 id:""
13                         }
14                 */
15                 options: {
16                         playlist: [],
17                         html5audioOptions:{controls:true,preload:"none"},
18                         classes: "",
19                         itemClasses: "",
20                         controlContainer: $('<div>'),
21                         playlistContainer: $('<ol>'),
22                         onLoad: function(){},
23                         onAdd: function(){},
24                         onPlay: function(){},
25                         onUpdate: function(){},
26                 },
27                 _create: function() {
28                 // Initialization logic here
29                         thePlaylist = this;     
30                         this.isActive = false;
31                         this.isLastAdd = false;
32                         this.controlButtons = []
33                         this.debugContainer = $('<pre>').hide();
34                         this.controlContainer = this.options.controlContainer;
35                         this.playlistContainer = this.options.playlistContainer;
36                         this.element.addClass(this.options.classes);    
37                         this.element.append(this.controlContainer);     
38                         this.element.append(this.playlistContainer);
39                         this.element.append(this.debugContainer);
40                         this.playlist = this.options.playlist;
41                         this.buildPlaylistControls();
42                         this.loadPlaylist();
43                         this._update();
44                         this.options.onLoad(this);
45                 },
46
47                 _setOption: function( key, value ) {
48                         this.options[ key ] = value;
49                         this._update();
50                 },
51                 _update: function() {   
52                         this.playlist = [];     
53                         this.playlistContainer.find('audio').each(function(){
54                                 thePlaylist.playlist.push(thePlaylist.jsonifyAudio($(this)));
55                         });
56                         this.debugContainer.text(
57                                 JSON.stringify(this.playlist, null, '\t')
58                         );
59                         this.savePlaylist();
60                         this.options.onUpdate(this);
61                         return this.playlist;
62                 },
63                 _reset: function() {    
64                         this.isActive =false;
65                         this.stopSounds();
66                         this.playlistContainer.find('*').remove();
67                         this._update();
68                 },
69                 savePlaylist: function(){
70                         var JSONPlaylist = JSON.stringify(this.playlist, null, '\t');
71                         if (localStorage !== null && localStorage !== undefined) {
72                                 localStorage['playlist'] = JSON.stringify(this.playlist, null, '\t');
73                         }
74                 },
75                 loadPlaylist: function(){
76                         if (localStorage !== null && localStorage !== undefined) {
77                                 this.playlist = localStorage['playlist']?JSON.parse(localStorage['playlist']):this.playlist;
78                         }
79                         $.each(this.playlist,function(k,v){
80                                 thePlaylist.playlistContainer.append(thePlaylist._htmlifyJsonSound(v));
81                         });
82                         return this.playlist;
83                 },
84                 // Transform HTML5 <audio> to simple JSON object.
85                 jsonifyAudio: function(audio) {
86                         var sound = {
87                                 source :{},
88                                 title: audio.attr('title'),
89                                 id:audio.attr('id'),
90                                 url:audio.attr('data-url'),
91                                 focus:audio.attr('data-player-focus')
92                         };
93                         audio.children('source').each(function(){
94                                 sound.source[$(this).attr('type')] = $(this).attr('src');
95                         });
96                         return sound;
97                 },
98                 // Play next sound
99                 setFocus: function(element) {
100                         this.isActive = element;
101                         this.playlistContainer.find('li').each(function(){
102                                 $(this).removeClass('active');
103                                 $(this).find('audio').removeAttr('data-player-focus');
104                         });
105                         this.isActive.addClass('active').find('audio').attr('data-player-focus',true);
106                         this._update();
107                 },
108                 // Transform JSON sound object to HTML container for playlist.
109                 _htmlifyJsonSound: function(sound) {
110                         var container = $('<li>').attr('data-origin',sound.id);
111                         var audio = $('<audio>',this.options.html5audioOptions)
112                                 .attr('title',sound.title).hide()
113                                 .attr('data-url',sound.url);
114                         $.each(sound.source,function(k,v){
115                                 var source = $('<source>',{src:v,type:k});
116                                 audio.append(source);
117                         });
118                         audio.on('play',function(){
119                                 thePlaylist.setFocus(container);
120                                 container.addClass('playing');
121                                 playpause.addClass('icon-pause').removeClass('icon-play');
122                                 thePlaylist.controlButtons['playpause'].removeClass('icon-play').addClass('icon-pause');
123                                 thePlaylist.afterPlay();
124                         }).on('pause',function(){
125                                 $(this).removeClass('playing');
126                                 playpause.addClass('icon-play').removeClass('icon-pause');
127                                 thePlaylist.controlButtons['playpause'].removeClass('icon-pause').addClass('icon-play');
128                         }).on('stop',function(){
129                                 $(this).trigger('pause');
130                                 if($(this)[0].currentTime){$(this)[0].currentTime = 0;}
131                         }).on("ended", function(){
132                                 thePlaylist.playNext();
133                         }).on('beforePause',function(){
134                                 return this;
135                         }).on('beforePlay',function(){
136                                 thePlaylist.pauseSounds();
137                                 return this;
138                         });
139                         var controls = $('<span>',{'class':'soundControls controls'});
140                         var link = $('<a>',{href:sound.url,'class':'button icon-external-link'});
141                         var html5 = $('<button>',{title:"Display HTML5 audio",'class':'icon-html5',click:function(){
142                                 audio.toggle();
143                         }}).hide();
144                         var remove = $('<button>',{title:"Remove from list",'class':'icon-remove',click:function(){
145                                 container.remove();
146                                 thePlaylist._update();
147                         }});
148                         var stop = $('<button>',{title:"Stop",'class':'icon-stop',click:function(){
149                                 audio.trigger('stop');
150                         }}).hide();
151                         var playpause = $('<button>',{title:"Play/Pause",'class':'icon-play',click:function(){
152                                 
153                                   if (audio[0].paused == false) { audio.trigger('pause');
154                                   } else {
155                                         audio.trigger('beforePlay').trigger('play');
156                                 }
157                         }});
158                         controls.append(playpause).append(stop).append(remove).append(html5);
159                         var title = $('<a>',{title:"More information",href:sound.url,'class':"button title",html:sound.title});
160                         container.append(controls).append(title).append(audio);
161                         if(sound.focus){thePlaylist.setFocus(container);}
162                         return container;
163                 },
164                 // Create a public method.
165                 registerAudio: function(audio,success) {
166                         var audioObj = this.jsonifyAudio(audio);
167                         var htmlAudio = this._htmlifyJsonSound(audioObj);
168                         this.playlistContainer.append(htmlAudio);
169                         this.isLastAdd = htmlAudio;
170                         if(!this.isActive){this.setFocus(this.isLastAdd);}
171                         this.options.onAdd(this);
172                         if(success){success();}
173                         this._update();
174                 },
175                 // Play next sound
176                 bindControl: function(control,audio,element,options) {
177                         element.addClass('loading');
178                         audioID = audio.attr('id');                     
179                         //TODO for controls in page content
180                 },
181                 // Play next sound
182                 registerControl: function(name,options) {
183                         this.controlButtons[name] = $('<button>',options);
184                         this.controlContainer.append(this.controlButtons[name]);
185                 },
186                 // Build controls
187                 buildPlaylistControls: function() {
188                         this.controlContainer.empty();
189                         /*
190                         this.registerControl('toggleList',{class:"icon-list",click:     function(){ 
191                                 thePlaylist.playlistContainer.toggle();
192                         }});
193                         this.registerControl('clearList',{class:"icon-trash",click:     function(){ 
194                                 thePlaylist.playlistContainer.empty();
195                                 thePlaylist._update();
196                         }});
197                         */
198                         this.registerControl('previous',{'class':"icon-step-backward",click:function(){
199                                 thePlaylist.playPrevious();
200                         }});
201                         this.registerControl('stop',{'class':"icon-stop",click: function(){ 
202                                 thePlaylist.stopSounds();
203                         }});
204                         this.registerControl('playpause',{'class':"icon-play playPause",click:  function(){
205                                 thePlaylist.playPauseList();
206                         }});
207                         this.registerControl('next',{'class':"icon-step-forward",click: function(){ 
208                                 thePlaylist.playNext();
209                         }});
210                         return true;
211                 },
212                 // Play next sound
213                 afterPlay: function() {
214                         this.options.onPlay(this);
215                 },
216                 // Play next sound
217                 beforePlay: function() {
218                         this.stopSounds();
219                 },
220                 // Play next sound
221                 getActive: function() {
222                         if(!this.isActive){
223                                 this.isActive = this.playlistContainer.children('li').first();                          
224                         }
225                         return this.isActive;
226                 },
227                 // Play next sound
228                 playPauseList: function() {
229                         if(this.controlButtons['playpause'].hasClass('icon-play')){
230                                 this.getActive().find('audio').trigger('beforePlay').trigger('play');
231                         }else{
232                                 this.getActive().find('audio').trigger('pause');        
233                         }
234                         return true;
235                 },
236                 // Play next sound
237                 playPrevious: function() {
238                         this.getActive().prev().find('audio').trigger('beforePlay').trigger('play');
239                         return true;
240                 },
241                 // Play next sound
242                 playNext: function() {
243                         this.getActive().next().find('audio').trigger('beforePlay').trigger('play');
244                         return true;
245                 },
246                 // Play next sound
247                 playFirst: function() {
248                         this.playlistContainer.find('audio').first().trigger('beforePlay').trigger('play');
249                         return true;
250                 },
251                 // Play next sound
252                 playLast: function() {
253                         this.playlistContainer.find('audio').last().trigger('beforePlay').trigger('play');
254                         return true;
255                 },
256                 // Pause all sounds.
257                 pauseSounds: function() {
258                         this.playlistContainer.find('audio').each(function(){$(this).trigger('pause');});       
259                 },
260                 // stop all sounds.
261                 stopSounds: function() {
262                         this.playlistContainer.find('audio').each(function(){$(this).trigger('stop');});        
263                 },
264         });
265 })(jQuery);
266