kopia lustrzana https://github.com/jameshball/osci-render
Improve recording performance by recording directly to a file
rodzic
f30ac1823e
commit
e7f018932d
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Ładowanie…
Reference in New Issue