@@ -144,7 +144,7 @@ function MediaRecorderWrapper(mediaStream) {
144
144
// if user chosen only audio option; and he tried to pass MediaStream with
145
145
// both audio and video tracks;
146
146
// using a dirty workaround to generate audio-only stream so that we can get audio/ogg output.
147
- if ( this . type == 'audio' && mediaStream . getVideoTracks && mediaStream . getVideoTracks ( ) . length ) {
147
+ if ( this . type == 'audio' && mediaStream . getVideoTracks && mediaStream . getVideoTracks ( ) . length && ! navigator . mozGetUserMedia ) {
148
148
var context = new AudioContext ( ) ;
149
149
var mediaStreamSource = context . createMediaStreamSource ( mediaStream ) ;
150
150
@@ -153,87 +153,106 @@ function MediaRecorderWrapper(mediaStream) {
153
153
154
154
mediaStream = destination . stream ;
155
155
}
156
-
156
+
157
157
// void start(optional long timeSlice)
158
158
// timestamp to fire "ondataavailable"
159
-
159
+
160
160
// starting a recording session; which will initiate "Reading Thread"
161
161
// "Reading Thread" are used to prevent main-thread blocking scenarios
162
162
this . start = function ( mTimeSlice ) {
163
163
mTimeSlice = mTimeSlice || 1000 ;
164
+ isStopRecording = false ;
164
165
165
- mediaRecorder = new MediaRecorder ( mediaStream ) ;
166
- mediaRecorder . ondataavailable = function ( e ) {
167
- console . log ( 'ondataavailable' , e . data . type , e . data . size , e . data ) ;
168
- // mediaRecorder.state == 'recording' means that media recorder is associated with "session"
169
- // mediaRecorder.state == 'stopped' means that media recorder is detached from the "session" ... in this case; "session" will also be deleted.
166
+ function startRecording ( ) {
167
+ if ( isStopRecording ) return ;
170
168
171
- if ( ! e . data . size ) {
172
- console . warn ( 'Recording of' , e . data . type , 'failed.' ) ;
173
- return ;
174
- }
169
+ mediaRecorder = new MediaRecorder ( mediaStream ) ;
175
170
176
- // at this stage, Firefox MediaRecorder API doesn't allow to choose the output mimeType format!
177
- var blob = new window . Blob ( [ e . data ] , {
178
- type : e . data . type || self . mimeType || 'audio/ogg' // It specifies the container format as well as the audio and video capture formats.
179
- } ) ;
171
+ mediaRecorder . ondataavailable = function ( e ) {
172
+ console . log ( 'ondataavailable' , e . data . type , e . data . size , e . data ) ;
173
+ // mediaRecorder.state == 'recording' means that media recorder is associated with "session"
174
+ // mediaRecorder.state == 'stopped' means that media recorder is detached from the "session" ... in this case; "session" will also be deleted.
180
175
181
- // Dispatching OnDataAvailable Handler
182
- self . ondataavailable ( blob ) ;
183
- } ;
176
+ if ( ! e . data . size ) {
177
+ console . warn ( 'Recording of' , e . data . type , 'failed.' ) ;
178
+ return ;
179
+ }
184
180
185
- mediaRecorder . onstop = function ( error ) {
186
- // for video recording on Firefox, it will be fired quickly.
187
- // because work on VideoFrameContainer is still in progress
188
- // https://wiki.mozilla.org/Gecko:MediaRecorder
189
- self . onstop ( error ) ;
190
- } ;
181
+ // at this stage, Firefox MediaRecorder API doesn't allow to choose the output mimeType format!
182
+ var blob = new window . Blob ( [ e . data ] , {
183
+ type : e . data . type || self . mimeType || 'audio/ogg' // It specifies the container format as well as the audio and video capture formats.
184
+ } ) ;
191
185
192
- // http://www.w3.org/TR/2012/WD-dom-20121206/#error-names-table
193
- // showBrowserSpecificIndicator: got neither video nor audio access
194
- // "VideoFrameContainer" can't be accessed directly; unable to find any wrapper using it.
195
- // that's why there is no video recording support on firefox
186
+ // Dispatching OnDataAvailable Handler
187
+ self . ondataavailable ( blob ) ;
188
+ } ;
196
189
197
- // video recording fails because there is no encoder available there
198
- // http://dxr.mozilla.org/mozilla-central/source/content/media/MediaRecorder.cpp#317
190
+ mediaRecorder . onstop = function ( error ) {
191
+ // for video recording on Firefox, it will be fired quickly.
192
+ // because work on VideoFrameContainer is still in progress
193
+ // https://wiki.mozilla.org/Gecko:MediaRecorder
199
194
200
- // Maybe "Read Thread" doesn't fire video-track read notification ;
201
- // that's why shutdown notification is received; and "Read Thread" is stopped.
195
+ // self.onstop(error) ;
196
+ } ;
202
197
203
- // https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-capture/MediaRecorder.html#error-handling
204
- mediaRecorder . onerror = function ( error ) {
205
- console . error ( error ) ;
206
- self . start ( mTimeSlice ) ;
207
- } ;
198
+ // http://www.w3.org/TR/2012/WD-dom-20121206/#error-names-table
199
+ // showBrowserSpecificIndicator: got neither video nor audio access
200
+ // "VideoFrameContainer" can't be accessed directly; unable to find any wrapper using it.
201
+ // that's why there is no video recording support on firefox
208
202
209
- mediaRecorder . onwarning = function ( warning ) {
210
- console . warn ( warning ) ;
211
- } ;
203
+ // video recording fails because there is no encoder available there
204
+ // http://dxr.mozilla.org/mozilla-central/source/content/media/MediaRecorder.cpp#317
212
205
213
- // void start(optional long mTimeSlice)
214
- // The interval of passing encoded data from EncodedBufferCache to onDataAvailable
215
- // handler. "mTimeSlice < 0" means Session object does not push encoded data to
216
- // onDataAvailable, instead, it passive wait the client side pull encoded data
217
- // by calling requestData API.
218
- mediaRecorder . start ( mTimeSlice ) ;
206
+ // Maybe "Read Thread" doesn't fire video-track read notification;
207
+ // that's why shutdown notification is received; and "Read Thread" is stopped.
219
208
220
- // Start recording. If timeSlice has been provided, mediaRecorder will
221
- // raise a dataavailable event containing the Blob of collected data on every timeSlice milliseconds.
222
- // If timeSlice isn't provided, UA should call the RequestData to obtain the Blob data, also set the mTimeSlice to zero.
209
+ // https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-capture/MediaRecorder.html#error-handling
210
+ mediaRecorder . onerror = function ( error ) {
211
+ console . error ( error ) ;
212
+ self . start ( mTimeSlice ) ;
213
+ } ;
214
+
215
+ mediaRecorder . onwarning = function ( warning ) {
216
+ console . warn ( warning ) ;
217
+ } ;
218
+
219
+ // void start(optional long mTimeSlice)
220
+ // The interval of passing encoded data from EncodedBufferCache to onDataAvailable
221
+ // handler. "mTimeSlice < 0" means Session object does not push encoded data to
222
+ // onDataAvailable, instead, it passive wait the client side pull encoded data
223
+ // by calling requestData API.
224
+ mediaRecorder . start ( 0 ) ;
225
+
226
+ // Start recording. If timeSlice has been provided, mediaRecorder will
227
+ // raise a dataavailable event containing the Blob of collected data on every timeSlice milliseconds.
228
+ // If timeSlice isn't provided, UA should call the RequestData to obtain the Blob data, also set the mTimeSlice to zero.
229
+
230
+ setTimeout ( function ( ) {
231
+ mediaRecorder . stop ( ) ;
232
+ startRecording ( ) ;
233
+ } , mTimeSlice ) ;
234
+ }
235
+
236
+ // dirty workaround to fix Firefox 2nd+ intervals
237
+ startRecording ( ) ;
223
238
} ;
224
239
240
+ var isStopRecording = false ;
241
+
225
242
this . stop = function ( ) {
226
- if ( mediaRecorder && mediaRecorder . state == 'recording' ) {
227
- mediaRecorder . stop ( ) ;
243
+ isStopRecording = true ;
244
+
245
+ if ( self . onstop ) {
246
+ self . onstop ( { } ) ;
228
247
}
229
248
} ;
230
249
231
- this . ondataavailable = this . onstop = function ( ) { } ;
250
+ this . ondataavailable = this . onstop = function ( ) { } ;
232
251
233
252
// Reference to itself
234
253
var self = this ;
235
-
236
- if ( ! self . mimeType ) {
254
+
255
+ if ( ! self . mimeType && ! ! mediaStream . getAudioTracks ) {
237
256
self . mimeType = mediaStream . getAudioTracks ( ) . length && mediaStream . getVideoTracks ( ) . length ? 'video/webm' : 'audio/ogg' ;
238
257
}
239
258
0 commit comments