nsresult MediaRecorder::CreateAndDispatchBlobEvent() { NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread"); if (!CheckPrincipal()) { // Media is not same-origin, don't allow the data out. return NS_ERROR_DOM_SECURITY_ERR; } nsCOMPtr<nsIDOMBlob> blob; blob = mEncodedBufferCache->ExtractBlob(mMimeType); // create an event that uses the MessageEvent interface, // which does not bubble, is not cancelable, and has no default action nsCOMPtr<nsIDOMEvent> event; nsresult rv = NS_NewDOMBlobEvent(getter_AddRefs(event), this, nullptr, nullptr); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMBlobEvent> blobEvent = do_QueryInterface(event); rv = blobEvent->InitBlobEvent(NS_LITERAL_STRING("dataavailable"), false, false, blob); NS_ENSURE_SUCCESS(rv, rv); event->SetTrusted(true); return DispatchDOMEvent(nullptr, event, nullptr, nullptr); }
void MediaRecorder::Start(const Optional<int32_t>& aTimeSlice, ErrorResult& aResult) { if (mState != RecordingState::Inactive) { aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } if (aTimeSlice.WasPassed()) { if (aTimeSlice.Value() < 0) { aResult.Throw(NS_ERROR_INVALID_ARG); return; } mTimeSlice = aTimeSlice.Value(); } else { mTimeSlice = 0; } // Create a TrackUnionStream to support Pause/Resume by using ChangeExplicitBlockerCount MediaStreamGraph* gm = mStream->GetStream()->Graph(); mTrackUnionStream = gm->CreateTrackUnionStream(mStream); MOZ_ASSERT(mTrackUnionStream, "CreateTrackUnionStream failed"); if (!CheckPrincipal()) { aResult.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } if (mEncodedBufferCache == nullptr) { mEncodedBufferCache = new EncodedBufferCache(MAX_ALLOW_MEMORY_BUFFER); } mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING("")); MOZ_ASSERT(mEncoder, "CreateEncoder failed"); mTrackUnionStream->SetAutofinish(true); nsRefPtr<MediaInputPort> port = mTrackUnionStream->AllocateInputPort(mStream->GetStream(), MediaInputPort::FLAG_BLOCK_OUTPUT); if (mEncoder) { mTrackUnionStream->AddListener(mEncoder); } else { aResult.Throw(NS_ERROR_DOM_ABORT_ERR); } if (!mReadThread) { nsresult rv = NS_NewNamedThread("Media Encoder", getter_AddRefs(mReadThread)); if (NS_FAILED(rv)) { aResult.Throw(rv); return; } nsRefPtr<ExtractEncodedDataTask> event = new ExtractEncodedDataTask(this, mEncoder); mReadThread->Dispatch(event, NS_DISPATCH_NORMAL); mState = RecordingState::Recording; } }
nsresult MediaRecorder::CreateAndDispatchBlobEvent(already_AddRefed<nsIDOMBlob>&& aBlob) { NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread"); if (!CheckPrincipal()) { // Media is not same-origin, don't allow the data out. nsRefPtr<nsIDOMBlob> blob = aBlob; return NS_ERROR_DOM_SECURITY_ERR; } BlobEventInit init; init.mBubbles = false; init.mCancelable = false; init.mData = aBlob; nsRefPtr<BlobEvent> event = BlobEvent::Constructor(this, NS_LITERAL_STRING("dataavailable"), init); event->SetTrusted(true); return DispatchDOMEvent(nullptr, event, nullptr, nullptr); }
void MediaRecorder::Start(const Optional<int32_t>& aTimeSlice, ErrorResult& aResult) { LOG(PR_LOG_DEBUG, ("MediaRecorder.Start %p", this)); if (mState != RecordingState::Inactive) { aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } if (mStream->GetStream()->IsFinished() || mStream->GetStream()->IsDestroyed()) { aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } if (!mStream->GetPrincipal()) { aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } if (!CheckPrincipal()) { aResult.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } int32_t timeSlice = 0; if (aTimeSlice.WasPassed()) { if (aTimeSlice.Value() < 0) { aResult.Throw(NS_ERROR_INVALID_ARG); return; } timeSlice = aTimeSlice.Value(); } mState = RecordingState::Recording; // Start a session mSessions.AppendElement(); mSessions.LastElement() = new Session(this, timeSlice); mSessions.LastElement()->Start(); }