web: move libav.ts to its own directory

This commit is contained in:
dumbmoron 2024-08-19 07:49:20 +00:00
parent bce5f789d7
commit 1072cf1e05
No known key found for this signature in database

View file

@ -1,9 +1,11 @@
import mime from "mime"; import mime from "mime";
import LibAV, { type LibAV as LibAVInstance, type Packet, type Stream } from "@imput/libav.js-encode-cli"; import LibAV, { type LibAV as LibAVInstance, type Packet, type Stream } from "@imput/libav.js-encode-cli";
import type { Chunk, ChunkMetadata, Decoder, FFmpegProgressCallback, FFmpegProgressEvent, FFmpegProgressStatus, FileInfo, OutputStream, RenderingPipeline, RenderParams } from "./types/libav"; import type { Chunk, ChunkMetadata, Decoder, FFmpegProgressCallback, FFmpegProgressEvent, FFmpegProgressStatus, FileInfo, OutputStream, RenderingPipeline, RenderParams } from "../types/libav";
import type { FfprobeData } from "fluent-ffmpeg"; import type { FfprobeData } from "fluent-ffmpeg";
import * as LibAVWebCodecs from "libavjs-webcodecs-bridge"; import * as LibAVWebCodecs from "libavjs-webcodecs-bridge";
import { BufferStream } from "./buffer-stream"; import { BufferStream } from "./buffer-stream";
import { BufferStream } from "../buffer-stream";
import WebCodecsWrapper from "./webcodecs";
import { browser } from "$app/environment"; import { browser } from "$app/environment";
const QUEUE_THRESHOLD_MIN = 16; const QUEUE_THRESHOLD_MIN = 16;
@ -11,11 +13,13 @@ const QUEUE_THRESHOLD_MAX = 128;
export default class LibAVWrapper { export default class LibAVWrapper {
libav: Promise<LibAVInstance> | null; libav: Promise<LibAVInstance> | null;
webcodecs: WebCodecsWrapper | null;
concurrency: number; concurrency: number;
onProgress?: FFmpegProgressCallback; onProgress?: FFmpegProgressCallback;
constructor(onProgress?: FFmpegProgressCallback) { constructor(onProgress?: FFmpegProgressCallback) {
this.libav = null; this.libav = null;
this.webcodecs = null;
this.concurrency = Math.min(4, browser ? navigator.hardwareConcurrency : 0); this.concurrency = Math.min(4, browser ? navigator.hardwareConcurrency : 0);
this.onProgress = onProgress; this.onProgress = onProgress;
} }
@ -26,6 +30,8 @@ export default class LibAVWrapper {
yesthreads: true, yesthreads: true,
base: '/_libav' base: '/_libav'
}); });
this.webcodecs = new WebCodecsWrapper(await this.libav);
} }
} }
@ -38,11 +44,16 @@ export default class LibAVWrapper {
async #get() { async #get() {
if (!this.libav) throw new Error("LibAV wasn't initialized"); if (!this.libav) throw new Error("LibAV wasn't initialized");
return await this.libav; if (!this.webcodecs) throw new Error("unreachable");
return {
libav: await this.libav,
webcodecs: this.webcodecs
};
} }
async probe(blob: Blob) { async probe(blob: Blob) {
const libav = await this.#get(); const { libav } = await this.#get();
await libav.mkreadaheadfile('input', blob); await libav.mkreadaheadfile('input', blob);
@ -81,7 +92,7 @@ export default class LibAVWrapper {
} }
async remux({ blob, output, args }: RenderParams) { async remux({ blob, output, args }: RenderParams) {
const libav = await this.#get(); const { libav } = await this.#get();
const inputKind = blob.type.split("/")[0]; const inputKind = blob.type.split("/")[0];
const inputExtension = LibAVWrapper.getExtensionFromType(blob); const inputExtension = LibAVWrapper.getExtensionFromType(blob);
@ -194,7 +205,7 @@ export default class LibAVWrapper {
} }
async transcode(blob: Blob) { async transcode(blob: Blob) {
const libav = await this.#get(); const { libav } = await this.#get();
let fmtctx; let fmtctx;
await libav.mkreadaheadfile('input', blob); await libav.mkreadaheadfile('input', blob);
@ -310,7 +321,7 @@ export default class LibAVWrapper {
} }
async #processChunk({ chunk, metadata }: { chunk: Chunk, metadata: ChunkMetadata }, ostream: OutputStream, index: number) { async #processChunk({ chunk, metadata }: { chunk: Chunk, metadata: ChunkMetadata }, ostream: OutputStream, index: number) {
const libav = await this.#get(); const { libav } = await this.#get();
let convertToPacket; let convertToPacket;
if (chunk instanceof EncodedVideoChunk) { if (chunk instanceof EncodedVideoChunk) {
@ -323,7 +334,7 @@ export default class LibAVWrapper {
} }
async #mux(pipes: RenderingPipeline[], ostreams: OutputStream[]) { async #mux(pipes: RenderingPipeline[], ostreams: OutputStream[]) {
const libav = await this.#get(); const { libav } = await this.#get();
const write_pkt = await libav.av_packet_alloc(); const write_pkt = await libav.av_packet_alloc();
let writer_ctx = 0, output_ctx = 0; let writer_ctx = 0, output_ctx = 0;
@ -414,7 +425,7 @@ export default class LibAVWrapper {
} }
async* #demux(fmt_ctx: number) { async* #demux(fmt_ctx: number) {
const libav = await this.#get(); const { libav } = await this.#get();
const read_pkt = await libav.av_packet_alloc(); const read_pkt = await libav.av_packet_alloc();
try { try {
@ -442,7 +453,7 @@ export default class LibAVWrapper {
} }
async #createEncoder(stream: Stream, codec: string) { async #createEncoder(stream: Stream, codec: string) {
const libav = await this.#get(); const { libav } = await this.#get();
let streamToConfig, configToStream, Encoder; let streamToConfig, configToStream, Encoder;
@ -502,16 +513,16 @@ export default class LibAVWrapper {
} }
async #createDecoder(stream: Stream) { async #createDecoder(stream: Stream) {
const libav = await this.#get(); const { libav } = await this.#get();
let streamToConfig, Decoder; let streamToConfig, initDecoder;
if (stream.codec_type === libav.AVMEDIA_TYPE_VIDEO) { if (stream.codec_type === libav.AVMEDIA_TYPE_VIDEO) {
streamToConfig = LibAVWebCodecs.videoStreamToConfig; streamToConfig = LibAVWebCodecs.videoStreamToConfig;
Decoder = VideoDecoder; initDecoder = this.webcodecs.initVideoDecoder;
} else if (stream.codec_type === libav.AVMEDIA_TYPE_AUDIO) { } else if (stream.codec_type === libav.AVMEDIA_TYPE_AUDIO) {
streamToConfig = LibAVWebCodecs.audioStreamToConfig; streamToConfig = LibAVWebCodecs.audioStreamToConfig;
Decoder = AudioDecoder; initDecoder = this.webcodecs.initAudioDecoder;
} else throw "Unknown type: " + stream.codec_type; } else throw "Unknown type: " + stream.codec_type;
const config = await streamToConfig(libav, stream); const config = await streamToConfig(libav, stream);