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]);