h265webplayer
h265webplayer
https://github.com/ksvc/h265webplayer
h265webplayer是金山云的Web端H.265视频播放器,该播放器Web SDK让您可以在支持WebAssembly的浏览器上播放MP4格式的点播视频,FLV http-flv协议的直播视频。
支持的功能
1、mp4格式的点播(音频需是aac格式的,其余音频格式待兼容)。
2、flv格式的直播。
兼容性
目前PC端和移动端都可以使用,使用前请使用播放器提供的isSupportH265接口检查是否支持播放条件。
demo 有两种访问方式
mp4 demo 访问方式
1、ks3直接访问,链接如下:
https://ks3-cn-beijing.ksyun.com/ksplayer/h265/mp4_demo/index.html
flv demo 访问方式
1、ks3直接访问,链接如下:
https://ks3-cn-beijing.ksyun.com/ksplayer/h265/outside_demo/v1.1.3/index.html
2、获取压缩包后本地创建服务访问,步骤如下:
播放器Demo压缩包地址
flv demo zip
https://ks3-cn-beijing.ksyun.com/ai-kie/sdk/h265-pc/h265-pc.zip
播放器Demo运行说明
0. 安装npm包管理器
参见:Node.js官网
1. 安装http服务器
npm install http-server -g
2. 启动服务
cd <demo directory>
npm run start
浏览器访问
http://localhost:8000
说明: 请替换页面中的拉流地址进行测试
集成h265解码器有两种方式
1、直接使用金山自研的h265播放器(推荐) 2、基于H265Decoder开发使用
第一种方式:使用h265播放器
token的意义
用于鉴权,验证用户是否拥有访问的权利以及访问的时长
如何获取token
先与商务沟通达成协议后,产品会根据需求提供一个对应的token
h265播放器初始化参数配置
let player = h265js.createPlayer({
isLive: false,
type: 'mp4'
},
{
enableSkipFrame: false,
token: 'f8ce4d1adb97c46f28161a3685232557',
wasmFilePath: 'http://localhost:8000/libqydecoder.wasm',
url: urlInput.value,
timeToDecideWaiting: 50000,
bufferTime: 0,
isShowStatistics: false
},{
audioElement: audioElement,
canvas: canvas,
videoElement: h264VideoEle
});
配置参数说明

播放器支持的方法

播放器支持的属性

播放器支持的事件

获取视频编码格式方法
player.on(h265js.Events.MEDIAINFO, function(event, data){
codec = data.codec;
if (codec === 'avc1') {
// h.264
// 处理h.264视频相关逻辑
} else if (codec === 'hev1') { // h.265
// 处理h.265视频相关逻辑
}
});
播放器控制条功能说明
<div class="ks-controls">
<button class="ks-controls-load" onclick="load()">Load</button>
<button onclick="start()">Start</button>
<button onclick="pause()">Pause</button>
<button class="ks-controls-muted" onclick="muted()" data-type="muted">Muted</button>
<button onclick="fullscreen()">Fullscreen</button>
<input type="text" name="ks-seek-to" value="35"/>
<button onclick="seekto()">SeekTo</button>
<div class="ks-time">
<span class="ks-current">00:00:00</span>
/
<span class="ks-duration">00:00:00</span>
</div>
</div>

控制条功能具体实现逻辑可以参考demo
播放器能力监测

