Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "modules/mediarecorder/MediaRecorder.h" | 6 #include "modules/mediarecorder/MediaRecorder.h" |
| 7 | 7 |
| 8 #include "core/dom/DOMError.h" | 8 #include "core/dom/DOMError.h" |
| 9 #include "core/fileapi/Blob.h" | 9 #include "core/fileapi/Blob.h" |
| 10 #include "modules/EventModules.h" | 10 #include "modules/EventModules.h" |
| 11 #include "modules/EventTargetModules.h" | 11 #include "modules/EventTargetModules.h" |
| 12 #include "modules/mediarecorder/BlobEvent.h" | |
| 12 #include "modules/mediarecorder/MediaRecorderErrorEvent.h" | 13 #include "modules/mediarecorder/MediaRecorderErrorEvent.h" |
| 13 #include "platform/NotImplemented.h" | 14 #include "platform/NotImplemented.h" |
| 14 #include "platform/blob/BlobData.h" | 15 #include "platform/blob/BlobData.h" |
| 15 #include "public/platform/Platform.h" | 16 #include "public/platform/Platform.h" |
| 16 #include "public/platform/WebMediaStream.h" | 17 #include "public/platform/WebMediaStream.h" |
| 17 | 18 |
| 18 namespace blink { | 19 namespace blink { |
| 19 | 20 |
| 20 namespace { | 21 namespace { |
| 21 | 22 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 m_recorderHandler->resume(); | 146 m_recorderHandler->resume(); |
| 146 } | 147 } |
| 147 | 148 |
| 148 void MediaRecorder::requestData(ExceptionState& exceptionState) | 149 void MediaRecorder::requestData(ExceptionState& exceptionState) |
| 149 { | 150 { |
| 150 if (m_state != State::Recording) { | 151 if (m_state != State::Recording) { |
| 151 exceptionState.throwDOMException(InvalidStateError, "The MediaRecorder's state is '" + stateToString(m_state) + "'."); | 152 exceptionState.throwDOMException(InvalidStateError, "The MediaRecorder's state is '" + stateToString(m_state) + "'."); |
| 152 return; | 153 return; |
| 153 } | 154 } |
| 154 | 155 |
| 155 createBlobEvent(BlobData::create()); | 156 createBlobEvent(nullptr, 0); |
| 156 } | 157 } |
| 157 | 158 |
| 158 String MediaRecorder::canRecordMimeType(const String& mimeType) | 159 String MediaRecorder::canRecordMimeType(const String& mimeType) |
| 159 { | 160 { |
| 160 RawPtr<WebMediaRecorderHandler> handler = Platform::current()->createMediaRe corderHandler(); | 161 RawPtr<WebMediaRecorderHandler> handler = Platform::current()->createMediaRe corderHandler(); |
| 161 if (!handler) | 162 if (!handler) |
| 162 return emptyString(); | 163 return emptyString(); |
| 163 | 164 |
| 164 // MediaRecorder canRecordMimeType() MUST return 'probably' "if the UA is | 165 // MediaRecorder canRecordMimeType() MUST return 'probably' "if the UA is |
| 165 // confident that mimeType represents a type that it can record" [1], but a | 166 // confident that mimeType represents a type that it can record" [1], but a |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 | 199 |
| 199 m_stopped = true; | 200 m_stopped = true; |
| 200 m_stream.clear(); | 201 m_stream.clear(); |
| 201 m_recorderHandler.clear(); | 202 m_recorderHandler.clear(); |
| 202 | 203 |
| 203 scheduleDispatchEvent(Event::create(EventTypeNames::stop)); | 204 scheduleDispatchEvent(Event::create(EventTypeNames::stop)); |
| 204 } | 205 } |
| 205 | 206 |
| 206 void MediaRecorder::writeData(const char* data, size_t length, bool lastInSlice) | 207 void MediaRecorder::writeData(const char* data, size_t length, bool lastInSlice) |
| 207 { | 208 { |
| 208 if (!lastInSlice && m_stopped) { | 209 if (m_stopped) { |
| 209 m_stopped = false; | 210 m_stopped = false; |
| 210 scheduleDispatchEvent(Event::create(EventTypeNames::start)); | 211 scheduleDispatchEvent(Event::create(EventTypeNames::start)); |
| 211 } | 212 } |
| 212 | 213 |
| 213 // TODO(mcasas): Act as |m_ignoredMutedMedia| instructs if |m_stream| track( s) is in muted() state. | 214 // TODO(mcasas): Act as |m_ignoredMutedMedia| instructs if |m_stream| track( s) is in muted() state. |
| 214 // TODO(mcasas): Use |lastInSlice| to indicate to JS that recording is done. | 215 createBlobEvent(data, length); |
| 215 | |
| 216 OwnPtr<BlobData> blobData = BlobData::create(); | |
| 217 blobData->appendBytes(data, length); | |
| 218 createBlobEvent(blobData.release()); | |
| 219 } | 216 } |
| 220 | 217 |
| 221 void MediaRecorder::failOutOfMemory(const WebString& message) | 218 void MediaRecorder::failOutOfMemory(const WebString& message) |
| 222 { | 219 { |
| 223 scheduleDispatchEvent(MediaRecorderErrorEvent::create( | 220 scheduleDispatchEvent(MediaRecorderErrorEvent::create( |
| 224 EventTypeNames::error, false, false, "OutOfMemory", message)); | 221 EventTypeNames::error, false, false, "OutOfMemory", message)); |
| 225 | 222 |
| 226 if (m_state == State::Recording) | 223 if (m_state == State::Recording) |
| 227 stopRecording(); | 224 stopRecording(); |
| 228 } | 225 } |
| 229 | 226 |
| 230 void MediaRecorder::failIllegalStreamModification(const WebString& message) | 227 void MediaRecorder::failIllegalStreamModification(const WebString& message) |
| 231 { | 228 { |
| 232 scheduleDispatchEvent(MediaRecorderErrorEvent::create( | 229 scheduleDispatchEvent(MediaRecorderErrorEvent::create( |
| 233 EventTypeNames::error, false, false, "IllegalStreamModification", messag e)); | 230 EventTypeNames::error, false, false, "IllegalStreamModification", messag e)); |
| 234 | 231 |
| 235 if (m_state == State::Recording) | 232 if (m_state == State::Recording) |
| 236 stopRecording(); | 233 stopRecording(); |
| 237 } | 234 } |
| 238 | 235 |
| 239 void MediaRecorder::failOtherRecordingError(const WebString& message) | 236 void MediaRecorder::failOtherRecordingError(const WebString& message) |
| 240 { | 237 { |
| 241 scheduleDispatchEvent(MediaRecorderErrorEvent::create( | 238 scheduleDispatchEvent(MediaRecorderErrorEvent::create( |
| 242 EventTypeNames::error, false, false, "OtherRecordingError", message)); | 239 EventTypeNames::error, false, false, "OtherRecordingError", message)); |
| 243 | 240 |
| 244 if (m_state == State::Recording) | 241 if (m_state == State::Recording) |
| 245 stopRecording(); | 242 stopRecording(); |
| 246 } | 243 } |
| 247 | 244 |
| 248 void MediaRecorder::createBlobEvent(PassOwnPtr<BlobData> blobData) | 245 void MediaRecorder::createBlobEvent(const char* data, size_t length) |
|
Peter Beverloo
2015/09/18 13:07:26
Out of interest, why do you find passing |data| an
mcasas
2015/09/21 15:24:15
Hmm this is just hanging around from the experimen
| |
| 249 { | 246 { |
| 250 // TODO(mcasas): Launch a BlobEvent when that class is landed, but also see https://github.com/w3c/mediacapture-record/issues/17. | 247 // TODO(mcasas): Launch a BlobEvent when that class is landed, but also see https://github.com/w3c/mediacapture-record/issues/17. |
|
Peter Beverloo
2015/09/18 13:07:26
This TODO is now redundant.
mcasas
2015/09/21 15:24:15
Rephrased.
| |
| 251 notImplemented(); | 248 OwnPtr<BlobData> blobData = BlobData::create(); |
| 249 blobData->appendBytes(data, length); | |
| 250 scheduleDispatchEvent(BlobEvent::create(EventTypeNames::dataavailable, false , false, Blob::create(BlobDataHandle::create(blobData.release(), length)))); | |
| 252 } | 251 } |
| 253 | 252 |
| 254 void MediaRecorder::stopRecording() | 253 void MediaRecorder::stopRecording() |
| 255 { | 254 { |
| 256 ASSERT(m_state != State::Inactive); | 255 ASSERT(m_state != State::Inactive); |
| 257 m_state = State::Inactive; | 256 m_state = State::Inactive; |
| 258 | 257 |
| 259 m_recorderHandler->stop(); | 258 m_recorderHandler->stop(); |
| 260 | 259 |
| 261 createBlobEvent(BlobData::create()); | 260 createBlobEvent(nullptr, 0); |
| 262 | 261 |
| 263 scheduleDispatchEvent(Event::create(EventTypeNames::stop)); | 262 scheduleDispatchEvent(Event::create(EventTypeNames::stop)); |
| 264 } | 263 } |
| 265 | 264 |
| 266 void MediaRecorder::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> event) | 265 void MediaRecorder::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> event) |
| 267 { | 266 { |
| 268 m_scheduledEvents.append(event); | 267 m_scheduledEvents.append(event); |
| 269 | 268 |
| 270 m_dispatchScheduledEventRunner.runAsync(); | 269 m_dispatchScheduledEventRunner.runAsync(); |
| 271 } | 270 } |
| 272 | 271 |
| 273 void MediaRecorder::dispatchScheduledEvent() | 272 void MediaRecorder::dispatchScheduledEvent() |
| 274 { | 273 { |
| 275 WillBeHeapVector<RefPtrWillBeMember<Event>> events; | 274 WillBeHeapVector<RefPtrWillBeMember<Event>> events; |
| 276 events.swap(m_scheduledEvents); | 275 events.swap(m_scheduledEvents); |
| 277 | 276 |
| 278 for (const auto& event : events) | 277 for (const auto& event : events) |
| 279 dispatchEvent(event); | 278 dispatchEvent(event); |
| 280 } | 279 } |
| 281 | 280 |
| 282 DEFINE_TRACE(MediaRecorder) | 281 DEFINE_TRACE(MediaRecorder) |
| 283 { | 282 { |
| 284 visitor->trace(m_stream); | 283 visitor->trace(m_stream); |
| 285 visitor->trace(m_scheduledEvents); | 284 visitor->trace(m_scheduledEvents); |
| 286 RefCountedGarbageCollectedEventTargetWithInlineData<MediaRecorder>::trace(vi sitor); | 285 RefCountedGarbageCollectedEventTargetWithInlineData<MediaRecorder>::trace(vi sitor); |
| 287 ActiveDOMObject::trace(visitor); | 286 ActiveDOMObject::trace(visitor); |
| 288 } | 287 } |
| 289 | 288 |
| 290 } // namespace blink | 289 } // namespace blink |
| OLD | NEW |