motion-graphics-webui / js /recorder.js
Sebastiankay's picture
Upload 20 files
52ae39e verified
const FPS = 30;
let frame = 0;
var chunks = [];
var stream;
var rec;
var track;
function timeout(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function initRecorder() {
stream = document.getElementById('canvasrecord').captureStream(0);
track = stream.getVideoTracks()[0];
if (!track.requestFrame) {
track.requestFrame = () => stream.requestFrame();
}
rec = new MediaRecorder(stream, {
bitsPerSecond: 3200000,
});
rec.ondataavailable = function (evt) {
console.log('chunky');
chunks.push(evt.data);
};
rec.start();
console.log('Recorder has been started');
rec.onstart = function () {
rec.pause();
console.log('start!');
};
}
async function recordFrame() {
console.log(frame);
waitForEvent(rec, 'pause');
//rec.onpause = async function(e) {
// wake up the recorder
rec.resume();
recordAnimate(false, (frame / FPS) * 1000);
//animate(false, (frame/FPS)*1000)
// force write the frame
track.requestFrame();
// wait until our frame-time elapsed
await timeout(1000 / FPS);
// sleep recorder
rec.pause();
//}
}
async function exportRecording() {
rec.stop();
stream.getTracks().forEach((track) => track.stop());
await waitForEvent(rec, 'stop');
return new Blob(chunks);
}
// Record canvas
async function record() {
updateRecordCanvas();
if ($('input[name=radio]:checked').val() == 'image') {
recording = true;
paused = true;
animate(false, currenttime);
const dataURL = canvasrecord.toDataURL({
format: 'png',
});
const link = document.createElement('a');
link.download = 'image.png';
link.href = dataURL;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
recording = false;
} else {
if (!recording) {
recording = true;
paused = true;
recordAnimate(false, (frame / FPS) * 1000);
recording = true;
$('#download-real').html('Rendering...');
$('#download-real').addClass('downloading');
var fps = 60;
var aCtx = new AudioContext();
function audioTimerLoop(callback, frequency) {
var freq = frequency / 1000;
var silence = aCtx.createGain();
silence.gain.value = 0;
silence.connect(aCtx.destination);
onOSCend();
var stopped = false;
function onOSCend() {
osc = aCtx.createOscillator();
osc.onended = onOSCend;
osc.connect(silence);
osc.start(0);
osc.stop(aCtx.currentTime + freq);
callback(aCtx.currentTime);
if (stopped) {
osc.onended = function () {
return;
};
}
}
return function () {
stopped = true;
};
}
var stopAnim = audioTimerLoop(renderAnim, 1000 / fps);
var stream = document
.getElementById('canvasrecord')
.captureStream(fps);
objects.forEach(function (object) {
if (
canvasrecord.getItemById(object.id).get('assetType') &&
canvasrecord.getItemById(object.id).get('assetType') ==
'video'
) {
var audio = $(
canvasrecord.getItemById(object.id).getElement()
)[0];
var audioContext = new AudioContext();
var audioSource =
audioContext.createMediaElementSource(audio);
var audioDestination =
audioContext.createMediaStreamDestination();
audioSource.connect(audioDestination);
stream.addTrack(
audioDestination.stream.getAudioTracks()[0]
);
}
});
if (background_audio != false) {
var audioContext = new AudioContext();
var audioSource =
audioContext.createMediaElementSource(background_audio);
var audioDestination =
audioContext.createMediaStreamDestination();
audioSource.connect(audioDestination);
stream.addTrack(audioDestination.stream.getAudioTracks()[0]);
background_audio.currentTime = 0;
background_audio.play();
}
let chunks = [];
var recorder = new MediaRecorder(stream, {
bitsPerSecond: 3200000,
});
recorder.ondataavailable = (e) => chunks.push(e.data);
recorder.onstop = (e) => {
stopAnim();
downloadRecording(chunks);
animate(false, 0);
$('#seekbar').offset({
left:
offset_left +
$('#inner-timeline').offset().left +
currenttime / timelinetime,
});
canvas.renderAll();
console.log('Finished rendering');
};
recorder.start();
setTimeout(function () {
recorder.stop();
}, duration);
async function renderAnim(time) {
await recordAnimate(time * 1000);
}
}
}
}
/*
initRecorder();
//await timeout(2000)
// draw one frame at a time
while (frame++ < FPS * (duration/1000)) {
await longDraw(); // do the long drawing
await recordFrame(); // record at constant FPS
}
// now all the frames have been drawn
const recorded = await exportRecording(); // we can get our final video file
const a = document.createElement('a');
a.style.display = 'none';
a.href = URL.createObjectURL(recorded);
a.download = "test.webm";
document.body.appendChild(a);
a.click();
recording = false;
currenttime = 0;
animate(false, 0);
$("#seekbar").offset({left:offset_left+$("#inner-timeline").offset().left+(currenttime/timelinetime)});
canvas.renderAll();
resizeCanvas();
if (background_audio != false) {
background_audio.pause();
background_audio = new Audio(background_audio.src)
}
$("#download-real").html("Download");
$("#download-real").removeClass("downloading");
updateRecordCanvas();
// Fake long drawing operations that make real-time recording impossible
function longDraw() {
recordAnimate((frame/FPS)*1000)
return wait(Math.random() * 300)
.then(recordAnimate((frame/FPS)*1000));
}*/
/*
paused = true;
recording = true;
$("#download-real").html("Rendering...");
$("#download-real").addClass("downloading");
var fps = 60;
var aCtx = new AudioContext();
function audioTimerLoop(callback, frequency) {
var freq = frequency / 1000;
var silence = aCtx.createGain();
silence.gain.value = 0;
silence.connect(aCtx.destination);
onOSCend();
var stopped = false;
function onOSCend() {
osc = aCtx.createOscillator();
osc.onended = onOSCend;
osc.connect(silence);
osc.start(0);
osc.stop(aCtx.currentTime + freq);
callback(aCtx.currentTime);
if (stopped) {
osc.onended = function() {
return;
};
}
};
return function() {
stopped = true;
};
}
var stopAnim = audioTimerLoop(renderAnim, 1000/(fps));
var stream = document.getElementById("canvasrecord").captureStream(fps);
objects.forEach(function(object){
if (canvasrecord.getItemById(object.id).get("assetType") && canvasrecord.getItemById(object.id).get("assetType") == "video") {
var audio = $(canvasrecord.getItemById(object.id).getElement())[0];
var audioContext = new AudioContext();
var audioSource = audioContext.createMediaElementSource(audio);
var audioDestination = audioContext.createMediaStreamDestination();
audioSource.connect(audioDestination);
stream.addTrack(audioDestination.stream.getAudioTracks()[0]);
}
})
if (background_audio != false) {
var audioContext = new AudioContext();
var audioSource = audioContext.createMediaElementSource(background_audio);
var audioDestination = audioContext.createMediaStreamDestination();
audioSource.connect(audioDestination);
stream.addTrack(audioDestination.stream.getAudioTracks()[0]);
background_audio.currentTime = 0;
background_audio.play();
}
let chunks = [];
var recorder = new MediaRecorder(stream, {
bitsPerSecond : 3200000,
});
recorder.ondataavailable = e => chunks.push(e.data);
recorder.onstop = e => {
stopAnim();
downloadRecording(chunks);
animate(false, 0);
$("#seekbar").offset({left:offset_left+$("#inner-timeline").offset().left+(currenttime/timelinetime)});
canvas.renderAll();
console.log("Finished rendering")
}
recorder.start();
setTimeout(function() {
recorder.stop();
}, duration)
async function renderAnim(time) {
await animate(false, time*1000);
}
*/
/*
$("#download-real").html("Rendering...");
$("#download-real").addClass("downloading");
// browser check
if (typeof MediaStreamTrackGenerator === undefined || typeof MediaStream === undefined || typeof VideoFrame === undefined) {
console.log('Your browser does not support the web APIs used in this demo');
return;
}
// recording setup
const fps = 60;
const generator = new MediaStreamTrackGenerator({ kind: "video" });
const writer = generator.writable.getWriter();
const stream = new MediaStream();
stream.addTrack(generator);
const recorder = new MediaRecorder(stream, { mimeType: "video/webm" });
recorder.start();
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// animate stuff
console.log('rendering...')
console.log(duration);
for (let i = 0; i < (duration/1000)*fps; i++) {
animate(false, (i/fps)*1000);
const frame = new VideoFrame(document.getElementById("canvasrecord"), {
timestamp: (i / fps)*1000
});
await writer.write(frame);
await timeout(100)
console.log("frame "+(i/fps)*1000);
}
console.log('rendering done');
// stop recording and
recorder.addEventListener("dataavailable", (evt) => {
const a = document.createElement('a');
a.style.display = 'none';
a.href = URL.createObjectURL(evt.data);
a.download = "test.webm";
document.body.appendChild(a);
a.click();
recording = false;
currenttime = 0;
animate(false, 0);
$("#seekbar").offset({left:offset_left+$("#inner-timeline").offset().left+(currenttime/timelinetime)});
canvas.renderAll();
resizeCanvas();
if (background_audio != false) {
background_audio.pause();
background_audio = new Audio(background_audio.src)
}
$("#download-real").html("Download");
$("#download-real").removeClass("downloading");
updateRecordCanvas();
});
recorder.stop();
*/