@nxtedition/ffmpeg
Advanced tools
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAKnD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,GAChD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB;AAGD,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,aAInD;AAID,wBAAgB,gBAAgB,CAAC,EAAE,GAAG,IAAI,EAAE;;CAAA,UAO3C;AAID,wBAAgB,gBAAgB,CAC9B,GAAG,OAAO,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC,GACzD,MAAM,CAER;AAeD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;CAAa,GACzD;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,GAAG,SAAS,CAWxC;AAGD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;CACZ,CAOA;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAEjD"} |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} |
+1
-0
@@ -23,1 +23,2 @@ import type { Duplex, Readable } from 'node:stream'; | ||
| export declare function parseLogs(lines: Readable): Duplex; | ||
| //# sourceMappingURL=index.d.ts.map |
+48
-75
@@ -1,95 +0,68 @@ | ||
| import split2 from 'split2' | ||
| import split2 from 'split2'; | ||
| // To assign stream specifiers to options. | ||
| // { 'c:v': k }, { v: id } => { 'c:v:id': k } | ||
| export function applyStreamSpecifiers( | ||
| params , | ||
| streamIds , | ||
| ) { | ||
| return Object.fromEntries( | ||
| Object.entries(params) | ||
| .map(([key, value]) => { | ||
| const [name, type] = key.split(':') | ||
| export function applyStreamSpecifiers(params, streamIds) { | ||
| return Object.fromEntries(Object.entries(params) | ||
| .map(([key, value]) => { | ||
| const [name, type] = key.split(':'); | ||
| if (!type) { | ||
| return [key, value] | ||
| return [key, value]; | ||
| } | ||
| return streamIds[type] != null ? [`${name}:${type}:${streamIds[type]}`, value] : null | ||
| }) | ||
| .filter((x) => x !== null), | ||
| ) | ||
| return streamIds[type] != null ? [`${name}:${type}:${streamIds[type]}`, value] : null; | ||
| }) | ||
| .filter((x) => x !== null)); | ||
| } | ||
| // { foo: x, bar: y } => [ -foo x -bar y ] | ||
| export function toArgv(args ) { | ||
| return Object.entries(args) | ||
| .filter(([k, v]) => v != null) | ||
| .flatMap(([k, v]) => [`-${k}`, v]) | ||
| export function toArgv(args) { | ||
| return Object.entries(args) | ||
| .filter(([k, v]) => v != null) | ||
| .flatMap(([k, v]) => [`-${k}`, v]); | ||
| } | ||
| // To be used with ffmpeg filter options or tee output. | ||
| // { foo: x, bar: y } => foo=x:bar=y | ||
| export function formatFilterArgs({ ...rest }) { | ||
| return Object.entries(rest) | ||
| .filter(([k, v]) => v !== null) | ||
| .map(([key, value]) => | ||
| String(value).includes(':') ? `${key}=\\'${value}\\'` : `${key}=${value}`, | ||
| ) | ||
| .join(':') | ||
| return Object.entries(rest) | ||
| .filter(([k, v]) => v !== null) | ||
| .map(([key, value]) => String(value).includes(':') ? `${key}=\\'${value}\\'` : `${key}=${value}`) | ||
| .join(':'); | ||
| } | ||
| // To be used with ffmpeg tee output. | ||
| // [ { out: x, foo: a }, { out: y, bar: b } ] => '[foo=a]x| [bar=b]y' | ||
| export function formatTeeOutputs( | ||
| ...outputs | ||
| ) { | ||
| return outputs.map(({ out, ...opts }) => `[${formatFilterArgs(opts)}]${out}`).join('| ') | ||
| export function formatTeeOutputs(...outputs) { | ||
| return outputs.map(({ out, ...opts }) => `[${formatFilterArgs(opts)}]${out}`).join('| '); | ||
| } | ||
| const statCast = { | ||
| frame: parseInt, | ||
| fps: parseFloat, | ||
| q: parseFloat, | ||
| // size: TODO, | ||
| // time: TODO, | ||
| // bitrate: TODO, | ||
| dup: parseInt, | ||
| drop: parseInt, | ||
| speed: parseFloat, | ||
| } | ||
| frame: parseInt, | ||
| fps: parseFloat, | ||
| q: parseFloat, | ||
| // size: TODO, | ||
| // time: TODO, | ||
| // bitrate: TODO, | ||
| dup: parseInt, | ||
| drop: parseInt, | ||
| speed: parseFloat, | ||
| }; | ||
| // Parse ffmpeg progress stats line, e.g. "frame=123 fps=45.6 q=2.3 size=1.2M time=00:01:23.45 bitrate=12.3kbits/s dup=0 drop=0 speed=1.23x" | ||
| export function parseProgressStats( | ||
| line , | ||
| cast = statCast, | ||
| ) { | ||
| if (!/size=.*time=/.test(line)) { | ||
| return | ||
| } | ||
| const stats = {} | ||
| for (const [, key, value] of line.matchAll(/(?:^|\s)([a-z]+)=\s*(\S+)/g)) { | ||
| stats[key] = cast[key] ? cast[key](value) : value | ||
| } | ||
| return stats | ||
| export function parseProgressStats(line, cast = statCast) { | ||
| if (!/size=.*time=/.test(line)) { | ||
| return; | ||
| } | ||
| const stats = {}; | ||
| for (const [, key, value] of line.matchAll(/(?:^|\s)([a-z]+)=\s*(\S+)/g)) { | ||
| stats[key] = cast[key] ? cast[key](value) : value; | ||
| } | ||
| return stats; | ||
| } | ||
| // Parse output "[context @ streamId] [loglevel] msg", where the first part is optional. | ||
| export function parseLogLine(line ) | ||
| { | ||
| const parsed = line.match(/^(?:\[([^\]]+) @ ([^\]]+)\] )?\[([^\]]+)\] (.*)$/) | ||
| if (parsed) { | ||
| const [, context, streamId, loglevel, msg] = parsed | ||
| return { context, streamId, loglevel, msg } | ||
| } | ||
| return { loglevel: 'unknown', msg: line } | ||
| export function parseLogLine(line) { | ||
| const parsed = line.match(/^(?:\[([^\]]+) @ ([^\]]+)\] )?\[([^\]]+)\] (.*)$/); | ||
| if (parsed) { | ||
| const [, context, streamId, loglevel, msg] = parsed; | ||
| return { context, streamId, loglevel, msg }; | ||
| } | ||
| return { loglevel: 'unknown', msg: line }; | ||
| } | ||
| export function parseLogs(lines ) { | ||
| return lines.compose(split2(/[\r\n]+/, (x) => parseLogLine(x))) | ||
| export function parseLogs(lines) { | ||
| return lines.compose(split2(/[\r\n]+/, (x) => parseLogLine(x))); | ||
| } | ||
| //# sourceMappingURL=index.js.map |
+2
-3
| { | ||
| "name": "@nxtedition/ffmpeg", | ||
| "version": "1.0.5", | ||
| "version": "1.0.6", | ||
| "type": "module", | ||
@@ -12,3 +12,3 @@ "main": "lib/index.js", | ||
| "scripts": { | ||
| "build": "rimraf lib && tsc -p tsconfig.build.json && amaroc ./src/index.ts && mv src/index.js lib/", | ||
| "build": "rimraf lib && tsc -p tsconfig.build.json", | ||
| "prepublishOnly": "yarn build", | ||
@@ -22,3 +22,2 @@ "typecheck": "tsc --noEmit", | ||
| "@types/split2": "^4.2.3", | ||
| "amaroc": "^1.0.1", | ||
| "oxlint-tsgolint": "^0.17.0", | ||
@@ -25,0 +24,0 @@ "rimraf": "^6.1.3", |
7829
76.61%5
-16.67%5
66.67%89
-12.75%