Skip to content

Commit

Permalink
browser(firefox): wait for file write to finish in stopVideoRecording (
Browse files Browse the repository at this point in the history
  • Loading branch information
yury-s committed Jul 18, 2020
1 parent c45b579 commit 562e1e6
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 6 deletions.
4 changes: 2 additions & 2 deletions browser_patches/firefox/BUILD_NUMBER
@@ -1,2 +1,2 @@
1130
Changed: yurys@chromium.org Thu Jul 16 15:31:21 PDT 2020
1131
Changed: yurys@chromium.org Fri Jul 17 17:30:24 PDT 2020
12 changes: 11 additions & 1 deletion browser_patches/firefox/juggler/protocol/PageHandler.js
Expand Up @@ -300,13 +300,23 @@ class PageHandler {
this._videoSessionId = screencast.startVideoRecording(docShell, file, width, height, scale || 0, devicePixelRatio * rect.top);
}

stopVideoRecording() {
async stopVideoRecording() {
if (this._videoSessionId === -1)
throw new Error('No video recording in progress');
const videoSessionId = this._videoSessionId;
this._videoSessionId = -1;
const screencast = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);
const result = new Promise(resolve =>
Services.obs.addObserver(function onStopped(subject, topic, data) {
if (videoSessionId != data)
return;

Services.obs.removeObserver(onStopped, 'juggler-screencast-stopped');
resolve();
}, 'juggler-screencast-stopped')
);
screencast.stopVideoRecording(videoSessionId);
return result;
}
}

Expand Down
Expand Up @@ -13,5 +13,9 @@ interface nsIDocShell;
interface nsIScreencastService : nsISupports
{
long startVideoRecording(in nsIDocShell docShell, in ACString fileName, in uint32_t width, in uint32_t height, in double scale, in int32_t offset_top);

/**
* Will emit 'juggler-screencast-stopped' when the video file is saved.
*/
void stopVideoRecording(in long sessionId);
};
25 changes: 22 additions & 3 deletions browser_patches/firefox/juggler/screencast/nsScreencastService.cpp
Expand Up @@ -11,6 +11,8 @@
#include "mozilla/PresShell.h"
#include "mozilla/StaticPtr.h"
#include "nsIDocShell.h"
#include "nsIObserverService.h"
#include "nsISupportsPrimitives.h"
#include "nsThreadManager.h"
#include "nsView.h"
#include "nsViewManager.h"
Expand Down Expand Up @@ -46,6 +48,18 @@ rtc::scoped_refptr<webrtc::VideoCaptureModule> CreateWindowCapturer(nsIWidget* w
windowId.AppendPrintf("%" PRIuPTR, rawWindowId);
return webrtc::DesktopCaptureImpl::Create(sessionId, windowId.get(), webrtc::CaptureDeviceType::Window);
}

void NotifyScreencastStopped(int32_t sessionId) {
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
if (!observerService) {
fprintf(stderr, "NotifyScreencastStopped error: no observer service\n");
return;
}

nsString id;
id.AppendPrintf("%" PRIi32, sessionId);
observerService->NotifyObservers(nullptr, "juggler-screencast-stopped", id.get());
}
}

class nsScreencastService::Session : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
Expand All @@ -72,13 +86,13 @@ class nsScreencastService::Session : public rtc::VideoSinkInterface<webrtc::Vide
return true;
}

void Stop() {
void Stop(std::function<void()>&& callback) {
mCaptureModule->DeRegisterCaptureDataCallback(this);
int error = mCaptureModule->StopCapture();
if (error) {
fprintf(stderr, "StopCapture error %d\n", error);
return;
}
mEncoder->finish(std::move(callback));
}

// These callbacks end up running on the VideoCapture thread.
Expand Down Expand Up @@ -150,7 +164,12 @@ nsresult nsScreencastService::StopVideoRecording(int32_t sessionId) {
auto it = mIdToSession.find(sessionId);
if (it == mIdToSession.end())
return NS_ERROR_INVALID_ARG;
it->second->Stop();
it->second->Stop([sessionId] {
NS_DispatchToMainThread(NS_NewRunnableFunction(
"NotifyScreencastStopped", [sessionId]() -> void {
NotifyScreencastStopped(sessionId);
}));
});
mIdToSession.erase(it);
return NS_OK;
}
Expand Down

0 comments on commit 562e1e6

Please sign in to comment.