forked from CrowdCurio/audio-annotator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
components.js
216 lines (184 loc) · 6.44 KB
/
components.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
'use strict';
/*
* Purpose:
* Used to create the timestamps of segment start and end times and play bar
* Dependencies:
* jQuey, audio-annotator.css
*/
var Util = {
// Convert seconds to timestamp string
secondsToString: function(seconds) {
if (seconds === null) {
return '';
}
var timeStr = '00:';
if (seconds >= 10) {
timeStr += seconds.toFixed(3);
} else {
timeStr += '0' + seconds.toFixed(3);
}
return timeStr;
},
// Return input elements that will contain the start, end and duration times of a sound segment
createSegmentTime: function() {
var timeDiv = $('<div>', {class: 'time_segment'});
var start = $('<span>', {text: 'Start:'});
var startInput = $('<input>', {
type: 'text',
class: 'form-control start',
readonly: true
});
var end = $('<span>', {text: 'End:'});
var endInput = $('<input>', {
type: 'text',
class: 'form-control end',
readonly: true
});
var duration = $('<span>', {text: 'Duration:'});
var durationInput = $('<input>', {
type: 'text',
class: 'form-control duration',
readonly: true
});
// Return the parent element with the all the time elements appended
return timeDiv.append([start, startInput, end, endInput, duration, durationInput]);
}
};
/*
* Purpose:
* Used for the play button and timestamp that controls how the wavesurfer audio is played
* Dependencies:
* jQuery, Font Awesome, Wavesurfer (lib/wavesurfer.min.js), Util (src/components.js), audio-annotator.css
*/
function PlayBar(wavesurfer) {
this.wavesurfer = wavesurfer;
// Dom element containing play button and progress timestamp
this.playBarDom = null;
// List of user actions (click-pause, click-play, spacebar-pause, spacebar-play) with
// timestamps of when the user took the action
this.events = [];
}
PlayBar.prototype = {
// Return a string of the form "<current_time> / <clip_duration>" (Ex "00:03.644 / 00:10.796")
getTimerText: function() {
return Util.secondsToString(this.wavesurfer.getCurrentTime()) +
' / ' + Util.secondsToString(this.wavesurfer.getDuration());
},
// Create the play bar and progress timestamp html elements and append eventhandlers for updating
// these elements for when the clip is played and paused
create: function() {
var my = this;
this.addWaveSurferEvents();
// Create the play button
var playButton = $('<i>', {
class: 'play_audio fa fa-play-circle',
});
playButton.click(function () {
my.trackEvent('click-' + (my.wavesurfer.isPlaying() ? 'pause' : 'play'));
my.wavesurfer.playPause();
});
// Create audio timer text
var timer = $('<span>', {
class: 'timer',
});
this.playBarDom = [playButton, timer];
},
// Append the play buttom and the progress timestamp to the .play_bar container
update: function() {
$(this.playBarDom).detach();
$('.play_bar').append(this.playBarDom);
this.events = [];
this.updateTimer();
},
// Update the progress timestamp (called when audio is playing)
updateTimer: function() {
$('.timer').text(this.getTimerText());
},
// Used to track events related to playing and pausing the clip (click or spacebar)
trackEvent: function(eventString) {
var audioSourceTime = this.wavesurfer.getCurrentTime();
var eventData = {
event: eventString,
time: new Date().getTime(),
audioSourceTime: audioSourceTime
};
this.events.push(eventData);
},
// Return the list of events representing the actions the user did related to playing and
// pausing the audio
getEvents: function() {
// Return shallow copy
return this.events.slice();
},
// Add wavesurfer event handlers to update the play button and progress timestamp
addWaveSurferEvents: function() {
var my = this;
this.wavesurfer.on('play', function () {
$('.play_audio').removeClass('fa-play-circle').addClass('fa-stop-circle');
});
this.wavesurfer.on('pause', function () {
$('.play_audio').removeClass('fa-stop-circle').addClass('fa-play-circle');
});
this.wavesurfer.on('seek', function () {
my.updateTimer();
});
this.wavesurfer.on('audioprocess', function () {
my.updateTimer();
});
// Play and pause on spacebar keydown
$(document).on("keydown", function (event) {
if (event.keyCode === 32) {
event.preventDefault();
my.trackEvent('spacebar-' + (my.wavesurfer.isPlaying() ? 'pause' : 'play'));
my.wavesurfer.playPause();
}
});
},
};
/*
* Purpose:
* Used for the workflow buttons that are used to submit annotations or to exit the task
* Dependencies:
* jQuery, audio-annotator.css
*/
function WorkflowBtns(exitUrl) {
// Dom of submit and load next btn
this.nextBtn = null;
// Dom of exit task btn
this.exitBtn = null;
// The url the user will be directed to when they exit
this.exitUrl = exitUrl;
// Boolean that determined if the exit button is shown
this.showExitBtn = false;
}
WorkflowBtns.prototype = {
// Create dom elements for the next and exit btns
create: function() {
var my = this;
this.nextBtn = $('<button>', {
class: 'btn submit',
text: 'SUBMIT & LOAD NEXT RECORDING'
});
this.nextBtn.click(function () {
$(my).trigger('submit-annotations');
});
this.exitBtn = $('<button>', {
text: 'Exit Now',
class: 'exit btn',
});
this.exitBtn.click(function () {
window.location = my.exitUrl;
});
},
// Append the next and exit elements to the the parent container
update: function() {
$('.submit_container').append(this.nextBtn);
if (this.showExitBtn) {
$('.submit_container').append(this.exitBtn);
}
},
// Set the value of showExitBtn
setExitBtnFlag: function(showExitBtn) {
this.showExitBtn = showExitBtn;
}
};