播放器使用
playerInstance = new Player({
el: playerRef.value,
url,
autoplay: false,
startTime: normalizeProgressTime(currentPlaybackTime.value),
marginControls: true,
// 保持固定的 16:9 容器,避免 fixed 尺寸与 CSS 的 100% 宽度相互覆盖。
// fluid: true,
// width: 16,
// height: 9,
// fitVideoSize: "fixed",
// videoFillMode: "contain",
// 原生支持 HLS 的浏览器直接播放;其他浏览器通过 MSE/HLS 插件播放。
fluid: false,
fitVideoSize: "fixWidth",
videoFillMode: "fillHeight",
plugins: useHlsPlugin ? [HlsPlugin] : [],
playbackRate: [0.5, 1, 1.5, 2],
defaultPlaybackRate: 1,
// 原生全屏整个水印外层:不改变播放器的全屏模式,同时让桌面端水印保留。
// iOS Safari 的系统视频全屏只呈现 video 元素,受浏览器限制无法叠加网页水印。
fullscreenTarget: watermarkRef.value,
// fullscreen: { useCssFullscreen: true },
hls: {
fetchOptions: {
// 仅给解密 key 接口附带登录凭证,避免 COS 的 m3u8/分片请求
// 因 Authorization 触发跨域预检而失败。
transformRequest(request) {
const isKeyRequest = request.url.includes("/training/getKey");
if (isKeyRequest && accessToken) {
request.headers = {
...(request.headers || {}),
Authorization: `Bearer ${accessToken}`,
};
}
// 仅用于本地排查:不输出 token 或 key 内容。
if (isKeyRequest) {
console.debug("[HLS key request]", {
viaPlugin: useHlsPlugin,
hasToken: Boolean(accessToken),
hasAuthorization: Boolean(request.headers?.Authorization),
});
}
return request;
},
},
},
});