diff --git a/frontend/src/features/optimize/OptimizeModal.tsx b/frontend/src/features/optimize/OptimizeModal.tsx index f4c284b..e2f2ebb 100644 --- a/frontend/src/features/optimize/OptimizeModal.tsx +++ b/frontend/src/features/optimize/OptimizeModal.tsx @@ -9,7 +9,7 @@ import { formatBytes } from "@/lib/format"; import type { MediaItem } from "@/lib/types"; import { estimateVideoBitrate, VIDEO_CODEC_CANDIDATES } from "./bitrate"; -import { probeVideoEncoders, workingCodecs } from "./detect"; +import { browserLabel, probeVideoEncoders, workingCodecs } from "./detect"; import { deleteStoredFile } from "./opfs"; import { DEFAULT_OPTIONS, @@ -196,6 +196,7 @@ export function OptimizeModal({ : "mp4" : options.container; const usableCodecs = workingCodecs(probes, container); + const isFirefox = browserLabel().startsWith("Firefox"); const applyMutation = useMutation({ mutationFn: async () => { @@ -667,14 +668,31 @@ export function OptimizeModal({ work here…
) : usableCodecs.length === 0 ? ( -- This browser cannot produce {container.toUpperCase()} video - samples — switch the container to{" "} - {container === "mp4" ? "WebM" : "MP4"}. -
++ {browserLabel()} cannot produce{" "} + {container.toUpperCase()} video samples + {container === "mp4" && isFirefox + ? " — Firefox does not implement H.264/HEVC encoding" + : ""} + . +
+ +- Encoders:{" "} + {browserLabel()} · encoders:{" "} {probes .map( (probe) => diff --git a/frontend/src/features/optimize/detect.ts b/frontend/src/features/optimize/detect.ts index 1844c17..dbdc0e8 100644 --- a/frontend/src/features/optimize/detect.ts +++ b/frontend/src/features/optimize/detect.ts @@ -137,3 +137,23 @@ export function workingCodecs( .map((probe) => probe.codec) .filter((codec) => candidates.includes(codec)); } + +/** Human-readable browser + platform, for the encoder diagnostics line. */ +export function browserLabel(): string { + const ua = navigator.userAgent; + const patterns: [RegExp, string][] = [ + [/(Firefox|FxiOS)\/([\d.]+)/, "Firefox"], + [/(Edg|EdgA|EdgiOS)\/([\d.]+)/, "Edge"], + [/(OPR)\/([\d.]+)/, "Opera"], + [/(Chrome|CriOS)\/([\d.]+)/, "Chrome"], + [/(Version)\/([\d.]+)[^)]*Safari/, "Safari"], + ]; + for (const [pattern, name] of patterns) { + const match = pattern.exec(ua); + if (match) { + const version = match[2]?.split(".")[0] ?? ""; + return `${name}${version ? ` ${version}` : ""}`; + } + } + return "unknown browser"; +}