lossless-cut/public/canvasPlayer.js

67 wiersze
1.7 KiB
JavaScript

const strtok3 = require('strtok3');
const { getOneRawFrame, encodeLiveRawStream } = require('./ffmpeg');
let aborters = [];
async function command({ path, inWidth, inHeight, streamIndex, seekTo: commandedTime, onFrame, playing }) {
let process;
let aborted = false;
function killProcess() {
if (process) {
process.kill();
process = undefined;
}
}
function abort() {
aborted = true;
killProcess();
aborters = aborters.filter(((aborter) => aborter !== abort));
}
aborters.push(abort);
try {
if (playing) {
const { process: processIn, channels, width, height } = encodeLiveRawStream({ path, inWidth, inHeight, streamIndex, seekTo: commandedTime });
process = processIn;
// process.stderr.on('data', data => console.log(data.toString('utf-8')));
const tokenizer = await strtok3.fromStream(process.stdout);
if (aborted) return;
const size = width * height * channels;
const rgbaImage = Buffer.allocUnsafe(size);
while (!aborted) {
// eslint-disable-next-line no-await-in-loop
await tokenizer.readBuffer(rgbaImage, { length: size });
if (aborted) return;
onFrame(rgbaImage, width, height);
}
} else {
const { process: processIn, width, height } = getOneRawFrame({ path, inWidth, inHeight, streamIndex, seekTo: commandedTime, outSize: 1000 });
process = processIn;
const { stdout: rgbaImage } = await process;
if (aborted) return;
onFrame(rgbaImage, width, height);
}
} catch (err) {
if (!err.killed) console.warn(err.message);
} finally {
killProcess();
}
}
function abortAll() {
aborters.forEach((aborter) => aborter());
}
module.exports = {
command,
abortAll,
};