Improve recording performance by recording directly to a file

pull/263/head
James H Ball 2024-10-12 20:07:53 +01:00
rodzic f30ac1823e
commit e7f018932d
3 zmienionych plików z 34 dodań i 24 usunięć

Wyświetl plik

@ -139,7 +139,8 @@
let externalBufferSize = 1920; let externalBufferSize = 1920;
let recording = false; let recording = false;
let mediaRecorder = undefined; let mediaRecorder = undefined;
let downloadCallback = undefined; let sendVideoDataCallback = undefined;
let finishRecordingCallback = undefined;
const toggleRecording = () => { const toggleRecording = () => {
recording = !recording; recording = !recording;
@ -148,19 +149,16 @@
const data = []; const data = [];
const stream = canvas.captureStream(60); const stream = canvas.captureStream(60);
mediaRecorder = new MediaRecorder(stream); mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = (e) => data.push(e.data); mediaRecorder.ondataavailable = (e) => {
mediaRecorder.onstop = (e) => {
const div = document.getElementById("buttonRow");
var a = document.createElement("a");
const video = new Blob(data, { type: "video/webm;codecs=h264" });
var reader = new FileReader(); var reader = new FileReader();
reader.readAsDataURL(video); reader.readAsDataURL(e.data);
reader.onloadend = function() { reader.onloadend = function() {
var dataUrl = reader.result; var dataUrl = reader.result;
var base64 = dataUrl.split(',')[1]; var base64 = dataUrl.split(',')[1];
downloadCallback(base64); sendVideoDataCallback(base64);
} }
}; };
mediaRecorder.onstop = (e) => finishRecordingCallback();
mediaRecorder.start(); mediaRecorder.start();
} else { } else {
mediaRecorder.stop(); mediaRecorder.stop();
@ -242,8 +240,12 @@
toggleFullscreen(); toggleFullscreen();
}); });
downloadCallback = (base64) => { finishRecordingCallback = () => {
Juce.getNativeFunction("downloadVideo")(base64); Juce.getNativeFunction("finishRecording")();
};
sendVideoDataCallback = (base64) => {
Juce.getNativeFunction("sendVideoData")(base64);
}; };
</script> </script>

Wyświetl plik

@ -270,9 +270,7 @@ void VisualiserComponent::paintXY(juce::Graphics& g, juce::Rectangle<float> area
} }
void VisualiserComponent::initialiseBrowser() { void VisualiserComponent::initialiseBrowser() {
if (recordingHalted != nullptr) { haltRecording();
recordingHalted();
}
oldBrowser = std::move(browser); oldBrowser = std::move(browser);
if (oldBrowser != nullptr) { if (oldBrowser != nullptr) {
removeChildComponent(oldBrowser.get()); removeChildComponent(oldBrowser.get());
@ -326,18 +324,18 @@ void VisualiserComponent::initialiseBrowser() {
.withNativeFunction("isVisualiserOnly", [this](auto& var, auto complete) { .withNativeFunction("isVisualiserOnly", [this](auto& var, auto complete) {
complete(visualiserOnly); complete(visualiserOnly);
}) })
.withNativeFunction("downloadVideo", [this](const juce::Array<juce::var>& args, auto complete) { .withNativeFunction("sendVideoData", [this](const juce::Array<juce::var>& args, auto complete) {
juce::String base64 = args[0].toString(); juce::FileOutputStream stream{tempVideoFile};
juce::Base64::convertFromBase64(stream, args[0].toString());
stream.flush();
})
.withNativeFunction("finishRecording", [this](auto& var, auto complete) {
chooser = std::make_unique<juce::FileChooser>("Save video", juce::File::getSpecialLocation(juce::File::SpecialLocationType::userDesktopDirectory).getChildFile("osci-render.webm"), "*.webm"); chooser = std::make_unique<juce::FileChooser>("Save video", juce::File::getSpecialLocation(juce::File::SpecialLocationType::userDesktopDirectory).getChildFile("osci-render.webm"), "*.webm");
chooser->launchAsync(juce::FileBrowserComponent::saveMode, chooser->launchAsync(juce::FileBrowserComponent::saveMode,
[base64](const juce::FileChooser& chooser) { [this](const juce::FileChooser& chooser) {
juce::File result = chooser.getResult(); juce::File result = chooser.getResult();
if (result.getFullPathName().isNotEmpty()) { if (result.getFullPathName().isNotEmpty()) {
juce::FileOutputStream stream(result); tempVideoFile.moveFileTo(result);
stream.setPosition(0);
stream.truncate();
juce::Base64::convertFromBase64(stream, base64);
stream.flush();
} }
}); });
}) })
@ -388,9 +386,19 @@ void VisualiserComponent::toggleRecording() {
if (oldVisualiser) { if (oldVisualiser) {
return; return;
} }
tempVideoFile = juce::File::createTempFile(".webm");
browser->emitEventIfBrowserIsVisible("toggleRecording", juce::var()); browser->emitEventIfBrowserIsVisible("toggleRecording", juce::var());
} }
void VisualiserComponent::haltRecording() {
if (oldVisualiser) {
return;
}
if (recordingHalted != nullptr) {
recordingHalted();
}
}
void VisualiserComponent::resized() { void VisualiserComponent::resized() {
if (!oldVisualiser) { if (!oldVisualiser) {
browser->setBounds(getLocalBounds()); browser->setBounds(getLocalBounds());
@ -415,9 +423,7 @@ void VisualiserComponent::childChanged() {
} }
void VisualiserComponent::popoutWindow() { void VisualiserComponent::popoutWindow() {
if (recordingHalted != nullptr) { haltRecording();
recordingHalted();
}
auto visualiser = new VisualiserComponent(sampleRateManager, consumerManager, settings, this, oldVisualiser); auto visualiser = new VisualiserComponent(sampleRateManager, consumerManager, settings, this, oldVisualiser);
visualiser->settings.setLookAndFeel(&getLookAndFeel()); visualiser->settings.setLookAndFeel(&getLookAndFeel());
visualiser->openSettings = openSettings; visualiser->openSettings = openSettings;

Wyświetl plik

@ -43,6 +43,7 @@ public:
void setVisualiserType(bool oldVisualiser); void setVisualiserType(bool oldVisualiser);
void handleAsyncUpdate() override; void handleAsyncUpdate() override;
void toggleRecording(); void toggleRecording();
void haltRecording();
VisualiserComponent* parent = nullptr; VisualiserComponent* parent = nullptr;
VisualiserComponent* child = nullptr; VisualiserComponent* child = nullptr;
@ -124,6 +125,7 @@ private:
std::unique_ptr<juce::WebBrowserComponent> oldBrowser = nullptr; std::unique_ptr<juce::WebBrowserComponent> oldBrowser = nullptr;
std::unique_ptr<juce::FileChooser> chooser; std::unique_ptr<juce::FileChooser> chooser;
juce::File tempVideoFile;
void initialiseBrowser(); void initialiseBrowser();
void resetBuffer(); void resetBuffer();