uniapp开发的app中需要使用海康威视播放视频流
第一步:
去官网https://open.hikvision.com/download/5c67f1e2f05948198c909700?type=20下载相关的SD
因为我是使用uniapp开发的app,选择下载了H5视频播放器开发包V2.5.1,同时它会有相关的demo下载,功能还是比较全的
第二步:
运行demo

第三步:将相关的js文件SDK放在项目中

在项目中引入:
javascript
<script module="vedio" lang="renderjs">
export default {
data() {
return {
playData: [],
player: null,
accessToken: null,
playerSdkLoaded: false, // SDK是否加载完成
isPlayerReady: false, // 标记播放器是否初始化完成(新增)
JSPlugin: null // 缓存SDK实例,避免重复加载(新增)
}
},
mounted() {
const that = this;
// 先修复removeEventListener空指针问题(关键)
this.fixRemoveEventListener();
// 只加载一次SDK,缓存到JSPlugin
import('@/static/js/h5player.min.js').then(res => {
console.log(res, 'SDK加载完成');
that.JSPlugin = res.JSPlugin;
that.playerSdkLoaded = true;
// 初始化播放器(首次加载)
that.initPlayer();
}).catch(err => {
console.error('SDK加载失败:', err);
})
},
beforeDestroy() {
// 页面销毁时彻底销毁播放器
this.destroyPlayer().then(() => {
this.player = null;
this.isPlayerReady = false;
this.JSPlugin = null;
});
},
methods: {
// 修复removeEventListener空指针(核心)
fixRemoveEventListener() {
const originalRemove = EventTarget.prototype.removeEventListener;
EventTarget.prototype.removeEventListener = function(type, listener, options) {
if (this) { // 仅当当前对象存在时执行
try {
originalRemove.call(this, type, listener, options);
} catch (err) {
if (err.message.includes('removeEventListener')) {
console.warn('解绑事件忽略:', type);
} else {
throw err;
}
}
}
};
},
// 切换播放地址(核心改造)
async changePlayUrl(newUrl, oldUrl, instance) {
if (!newUrl || newUrl === oldUrl) return; // 空地址/相同地址不处理
console.log('切换流地址:', newUrl);
// 1. 先彻底销毁旧播放器
await this.destroyPlayer();
// 2. 确保SDK已加载,重新初始化播放器
if (!this.JSPlugin) {
console.error('SDK未加载完成');
return;
}
await this.initPlayer();
// 3. 播放器初始化完成后立即播放(取消setTimeout,改用实例就绪判断)
if (this.player && this.isPlayerReady) {
this.player.JS_Play(newUrl, {
playURL: newUrl,
mode: 0,
PlayBackMode: 1,
keepDecoder: 0
}, 0).then(res => {
console.log('播放成功:', res);
}).catch(err => {
console.error('播放失败:', err);
// H.265解码失败时降级处理(可选)
if (err.message.includes('h265')) {
uni.showToast({
title: 'H.265解码失败,请切换H.264流',
icon: 'none'
});
}
});
}
},
// 销毁播放器(Promise封装,确保彻底)
destroyPlayer() {
return new Promise(resolve => {
if (this.player && this.isPlayerReady) {
try {
this.player.JS_Stop(); // 先停止播放(海康标准方法)
this.player.off(); // 解绑事件
this.player.destroy(); // 销毁实例
// 清空容器DOM,避免残留
const container = document.getElementById('video-container');
if (container) container.innerHTML = '';
} catch (err) {
console.warn('销毁播放器错误:', err);
} finally {
this.player = null;
this.isPlayerReady = false;
resolve();
}
} else {
resolve();
}
});
},
// 全屏播放
wholeFullScreen() {
if (!this.player) return;
this.player.JS_FullScreenDisplay(true).then(() => {
console.log('全屏成功');
}).catch(e => {
console.error('全屏失败:', e);
})
},
// 初始化播放器(锁定软解,稳化解码)
initPlayer() {
return new Promise((resolve) => {
if (!this.JSPlugin) {
resolve(false);
return;
}
try {
const my_player = new this.JSPlugin({
szId: 'video-container', // 容器ID
szBasePath: "/static/js/", // SDK路径
iMaxSplit: 1, // 移动端只需要1路播放,减少性能消耗
openDebug: false, // 关闭debug,减少日志干扰
mseWorkerEnable: true, // 开启多线程解码,提升软解性能
bSupporDoubleClickFull: true,
// ========== 核心:锁定软解,避免H.265硬解不稳定 ==========
decodeType: 'soft', // 强制软解(关键!放弃auto硬解)
enableSoftDecode: true, // 显式开启软解
supportH265: true,
isFlushURI: true, // 切换流清空URI缓存
reconnectTimes: 3, // 解码失败重连
reconnectInterval: 2000,
// ========== 移动端适配 ==========
renderType: 'canvas', // canvas渲染更兼容
lowLatency: false, // 关闭低延迟,换稳定性
maxBufferLength: 5, // 降低缓冲,减少内存占用
});
// 绑定错误回调,捕获解码异常
my_player.JS_SetWindowControlCallback({
pluginErrorHandler: (iWndIndex, iErrorCode, oError) => {
console.error('播放器错误:', iWndIndex, iErrorCode, oError);
if (oError && oError.message.includes('h265')) {
this.isPlayerReady = false;
}
},
firstFrameDisplay: (iWndIndex, iWidth, iHeight) => {
console.log('首帧显示:', iWndIndex, iWidth, iHeight);
this.isPlayerReady = true; // 首帧显示标记就绪
},
performanceLack: (iWndIndex) => {
console.warn('性能不足:', iWndIndex);
}
});
this.player = my_player;
this.isPlayerReady = true; // 标记初始化完成
resolve(true);
} catch (err) {
console.error('初始化播放器失败:', err);
this.isPlayerReady = false;
resolve(false);
}
});
},
// 截取设备序号和通道号(保留)
getHashParts(str) {
const parts = str.split("#");
return {
before: parts[0],
after: parts.length > 1 ? parts[1] : "",
};
}
},
}
</script>
在项目中也遇到了很多问题,也都一一解决了:
1:因为开发的app,在浏览器的手机模拟器能够播放,但是在真机运行的时候提示JSPlugin没有定义
后来经过调整,查资料是因为js文件引入没有加载成功,后来就改变了引入方式,变成这样

