40 lines
2.6 KiB
TypeScript
40 lines
2.6 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import crypto from "node:crypto";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const root = path.resolve(import.meta.dirname, "../../..");
|
|
const fixture = fs.readFileSync(path.join(root, "tests/files/web/media/sequencer-probe.mp4"));
|
|
const sourceSha256 = crypto.createHash("sha256").update(fixture).digest("hex");
|
|
|
|
test("WBV2-P1128-000 probes and decodes a movie through the local ffmpeg.wasm Worker", async ({ page }) => {
|
|
test.setTimeout(120_000);
|
|
await page.goto("/");
|
|
const result = await page.evaluate(async ({ bytes, sourceSha256 }) => {
|
|
const [{ probeSequencerCodec, probeSequencerMovieCodecWithFallback }, cache] = await Promise.all([
|
|
import("/src/sequencer/SequencerCodecProbe.ts"),
|
|
import("/src/sequencer/SequencerMediaProxyCache.ts"),
|
|
]);
|
|
const source = Uint8Array.from(bytes).buffer;
|
|
const request = { schemaVersion: 1 as const, stripType: "MOVIE" as const, mimeType: "video/mp4", byteLength: source.byteLength, sourceSha256 };
|
|
const browser = await probeSequencerCodec(request, source);
|
|
const capability = await probeSequencerMovieCodecWithFallback(request, source);
|
|
const frame = await cache.generateInitialSequencerMovieProxyFrame(request, capability, { kind: "MOVIE_RGBA8_FRAME", width: 8, height: 8, colorSpace: "SRGB8", alphaMode: "STRAIGHT" }, source);
|
|
const corrupt = new Uint8Array(source.slice(0));
|
|
corrupt.fill(0, 0, Math.min(32, corrupt.length));
|
|
const corruptHash = Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256", corrupt)), (value) => value.toString(16).padStart(2, "0")).join("");
|
|
const corruptResult = await probeSequencerMovieCodecWithFallback({ ...request, sourceSha256: corruptHash }, corrupt.buffer);
|
|
const cancellation = new AbortController();
|
|
cancellation.abort();
|
|
const cancelled = await probeSequencerMovieCodecWithFallback(request, source, cancellation.signal).then(() => false).catch((error) => error?.name === "AbortError");
|
|
return { browser, capability, frameBytes: frame.data.byteLength, frameManifest: frame.manifest, corrupt: { status: corruptResult.status, reason: corruptResult.reason }, cancelled };
|
|
}, { bytes: Array.from(fixture), sourceSha256 });
|
|
|
|
expect(result.browser.status).toBe("BLOCKED");
|
|
expect(result.capability).toMatchObject({ status: "READY", backend: "FFMPEG_WASM", decoded: { width: 16, height: 16, durationMicros: 1_000_000 } });
|
|
expect(result.frameBytes).toBe(8 * 8 * 4);
|
|
expect(result.frameManifest.decodeCapability).toEqual(result.capability);
|
|
expect(result.corrupt).toEqual({ status: "BLOCKED", reason: "DECODE_FAILED" });
|
|
expect(result.cancelled).toBe(true);
|
|
});
|