#2895·plyr

使用 plyr 和 nextjs 播放视频;收到 AbortError: play() 请求被 pause() 调用中断

作者: PaulNgo-BlueOC创建于 2026年5月16日更新于 2026年5月16日

// ── Plyr initialisation ────────────────────────────────────────────────────

useEffect(() => { const video = videoRef.current; if (!video) return;

// Dynamic import: Plyr reads document at module load, which crashes SSR. let destroyed = false; void (async () => { const [{ default: Plyr }] = await Promise.all([ import("plyr"), import("plyr/dist/plyr.css"), ]); if (destroyed) return;

const player = new Plyr(video, {
  controls: [
    "play",
    "progress",
    "current-time",
    "duration",
    "mute",
    "volume",
    "settings",
    "fullscreen",
  ],
  settings: ["speed"],
  speed: { selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 2] },
  clickToPlay: false,
  disableContextMenu: true,
  keyboard: { focused: true, global: false },
  tooltips: { controls: true, seek: true },
  i18n: {
    speed: "Tốc độ",
    normal: "Bình thường",
    quality: "Chất lượng",
    loop: { start: "Bắt đầu", end: "Kết thúc", all: "Tất cả", reset: "Đặt lại", none: "Không" },
  },
});
plyrRef.current = player;

})();

return () => { destroyed = true; if (plyrRef.current) { plyrRef.current.destroy(); plyrRef.current = null; } }; }, []);

const startPlayback = useCallback(async () => { const video = videoRef.current; if (!video) return;

const ms = new MediaSource(); mediaSourceRef.current = ms; video.src = URL.createObjectURL(ms);

ms.addEventListener("sourceopen", async () => { try { // const sb = ms.addSourceBuffer("video/mp4; codecs="avc1.640020,mp4a.40.2""); const sb = ms.addSourceBuffer("video/webm; codecs="vp9,opus""); await sb.addEventListener("loadedmetadata", () => { plyrRef.current.play(); }); } catch (e) { setState({ status: "error", message: e.message }); } }); }, []);

return (

);