web: move libav.ts to its own directory
This commit is contained in:
parent
bce5f789d7
commit
1072cf1e05
1 changed files with 24 additions and 13 deletions
|
@ -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);
|
Loading…
Add table
Add a link
Reference in a new issue