2:因为是多个视频流进行切换,在切换的时候会出现这样的问题,原因是实例未销毁

3:在切换的时候会出现[H5player]-%c2025-12-08 10:57:44.823%c-Error: color: blue color: black VideoDecoder not support h265: at app-view.js:45399,导致播放不出来,以下是解决办法
在 UniApp 中使用海康威视 H5 播放器切换视频流时出现 [H5player] VideoDecoder not support h265 错误,核心原因是移动端浏览器 / 设备不支持 H.265(HEVC)解码 ,且海康威视 H5 播放器默认未启用兼容降级策略。以下是分维度的解决方案,从「解码兼容」「流格式转换」「播放器配置」三个层面彻底解决:
一、核心问题定位
H.265(HEVC)是高效视频编码格式,但移动端存在两大兼容问题:
- 硬件层面:中低端安卓 /iOS 设备的视频解码芯片不支持 H.265 硬解;
- 浏览器层面 :移动端 Chrome/Safari 等浏览器的
VideoDecoderAPI(WebCodecs)对 H.265 支持极差,仅部分高版本安卓设备兼容; - 播放器层面:海康 H5 播放器默认优先使用硬解,未检测到 H.265 支持时直接报错,未自动降级为软解 / 转码。

以上就是我使用海康威视的经验分享,大家如果有相同的问题或者其它好的经验,可以评论区讨论哦