Files
xsh-assistant-next/composables/useVideoSubtitleEmbedding.ts

79 lines
1.6 KiB
TypeScript

import {
Combinator,
EmbedSubtitlesClip,
MP4Clip,
OffscreenSprite,
} from "@webav/av-cliper";
export interface SubtitleEmbeddingOptions {
color?: string;
textBgColor?: string | null;
type?: "srt";
fontFamily?: string;
fontSize?: number;
letterSpacing?: string | null;
bottomOffset?: number;
strokeStyle?: string;
lineWidth?: number | null;
lineCap?: CanvasLineCap | null;
lineJoin?: CanvasLineJoin | null;
textShadow?: {
offsetX: number;
offsetY: number;
blur: number;
color: string;
};
videoWidth?: number;
videoHeight?: number;
}
export const useVideoSubtitleEmbedding = async (
videoUrl: string,
srtUrl: string,
options?: SubtitleEmbeddingOptions
) => {
if (!options) {
options = {
videoWidth: 1920,
videoHeight: 1080,
};
}
const videoSprite = new OffscreenSprite(
new MP4Clip((await fetch(videoUrl)).body!)
);
videoSprite.time = { duration: 10e6, offset: 0 };
const srtSprite = new OffscreenSprite(
new EmbedSubtitlesClip(await (await fetch(srtUrl)).text(), {
videoWidth: 1920,
videoHeight: 1080,
fontSize: 36,
fontFamily: "Noto Sans SC",
strokeStyle: "none",
textShadow: {
offsetX: 2,
offsetY: 2,
blur: 4,
color: "rgba(0, 0, 0, 0.25)",
},
...options,
})
);
srtSprite.time = { duration: 10e6, offset: 0 };
const combinator = new Combinator({
width: 1920,
height: 1080,
});
await combinator.addSprite(videoSprite);
await combinator.addSprite(srtSprite);
const srcBlob = URL.createObjectURL(
await new Response(combinator.output()).blob()
);
return srcBlob;
};