UNPKG

yuv-rx

Version:

Reading videos as Rx Observables of decoded frames

85 lines (84 loc) 3.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.yuv4mpegStreamForPath = exports.yuv4mpegStreamForCustomInput = void 0; const child_process_1 = require("child_process"); const rxjs_1 = require("rxjs"); const log_handler_1 = require("./log-handler"); function inputArgs(path, options) { var _a, _b; const params = []; params.push('-flags2', '+showall'); const seekseconds = (_a = options === null || options === void 0 ? void 0 : options.seekSeconds) !== null && _a !== void 0 ? _a : 0; if (seekseconds > 0) { params.push('-ss', seekseconds.toString()); } if (options === null || options === void 0 ? void 0 : options.iFramesOnly) { params.push('-skip_frame', 'nokey'); } params.push('-i', path); const vstream = options === null || options === void 0 ? void 0 : options.videoStream; if (vstream != null) { params.push('-map', `0:v:${vstream}`); } const vframes = (_b = options === null || options === void 0 ? void 0 : options.vframes) !== null && _b !== void 0 ? _b : null; if (vframes != null) { params.push('-vframes', vframes.toString()); } return params; } function outputArgs(pixFmt) { return ['-loglevel', 'error', '-f', 'yuv4mpegpipe', '-pix_fmt', pixFmt !== null && pixFmt !== void 0 ? pixFmt : 'yuv420p', '-strict', '-1', '-threads', '0', '-']; } function yuv4mpeg(path, options) { return [...inputArgs(path, options), ...outputArgs(options === null || options === void 0 ? void 0 : options.pixFmt)]; } function yuv4mpegStream(ffmpeg, args, options) { return new rxjs_1.Observable(subscriber => { var _a; if (options === null || options === void 0 ? void 0 : options.verbose) { console.log('FFMpeg:', ffmpeg); console.log('Arguments:', args.join(' ')); } const handleFfmpegLog = (0, log_handler_1.logHandlerFn)((_a = options === null || options === void 0 ? void 0 : options.ffmpegLogHandler) !== null && _a !== void 0 ? _a : 'none'); let exited = false; const child = (0, child_process_1.spawn)(ffmpeg, args, { stdio: 'pipe' }); child.on('exit', (code, signal) => { exited = true; if (options === null || options === void 0 ? void 0 : options.verbose) { console.log(new Error(`FFMpeg exited with code ${code}, signal ${signal}`)); } if (code != null && code == 0) { if (child.stdout.readableEnded) { subscriber.complete(); } } else { subscriber.error(new Error(`FFMpeg exited with exit code ${code}, signal ${signal}`)); } }); child.stdout.on('end', () => { if (options === null || options === void 0 ? void 0 : options.verbose) { console.log('Output stream ended'); } if (exited) { subscriber.complete(); } }); child.stdout.on('data', data => { if (options === null || options === void 0 ? void 0 : options.verbose) { console.log(`Received data (${data.length} bytes)`); } subscriber.next(data); }); child.stderr.on('data', handleFfmpegLog); return () => child.kill(); }); } function yuv4mpegStreamForCustomInput(ffmpeg, args, options) { return yuv4mpegStream(ffmpeg, [...args, ...outputArgs(options === null || options === void 0 ? void 0 : options.pixFmt)], options); } exports.yuv4mpegStreamForCustomInput = yuv4mpegStreamForCustomInput; function yuv4mpegStreamForPath(ffmpeg, path, options) { return yuv4mpegStream(ffmpeg, yuv4mpeg(path, options), options); } exports.yuv4mpegStreamForPath = yuv4mpegStreamForPath;