2 * GNU MediaGoblin -- federated, autonomous media hosting
3 * Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 var audioPlayer
= new Object();
21 (function (audioPlayer
) {
22 audioPlayer
.init = function (audioElement
) {
23 audioPlayer
.audioElement
= audioElement
;
25 console
.log(audioElement
);
29 $(audioElement
).hide();
32 function attachEvents () {
33 audioPlayer
.audioElement
.addEventListener(
34 'durationchange', audioPlayer
.durationChange
, true);
35 audioPlayer
.audioElement
.addEventListener(
36 'timeupdate', audioPlayer
.timeUpdate
, true);
37 audioPlayer
.audioElement
.addEventListener(
38 'progress', audioPlayer
.onProgress
, true);
39 audioPlayer
.audioElement
.addEventListener(
40 'ended', audioPlayer
.onEnded
, true);
42 $(document
).ready( function () {
43 $('.audio-spectrogram').delegate(
44 '.seekbar', 'click', audioPlayer
.onSeek
);
45 $('.audio-spectrogram').delegate(
46 '.audio-control-play-pause', 'click', audioPlayer
.playPause
);
47 $('.audio-spectrogram').delegate(
48 '.audio-volume', 'change', audioPlayer
.onVolumeChange
);
49 $('.audio-media').delegate(
50 '.audio-spectrogram', 'attachedControls',
51 audioPlayer
.onControlsAttached
);
55 audioPlayer
.onVolumeChange = function(e
) {
56 console
.log('volume change', e
);
57 audioPlayer
.audioElement
.volume
= e
.target
.value
;
60 audioPlayer
.onControlsAttached = function(e
) {
61 console
.log('Controls attached', e
);
62 $('.audio-spectrogram .audio-volume').val(
63 Math
.round(audioPlayer
.audioElement
.volume
, 2));
66 audioPlayer
.onProgress = function(e
) {
68 * Handler for file download progress
72 var buffered
= audioPlayer
.audioElement
.buffered
;
76 var indicators
= $('.audio-spectrogram .buffered-indicators div');
78 for (var i
= 0; i
< buffered
.length
; i
++) {
79 if (!(i
in indicators
)) {
80 $('<div style="display: none;"></div>')
81 .appendTo($('.audio-spectrogram .buffered-indicators'))
83 indicators
= $('.audio-spectrogram .buffered-indicators div');
85 var posStart
= ((buffered
.start(i
) / audioPlayer
.audioElement
.duration
)
86 * audioPlayer
.imageElement
.width());
87 var posStop
= ((buffered
.end(i
) / audioPlayer
.audioElement
.duration
)
88 * audioPlayer
.imageElement
.width());
89 console
.log('indicators', indicators
);
91 var indicator
= $(indicators
[i
]);
93 indicator
.css('left', posStart
);
94 indicator
.css('width', posStop
- posStart
);
98 * Clean up unused indicators
100 if (indicators
.length
> buffered
.length
) {
101 for (var i
= buffered
.length
; i
< indicators
.length
; i
++) {
102 $(indicators
[i
]).fadeOut(500, function () {
109 audioPlayer
.onSeek = function (e
) {
111 * Callback handler for seek event, which is a .click() event on the
114 console
.log('onSeek', e
);
116 var im
= audioPlayer
.imageElement
;
117 var pos
= (e
.offsetX
|| e
.originalEvent
.layerX
) / im
.width();
119 audioPlayer
.audioElement
.currentTime
= pos
* audioPlayer
.audioElement
.duration
;
120 audioPlayer
.audioElement
.play();
121 audioPlayer
.setState(audioPlayer
.PLAYING
);
124 audioPlayer
.onEnded = function (e
) {
125 audioPlayer
.setState(audioPlayer
.PAUSED
);
128 audioPlayer
.playPause = function (e
) {
129 console
.log('playPause', e
);
130 if (audioPlayer
.audioElement
.paused
) {
131 audioPlayer
.audioElement
.play();
132 audioPlayer
.setState(audioPlayer
.PLAYING
);
134 audioPlayer
.audioElement
.pause();
135 audioPlayer
.setState(audioPlayer
.PAUSED
);
139 audioPlayer
.NULL
= null;
140 audioPlayer
.PLAYING
= 2;
141 audioPlayer
.PAUSED
= 4;
143 audioPlayer
.state
= audioPlayer
.NULL
;
145 audioPlayer
.setState = function (state
) {
146 if (state
== audioPlayer
.state
) {
149 audioPlayer
.state
= state
;
153 case audioPlayer
.PLAYING
:
154 $('.audio-spectrogram .audio-control-play-pause')
155 .removeClass('paused').addClass('playing')
158 case audioPlayer
.PAUSED
:
159 $('.audio-spectrogram .audio-control-play-pause')
160 .removeClass('playing').addClass('paused')
166 audioPlayer
.durationChange = function () {
170 audioPlayer
.timeUpdate = function () {
172 * Callback handler for the timeupdate event, responsible for
173 * updating the playhead
175 var currentTime
= audioPlayer
.audioElement
.currentTime
;
176 var playhead
= audioPlayer
.imageElement
.parent().find('.playhead');
177 playhead
.css('width', (currentTime
/ audioPlayer
.audioElement
.duration
)
178 * audioPlayer
.imageElement
.width());
179 var time
= formatTime(currentTime
);
180 var duration
= formatTime(audioPlayer
.audioElement
.duration
);
181 audioPlayer
.imageElement
.parent()
182 .find('.audio-currentTime')
183 .text(time
+ '/' + duration
);
186 function formatTime(seconds
) {
188 * Format a time duration in (hh:)?mm:ss manner
190 var h
= Math
.floor(seconds
/ (60 * 60));
191 var m
= Math
.floor((seconds
- h
* 60 * 60) / 60);
192 var s
= Math
.round(seconds
- h
* 60 * 60 - m
* 60);
193 return '' + (h
? (h
< 10 ? '0' + h
: h
) + ':' : '') + (m
< 10 ? '0' + m
: m
) + ':' + (s
< 10 ? '0' + s
: s
);
196 audioPlayer
.formatTime
= formatTime
;
198 audioPlayer
.attachToImage = function (imageElement
) {
200 * Attach the player to an image element
202 console
.log(imageElement
);
204 var im
= $(imageElement
);
206 audioPlayer
.imageElement
= im
;
208 $('<div class="playhead"></div>').appendTo(im
.parent());
209 $('<div class="buffered-indicators"></div>').appendTo(im
.parent());
210 $('<div class="seekbar"></div>').appendTo(im
.parent());
211 $('<div class="audio-control-play-pause paused">▶</div>').appendTo(im
.parent());
212 $('<div class="audio-currentTime">00:00</div>').appendTo(im
.parent());
213 $('<input type="range" class="audio-volume"'
214 +'value="1" min="0" max="1" step="0.001" />').appendTo(im
.parent());
215 $('.audio-spectrogram').trigger('attachedControls');
219 $(document
).ready(function () {
220 if (!$('.audio-media').length
) {
224 console
.log('Initializing audio player');
226 audioElements
= $('.audio-media .audio-player');
227 audioPlayer
.init(audioElements
[0]);
228 audioPlayer
.attachToImage($('.audio-spectrogram img')[0]);