transavormer
Version:
Transform (transcode, transmux, etc) audio/video formats using libav.js and WebCodecs
94 lines (88 loc) • 3.29 kB
text/typescript
/*
* Copyright (c) 2024 Yahweasel
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
import * as ifs from "./interfaces";
/**
* Get the stream→stream mapping for this set of streams and this selection.
*/
export function mkMapping(
streams: ifs.StreamParameters[],
selectionIn: ifs.Selection | ifs.Selection[]
) {
// Canonicalize the selection
const selection: ifs.SelectionFull[] = [];
const selectionArr: ifs.Selection[] =
((<ifs.Selection[]> selectionIn).length)
? (<ifs.Selection[]> selectionIn) : [<ifs.Selection> selectionIn];
for (const sel of selectionArr) {
if (typeof sel === "number") {
selection.push({
type: "all",
selection: sel
});
} else if (typeof sel === "string") {
let sel0 = sel[0];
let sel1 = sel;
if (sel0 === "v" || sel[0] === "a")
sel1 = sel.slice(1);
selection.push({
type: (sel0 === "v") ? "video" :
(sel0 === "a") ? "audio" :
"all",
selection: (sel1.length) ? +sel1 : "all"
});
} else {
selection.push(sel);
}
}
// And make the mapping
const ret: number[] = Array(streams.length).fill(-1);
let outCount = 0;
for (const sel of selection) {
if (sel.selection === "none") continue;
if (sel.selection === "all") {
// Map everything (of some type)
for (let i = 0; i < ret.length; i++) {
if (ret[i] >= 0) continue;
if (
sel.type === "all" ||
(streams[i].codec_type === 0 /* video */ && sel.type === "video") ||
(streams[i].codec_type === 1 && sel.type === "audio")
) {
ret[i] = outCount++;
}
}
continue;
}
// Otherwise, we have to actually look for the appropriate index
let idx = 0;
for (let i = 0; i < ret.length; i++) {
if (
sel.type === "all" ||
(streams[i].codec_type === 0 && sel.type === "video") ||
(streams[i].codec_type === 1 && sel.type === "audio")
) {
if (idx === sel.selection) {
// Choose this one
if (ret[i] < 0)
ret[i] = outCount++;
break;
}
idx++;
}
}
}
return ret;
}