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, { probeMovieWithFFmpeg }] = await Promise.all([ import("/src/sequencer/SequencerCodecProbe.ts"), import("/src/sequencer/SequencerMediaProxyCache.ts"), import("/src/sequencer/FFmpegMovieProbe.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 automatic = await probeSequencerMovieCodecWithFallback(request, source); const capability = await probeMovieWithFFmpeg(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"); const running = new AbortController(); const pending = probeSequencerMovieCodecWithFallback(request, source, running.signal); running.abort(); const cancelledDuringProbe = await pending.then(() => false).catch((error) => error?.name === "AbortError"); return { browser, automatic, capability, frameBytes: frame.data.byteLength, frameManifest: frame.manifest, corrupt: { status: corruptResult.status, reason: corruptResult.reason }, cancelled, cancelledDuringProbe }; }, { bytes: Array.from(fixture), sourceSha256 }); expect(result.automatic).toMatchObject({ status: "READY", backend: result.browser.status === "READY" ? "HTML_MEDIA" : "FFMPEG_WASM", decoded: { width: 16, height: 16, durationMicros: 1_000_000 } }); 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); expect(result.cancelledDuringProbe).toBe(true); });