
问题
在vue2项目中使用了xgplayer来进行播放视频,但是只有谷歌浏览器!可以,火狐和edg/360都没有法播放
请添加图片描述
。
新的插件-Jessibuca
除了谷歌其他浏览器用Jessibuca
项目根目录
├── public/
│ └── jessibuca/ # [关键] Jessibuca 播放器核心文件
│ ├── jessibuca.js # 主程序
│ ├── decoder.js # 解码器 Worker
│ └── decoder.wasm # WASM 解码库 (H.265软解核心)
├── src/
│ └── views/
│ └── index.vue # 播放器页面主逻辑
:https://github.com/bosscheng/jessibuca-vue-demo/tree/pro-vue2这个地址可以下载Jessibuca ,注意 我是在dmeo/public里面找到的这3个文件的,且是放在自己项目public下的。
<template>
<div class="app">
<h1>直播播放器演示</h1>
<!-- 使用 xgplayer 容器 (Chrome/Edge 等默认模式) -->
<div v-if="!useJessibuca" id="mse" class="xg-style"></div>
<!-- Jessibuca 容器 (Firefox 兼容模式) -->
<div v-else id="jessibuca-container" class="jessibuca-style"></div>
<!-- 错误提示遮罩 -->
<div v-if="errorMessage" class="error-mask">
<div class="error-content">
<i class="el-icon-warning" style="font-size: 40px; color: #ffba00; margin-bottom: 10px;"></i>
<p>{{ errorMessage }}</p>
<p v-if="useJessibuca" style="font-size: 12px; color: #999; margin-top: 5px;">
软解码模式 (兼容模式) | <a href="#" @click.prevent="retryJessibuca" style="color: #409EFF">点击重试</a>
</p>
</div>
</div>
</div>
</template>
<script>
import Player from "xgplayer";
import FlvPlugin from "xgplayer-flv";
import "xgplayer/dist/index.min.css";
export default {
name: 'App',
data() {
return {
player: null,
jessibucaPlayer: null,
streamId: '34020000001110000003_51070300001310000002',
errorMessage: '',
useJessibuca: false // 替换原有的 isFirefox,避免歧义
}
},
mounted() {
// 策略:仅 Google Chrome 浏览器使用 xgplayer (硬解码),其他所有浏览器使用 Jessibuca (软解码)
const ua = navigator.userAgent;
// 判断是否为 Google Chrome (排除 Edge, Opera 等也包含 Chrome 关键字的浏览器)
const isChrome = ua.indexOf("Chrome") > -1 && ua.indexOf("Edg") === -1 && ua.indexOf("OPR") === -1;
// 如果不是 Chrome,就使用 Jessibuca
this.useJessibuca = !isChrome;
this.$nextTick(() => {
if (this.useJessibuca) {
// 非 Chrome 浏览器: 加载 Jessibuca
this.initJessibuca();
} else {
// Chrome: 加载 xgplayer
this.initPlayer();
}
});
},
beforeDestroy() {
if (this.player) {
this.player.destroy();
this.player = null;
}
if (this.jessibucaPlayer) {
this.jessibucaPlayer.destroy();
this.jessibucaPlayer = null;
}
},
methods: {
retryJessibuca() {
this.errorMessage = '';
this.initJessibuca();
},
// 初始化 Jessibuca (用于 Firefox H.265 软解)
initJessibuca() {
const host = window.location.host;
const url = `http://${host}/proxy/sms/local/live/34020000001110000003_51070300001310000002.flv?expired=20260212190637`;
// 使用本地文件加载 Jessibuca (您已下载到 public/jessibuca 目录)
const localScriptUrl = "/jessibuca/jessibuca.js";
const localDecoderUrl = "/jessibuca/decoder.js";
if (!window.Jessibuca) {
const script = document.createElement('script');
script.src = localScriptUrl;
script.onload = () => {
this.createJessibuca(url, localDecoderUrl);
};
script.onerror = () => {
this.errorMessage = '加载本地 Jessibuca 播放器失败。请确认 public/jessibuca/jessibuca.js 文件存在。';
};
document.body.appendChild(script);
} else {
this.createJessibuca(url, localDecoderUrl);
}
},
createJessibuca(url, decoderUrl) {
if (this.jessibucaPlayer) {
this.jessibucaPlayer.destroy();
this.jessibucaPlayer = null;
}
try {
this.jessibucaPlayer = new window.Jessibuca({
container: document.getElementById('jessibuca-container'),
videoBuffer: 1, // 增加缓存到 1秒
isResize: false,
loadingText: "正在加载 H.265 视频...",
debug: true,
useMSE: false, // 强制关闭 MSE,使用软解码
useWCS: false,
decoder: decoderUrl, // 引用 decoder.js 本地地址
forceNoOffscreen: true, // 兼容性设置
hasAudio: true, // 尝试开启音频
showBandwidth: true, // 显示网速以便调试
operateBtns: {
fullscreen: true,
screenshot: true,
play: true,
},
});
this.jessibucaPlayer.on('error', (error) => {
console.error('Jessibuca error:', error);
// 忽略 fetchError 如果流还在继续 (有时候是虚假报错)
if (error === 'fetchError') {
console.warn('Ignored fetchError, retrying internally...');
return;
}
this.errorMessage = '播放出错: ' + JSON.stringify(error);
});
this.jessibucaPlayer.on('start', () => {
console.log('Jessibuca started playing');
this.errorMessage = '';
});
this.jessibucaPlayer.play(url);
} catch (e) {
console.error(e);
this.errorMessage = '初始化 Jessibuca 失败: ' + e.message;
}
},
initPlayer() {
const host = window.location.host;
// 使用硬编码的 HTTP-FLV 地址 (走本地代理)
const url = `http://${host}/proxy/sms/local/live/34020000001110000003_51070300001310000002.flv?expired=20260212190637`;
console.log('Initializing xgplayer with URL:', url);
if (this.player) {
this.player.destroy();
this.player = null;
}
this.player = new Player({
id: 'mse',
url: url,
isLive: true,
autoplay: true,
autoplayMuted: true, // 自动静音播放,防止浏览器策略阻止
width: '100%',
height: '600px',
volume: 0.6, // 默认音量
plugins: [FlvPlugin], // 启用 FLV 插件
flv: {
retryCount: 3,
retryDelay: 1000,
loadTimeout: 10000,
fetchOptions: {
mode: "cors",
},
// 尝试开启 worker 以提升 H.265 软解性能 (如果支持)
enableWorker: true,
enableStashBuffer: false
},
// 错误处理
error: (err) => {
console.error('xgplayer error:', err);
}
});
// 监听错误事件
this.player.on('error', (err) => {
console.error('Player Error Event:', err);
// 捕获 H.265 不支持的错误 (MediaSource error)
if (err.errorType === 'media' && err.errorCode === 5200) {
this.errorMessage = '该视频格式 (H.265) 在当前浏览器中不受支持。';
if (this.player) {
this.player.destroy(); // 销毁播放器防止持续报错
this.player = null;
}
} else {
this.errorMessage = '播放出错,请检查网络或刷新重试';
}
});
}
}
}
</script>
<style scoped>
.app {
padding: 20px;
max-width: 1200px;
margin: 0 auto;
position: relative;
}
.xg-style {
width: 100%;
background-color: black;
}
.jessibuca-style {
width: 100%;
height: 600px;
background-color: black;
position: relative;
}
.error-mask {
position: absolute;
top: 100px; /* 调整位置使其在播放器区域内 */
left: 0;
right: 0;
height: 600px;
background: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
color: white;
z-index: 100;
}
.error-content {
text-align: center;
}
</style>
实现文档如下
# 视频播放器功能实现文档
## 1. 功能概述
本项目实现了在不同浏览器(Chrome、Edge、Firefox 等)下兼容播放 **H.265 (HEVC)** 编码的 HTTP-FLV 直播流。
由于部分浏览器(如 Firefox、Edge)原生不支持或支持不完善 H.265 硬解码,我们采用了 **"双核"策略**:
- **Google Chrome**: 使用 `xgplayer` (硬解码,性能最佳)。
- **其他浏览器 (Firefox / Edge / Opera 等)**: 使用 `Jessibuca` (WASM 软解码,兼容性最佳)。
## 2. 核心文件结构
项目根目录
├── public/
│ └── jessibuca/ # [关键] Jessibuca 播放器核心文件
│ ├── jessibuca.js # 主程序
│ ├── decoder.js # 解码器 Worker
│ └── decoder.wasm # WASM 解码库 (H.265软解核心)
├── src/
│ └── views/
│ └── index.vue # 播放器页面主逻辑
## 3. 实现逻辑流程
### 3.1 初始化流程 (Mounted)
1. **浏览器检测**: 通过 `navigator.userAgent` 精确判断浏览器类型。
- 判断逻辑:是否包含 "Chrome" 且 **不包含** "Edg" (Edge) 和 "OPR" (Opera)。
2. **分支处理**:
- **是 Google Chrome**: 调用 `initPlayer()` (xgplayer)。
- **是 其他浏览器**: 调用 `initJessibuca()` (Jessibuca)。
### 3.2 Chrome 模式 (xgplayer)
- **依赖库**: `xgplayer`, `xgplayer-flv`。
- **特点**: 利用浏览器原生 MSE (Media Source Extensions) 进行硬解码。
- **配置**: 开启 CORS 模式,自动静音播放。
### 3.3 兼容模式 (Jessibuca)
- **适用对象**: Firefox, Edge, Opera, Safari 等。
- **依赖文件**: `public/jessibuca/*`。
- **原理**:
1. 动态加载 `jessibuca.js`。
2. 创建播放器实例,指定 `decoder: '/jessibuca/decoder.js'`。
3. 设置 `useMSE: false` 强制关闭硬解码,启用 WASM 软解码。
- **注意**: 软解码会消耗更多 CPU 资源,但能确保在不支持 H.265 的浏览器上出画面。
## 4. 常见问题排查
### Q1: 播放器提示 "初始化 Jessibuca 失败"
- **原因**: `public/jessibuca/` 目录下缺少文件,或者服务器无法访问该目录。
- **解决**: 确保 `jessibuca.js`, `decoder.js`, `decoder.wasm` 三个文件都存在且可访问。
### Q2: 画面黑屏但有网速
- **原因**: 可能是音频编码不支持或 CSS 样式冲突。
- **解决**: 代码中已设置 `hasAudio: true` (尝试支持音频);确保容器 `div` 有明确的宽高(如 `height: 600px`)。
### Q3: 跨域错误 (CORS)
- **原因**: 视频流地址不支持跨域。
- **解决**: 代码中使用了本地代理 (`/proxy/...`) 转发请求,确保 `vue.config.js` 中配置了正确的 `proxy` 规则。
## 5. 维护指南
如果将来需要升级播放器:
1. **xgplayer**: 直接 `npm update xgplayer`。
2. **Jessibuca**: 需要手动下载新版文件替换 `public/jessibuca/` 下的内容。
此文档是记录,方便下次使用