第二种方式:基于H265Decoder解码器
JS接口说明
初始化
import H265Decoder from '<decoder direcotory >/h265decoder.js';
let config = {
wasmFilePath: 'http://localhost:8000/libqydecoder.wasm',
enableSkipFrame: true
};
let decoder;
//加载并编译wasm解码库
H265Decoder.compileWasmInterfaces(config.wasmFilePath, function () {
decoder = new H265Decoder(config);
//设置解码回调
decoder.set_image_callback(onDecodedFrameCallback);
}
向解码器队列送数据
decoder.toBeDecodeQueue.push({
nalu: new Uint8Array(naluData), // naluData 为 ArrayBuffer类型数据
pts: 0, //展示时间戳
isDroppable: false }); // 表示是否可以跳帧
- decoder的toBeDecodeQueue属性为保存待解码数据的数组,需自行控制待解码队列缓冲区的长度,避免内存溢出
- decoder会自动取出toBeDecodeQueue中的数据给底层wasm解码器,并在解码后自动释放传入wasm解码器的待解码数据
设置解码输出图像回调
set_image_callback
decoder.set_image_callback((image) => {
let w = image.get_width(); //获取图像宽度
let h = image.get_height(); //获取图像高度
let pts = image.get_pts(); //获取图像pts时间戳
// let image_data = new Uint8ClampedArray(w * h * 4);
// for (let i = 0; i < w * h; i++) {
// image_data[i * 4 + 3] = 255;
// }
// //转换image中的YUV数据到image_data中的RGB数据
// image.transcode(image_data);
//优化: 直接返回YUV数据
let yuvData = image.getYuvDataNew(); //Uint8Array
});
说明: 解码回调函数的参数image为Image类型,参见h265decoder.js中的定义
其他接口
暂停解码
decoder.pause();
恢复解码
decoder.resume();
检查是否为暂停状态
if(decoder.isPaused()) {}
启动解码器
decoder.start();
说明: 默认情况初始化解码器时会自动调用启动解码器
销毁解码器
decoder.free();
接收累积跳帧数通知
decoder.on('skip_frame, (skippedframecount) => {
console.log(skippedframecount);
});
wasm解码器接口说明
接口函数返回码说明
const qy265decoder = {
QY_OK : (0x00000000), // Success
QY_FAIL : (0x80000001), // Unspecified error
QY_OUTOFMEMORY : (0x80000002), // Ran out of memory
QY_POINTER : (0x80000003), // Invalid pointer
QY_NOTSUPPORTED : (0x80000004),// Not support feature encoutnered
QY_AUTH_INVALID : (0x80000005), // authentication invalid
QY_SEARCHING_ACCESS_POINT : (0x00000001), // in process of searching first access
point
QY_REF_PIC_NOT_FOUND : (0x80000007), // encode complete
QY_NEED_MORE_DATA : (0x00000008), // need more data
QY_BITSTREAM_ERROR : (0x00000009), // detecting bitstream error, can be
ignored
QY_TOKEN_INVALID : (0x0000000A) //token invalid
错误码分为三大类状态:
- 等于0: QY_OK,表示完全正常
- 大于0:虽然当前不能正常解码,但解码器本身并没有出错
- 小于0:解码器本身发生了一些异常和错误
创建解码器
QY265DecoderCreate
let returnCode = _malloc(4); //为返回码分配空间
setValue(returnCode, 0, "i32"); // 返回码设置为0
let decoder = qy265decoder.QY265DecoderCreate(null, token, returnCode);
if(getValue(returnCode, 'i32') === qy265decoder.QY_OK) { /*解码器创建成功*/ }
销毁编码器
QY265DecoderDestroy
qy265decoder.QY265DecoderDestroy(decoder);
- 参数

判断解码输出帧是否有效
QY265DecoderGetFrameValid
let framevalid = qy265decoder.QY265DecoderGetFrameValid(frame);
- 参数
- frame: QY265DecoderGetDecodedFrameEm接口返回的解码输出帧
- 返回值: 解码输出帧是否有效, 1为有效
归还解码输出帧
QY265DecoderReturnDecodedFrame
通知解码器释放该帧占用的相关内存
qy265decoder.QY265DecoderReturnDecodedFrame(decoder, frame);
- 参数
- decoder: 通过QY265DecoderCreate接口创建的解码器实例
- frame:QY265DecoderGetDecodedFrameEm接口返回的解码输出帧
获取解码输出帧的宽度
QY265GetFrameWidth
let width = qy265decoder.QY265GetFrameWidth(frame, 0);
- 参数
- frame:QY265DecoderGetDecodedFrameEm接口返回的解码输出帧
- 返回值: 解码输出帧的宽度
获取解码输出帧的高度
QY265GetFrameHeight
let height = qy265decoder.QY265GetFrameHeight(frame, 0);
- 参数
- frame:QY265DecoderGetDecodedFrameEm接口返回的解码输出帧
- 返回值: 解码输出帧的高度
获取解码输出帧的显示时间戳
QY265GetFramePts
let pts = qy265decoder.QY265GetFramePts(frame, 0);
- 参数
- frame:QY265DecoderGetDecodedFrameEm接口返回的解码输出帧
- 返回值: 解码输出帧的显示时间戳
获取解码输出帧的YUV某个分量 QY265DecoderGetFramePlane
let stride = _malloc(2);
let y = qy265decoder.QY265DecoderGetFramePlane(frame, 0, stride);
let u = qy265decoder.QY265DecoderGetFramePlane(frame, 1, stride);
let v = qy265decoder.QY265DecoderGetFramePlane(frame, 2, stride);
- 参数
- frame:QY265DecoderGetDecodedFrameEm接口返回的解码输出帧
- index: YUV分量索引,0表示Y分量,1表示U分量,2表示v分量
- 返回值: YUV某个数据分量的数组,格式为Uint8Array
Flush解码器
QY265DecodeFlush
因为解码NAL单元与获取解码输出为异步关系, 所以解码器中可能存在剩余尚未解码完成的若干NAL单元. 调用本函数将使解码器完成所有已经输入的NAL单元的解码. 一般在码流结束或者播放器拖曳时使用.
qy265decoder.QY265DecodeFlush(decoder, bClearCachedPics, returnCode);
- 参数
- decoder: 通过QY265DecoderCreate接口创建的解码器实例
- bClearCachedPics: 是否清除缓冲的图像. 在码流结束时, 置为false, 不清除, 得到所有输出帧;在播放器拖曳或其他情况下, 置为true, 清除之前的图像帧, 重新开始
- returnCode: 返回码,returnCode对应地址保存0(QY_OK)表示正常
YUV渲染器文档
初始化YUV渲染器
import WebGLCanvas from 'yuvrender.min.js'; // yuvrender.min.js在压缩包中的demo目录下
let webGLCanvas = new WebGLCanvas({
canvas: this.canvas, //传入一个canvas
width: width, //视频帧宽度
height: height //视频帧高度
});
- 备注:视频会根据它真实的宽高比自适应视频容器canvas的宽高
<canvas id="videoDisplayCanvas" width="1600" height="600">
渲染一帧YUV数据
// 假设yuvData为解码输出的一帧图像的YUV表示(Uint8Array类型)
let ylen = width * height; //视频宽高
let uvlen = (width / 2) * (height / 2);
webGLCanvas.drawNextOutputPicture({
yData: yuvData.subarray(0, ylen),
uData: yuvData.subarray(ylen, ylen + uvlen),
vData: yuvData.subarray(ylen + uvlen, ylen + uvlen*2)
});
获取解码输出的图像帧的YUV表示
参见: 设置解码输出图像回调 set_image_callback
h265webplayer的更多相关文章
随机推荐
- 一个DDOS病毒的分析(二)
一.基本信息 样本名称:hra33.dll或者lpk.dll 样本大小: 66560 字节 文件类型:Win32的dll文件 病毒名称:Dropped:Generic.ServStart.A3D47B ...
- POJ 3613 快速幂+Floyd变形(求限制k条路径的最短路)
题意: 给你一个无向图,然后给了一个起点s和终点e,然后问从s到e的最短路是多少,中途有一个限制,那就是必须走k条边,路径可以反复走. 思路: 感觉很赞的一个题目,据说证明是什 ...
- UVA11054Gergovia的酒交易
题意: 有n个村庄,每个村庄要么买酒要么买酒,负数是买酒,整数是买酒,题目保证所有的数字想加和为0,保证有解,然后每一个村庄往相邻的村庄运k坛酒的花费是k,问满足所有的村庄的最小花费是多少 ...
- Intel汇编语言程序设计学习-第五章 过程-下
5.3.3 库测试程序 测试程序#1:整数I/O 该测试程序把输出文本的颜色改为蓝底黄字,然后以十六进制数显示七个数组的内容,最后提示用户输入一个有符号整数,再分别以十进制.十六进制和二进制格式重复 ...
- Windows 怎么知道我已经连接到互联网而不是局域网? 原来当中大有文章!
Windows 怎么知道我已经连接到互联网而不是局域网? 原来当中大有文章! 转载 原文章地址:点击 2014-01-09 Windows 怎么知道我已经连接到互联网而不是局域网? 原来当中大有文章! ...
- 简单使用高德地图开放平台API
需求说明 输入经纬度,得到城市名 挑选API 使用高德逆地理编码API,点击查看文档 demo <?php /** * 根据输入的经纬度返回城市名称 * @param $longitude 终点 ...
- 0902-用GAN生成动漫头像
0902-用GAN生成动漫头像 目录 一.概述 二.代码结构 三.model.py 3.1 生成器 3.2 判别器 四.参数配置 五.数据处理 六.训练 七.随机生成图片 八.训练模型并测试 pyto ...
- [论文阅读笔记] Fast Network Embedding Enhancement via High Order Proximity Approximati
[论文阅读笔记] Fast Network Embedding Enhancement via High Order Proximity Approximation 本文结构 解决问题 主要贡献 主要 ...
- 低代码平台--基于surging开发微服务编排流程引擎构思
前言 微服务对于各位并不陌生,在互联网浪潮下不是在学习微服务的路上,就是在使用改造的路上,每个人对于微服务都有自己理解,有用k8s 就说自己是微服务,有用一些第三方框架spring cloud, du ...
- 21.File和IO流
IO就可以对文件进行读写 File表示要读写的文件在哪,也可以对文件进行创建,删除等操作 小结: IO流是什么? 1.可以将数据从本地文件中读取出来 2.可以将数据从内存保存到本地文件 File类时什 ...