H.265/Hevc Web端播放器,支持H.265编码的mp4/hls/m3u8/mpegts 的媒体播放,支持点播、直播。A Hevc Web Player , support file type: mp4/hls/m3u8/mpegts, support play type: vod/live。Github:https://github.com/numberwolf/h265web.js
npm install h265web.js| 更新 | 内容 |
| ---- | ---- |
| 时间 | 2021/02/18 |
| 内容1 | 1.新播放内核,增加音频播放能力 |
| 时间 | 2021/02/08 |
| 内容1 | 1.增加播放内核类型:新播放内核,可兼容多种解码Badcase(测试阶段, 输入媒资Mp4Box需要前置Moov,当前还不支持音频、Seek) |
| 时间 | 2021/01/04 |
| 内容1 | 1.支持H.265的流式接入,可直接以265的URI进行播放、也可以流式字节填充播放(可应用于直播) |
| 内容2 | 2.取消了播放器自带的播放view蒙板(用于点击播放画面触发暂停/播放能力),开放给用户自行实现 |
| 内容3 | 3.支持 如果播放器配置的长宽与视频纵横比不匹配,自动裁剪黑边区域 |
| 内容4 | 4.增加onPlayFinish 事件回调,播放结束调用 |
| @TODO | 内容 |
| ---- | ---- |
| 播放问题 | 新内核增加Seek能力 |
| h265web.js | mpeg.js (解析ts) |
| ---- | ---- |
|  |  |
License GPL-3.0 https://www.gnu.org/licenses/gpl-3.0.md

————————— __一个可支持HEVC/H.265编码播放720P、1080P的播放器。__
__~^_^~ 作者用爱发电 如果 h265web.js 帮助到了你,请点击右上角的star~__
- 0、说明
- 当前能力
- 联系我
- 线上demo
- 效果预览
- 1、快捷方式使用
- 安装
- 播放器配置
- 初始化播放器
- 播放器API能力
#### 当前能力 ####
* 协议
| 协议 | 模式 | 是否支持 | 说明 |
| ---- | ---- | ---- | ---- |
| mp4 | 点播 | 是 | ---- |
| mpeg-ts | 点播 | 是 | ---- |
| m3u8 | 点播 | 是 | ---- |
| hls | 直播 | 是 | ---- |
| H.265 | 点播 | 是 | ---- |
| H.265 | 直播 | 是 | ---- |
| http-flv | 直播 | 否 | 待支持 |
| flv | 点播 | 否 | 待支持 |
* 能力
| 能力 | 是否支持 | 其他 |
| ---- | ---- | ---- |
| 直播 | 是 | ---- | ---- |
| 点播 | 是 | ---- | ---- |
| Seek跳转 | 是 | core=1 时的新内核不支持 | ---- |
| 精准Seek | 是 | ---- | ---- |
| 封面图 | 是 | ---- | ---- |
| 边下边播 | 是 | ---- | ---- |
| 音量调节 | 是 | ---- | ---- |
| 播放 | 是 | ---- | ---- |
| 暂停 | 是 | ---- | ---- |
| 重新播放 | 是 | ---- | ---- |
| 暂停截图 | 是 | ---- | ---- |
| 1080p播放 | 是 | ---- | ---- |
| 720p播放 | 是 | ---- | ---- |
| 多路播放 | 是 | ---- | ---- |
#### 当前版本的token ####
``javascript`
token = "base64:QXV0aG9yOmNoYW5neWFubG9uZ3xudW1iZXJ3b2xmLEdpdGh1YjpodHRwczovL2dpdGh1Yi5jb20vbnVtYmVyd29sZixFbWFpbDpwb3JzY2hlZ3QyM0Bmb3htYWlsLmNvbSxRUTo1MzEzNjU4NzIsSG9tZVBhZ2U6aHR0cDovL3h2aWRlby52aWRlbyxEaXNjb3JkOm51bWJlcndvbGYjODY5NCx3ZWNoYXI6bnVtYmVyd29sZjExLEJlaWppbmcsV29ya0luOkJhaWR1";
#### 联系我 ####
* Github: https://github.com/numberwolf/h265web.js
* Email(porschegt23@foxmail.com)
* QQ: 531365872
* Discord:numberwolf#8694
* 微信:numberwolf11
#### 线上demo ####
#### 效果预览 ####
| 类型 | 点播 | 直播 |
| ---- | ---- | ---- |
| 点击
放大 |
|
|
* 使用流程也可以直接看 play.js和index.html的Demo使用
* 本项目可以直接放在你的web服务器目录下访问index.html
———————— __API以及事件能力__
#### 1)引入包
* 方式1.1:引入Github的本地文件 require形式
`javascript`
// 引入Github的本地文件
require('./dist/h265webjs');
* 方式1.2:引入Github的本地文件 import xxx from xxx形式 (推荐)
`javascript`
// 引入Github的本地文件
import H265webjsModule from './dist/index';
* 方式2:从npm商店引入
 | npm:h265web.js
#### 2)安装Wasm
* 如果使用了直接从Github下载dist的话这一步可以跳过。
如果用npm方式进行安装,则需要将./node_modules/h265web.js/dist/.wasm拷贝到你的h265webjs.js同级目录下才可以。
* 示例Cmd
`bash`
npm i h265web.js
cp ./node_modules/h265web.js/dist/*.wasm ./dist/
#### 3)引入h265web.js到你的项目
* 本地引入(从Github h265web.js)
* 1)require形式
`javascript`
require('./dist/h265webjs');
* 2)import xxx from xxx形式 (推荐)`
javascript`
// 引入Github的本地文件
import H265webjsModule from './dist/index';
* npm形式引入

`javascript`
const H265webjs = require('h265web.js');
* 创建代码如下
`javascript
const PLAYER_CORE_TYPE_DEFAULT = 0; // 默认播放器内核
const PLAYER_CORE_TYPE_CNATIVE = 1; // 实验播放器内核
var config = {
type: "mp4",
player: "glplayer",
width: 960,
height: 540,
accurateSeek : true,
token : token,
extInfo : {
moovStartFlag : true,
readyShow : true,
rawFps : 30,
autoCrop : false,
core : PLAYER_CORE_TYPE_DEFAULT
}
};
`
* 配置详解
| 配置项 | 类型 | 可选值 | 必填 | 说明 |
| ---- | ---- | ---- | ---- | ---- |
| type | String | mp4/hls/ts/raw265 | 是 | 播放文件的类型 |
| player | String | - | 是 | 播放窗口的dom的id值 |
| width | Int | - | 是 | 播放窗口的宽度 |
| height | Int | - | 是 | 播放窗口的高度 |
| accurateSeek | Bool | true/false | 是 | 精准Seek(暂时固定为true) |
| token | String | - | 是 | 播放器token值 |
| extInfo | Object | - | 否 | 播放器额外配置 |
| \+ moovStartFlag | Bool | true/false | 否:默认false | Mp4的moov box是否前置 关联到动态加载 |
| \+ readyShow | Bool | true/false | 否:默认false | 是否需要封面图展示 |
| \+ rawFps | Float32 | 例如:30 | 否:默认24 | HEVC/AVC裸流播放时候的帧率设定 |
| \+ autoCrop | Bool | - | 否:默认false | 如果播放器配置的长宽与视频纵横比不匹配,自动裁剪黑边区域 |
| \+ core | Int | - | 否:默认0 | 0:默认播放内核 1:测试阶段的高成功率播放内核 |
* 创建方法(全局方法)
> new265webjs(播放地址, 播放器配置)
| 参数 | 类型 | 默认值 | 必填 | 说明 |
| ---- | ---- | ---- | ---- | ---- |
| 播放地址 | String | - | 是 | 播放视频地址 |
| 播放器配置 | Object | - | 是 | 播放器配置信息 |
* 创建示例Demo
* 1)路径 + 配置
* 例子1 创建 mp4/hls/ts类型播放器
`javascript``
let videoURL = "h265_test.mp4";
let config = {
type: "mp4",
player: "glplayer",
width: 960,
height: 540,
accurateSeek : true,
token : token,
extInfo : {
moovStartFlag : true,
readyShow : true
}
};
* 例子2 创建raw265类型 播放h265裸流 播放器(包括直播)
`javascript``
let config = {
type: "raw265",
player: "glplayer",
width: 960,
height: 540,
accurateSeek : true,
token : token,
extInfo : {
readyShow : true,
rawFps : 30 // 播放帧率
}
};
* 2)创建播放器
* 1. 以require('./src/h265webjs');引入为前提
示例:
`javascript`
let h265webjs = new265webjs(videoURL, config); // 全局方法
* 2. 以import H265webjsModule from './dist/index';引入为前提 (推荐)
示例:
`javascript`
let h265webjs = H265webjsModule.createPlayer(videoURL, config);
* 3. 如果创建的是raw265类型的裸流数据播放 请注意
* raw265类型下,喂字节流播放
调用函数
| 函数 | 返回 | 说明 |
| ---- | ---- | ---- |
| append265raw | bool | 喂裸流字节数据 |
参数
| 参数 | 类型 | 默认值 | 必填 | 说明 |
| ---- | ---- | ---- | ---- | ---- |
| chunk | Uint8Array | - | 是 | 字节裸流数据 |
例子 - 这里直接将265文件通过网络串流传输
`javascript`
let videoURL = "demo/res/raw.h265";
// fetch 265
let fileStart = 0;
let startFetch = false;
let networkInterval = window.setInterval(() => {
if (!startFetch) {
startFetch = true;
fetch(videoURL).then(function(response) {
let pump = function(reader) {
return reader.read().then(function(result) {
if (result.done) {
window.clearInterval(networkInterval);
return;
}
let chunk = result.value;
// console.log(chunk);
h265webjs.append265raw(chunk); // 调用喂流
return pump(reader);
});
}
return pump(response.body.getReader());
})
.catch(function(error) {
console.log(error);
});
}
}, 1);
#### 1)Seek完成
> 主要用于SEEK完成做一些操作
* 示例
`javascript`
player.onSeekFinish = () => {
// todo
};
#### 2)YUV帧数据渲染
| 回调参数 | 类型 | 默认值 | 必填 | 说明 |
| ---- | ---- | ---- | ---- | ---- |
| width | int | - | - | YUV宽度 |
| height | int | - | - | YUV高度 |
| imageBufferY | Uint8Array | - | - | Y分量 |
| imageBufferB | Uint8Array | - | - | ChromaB分量 |
| imageBufferR | Uint8Array | - | - | ChromaR分量 |
> 可以利用事件回调的YUV做全屏播放
> 需要调用 setRenderScreen 函数开启才可以收到事件回调数据, 下方1.5 API会说明
* 示例
`javascript`
player.onRender = (width, height, imageBufferY, imageBufferB, imageBufferR) => {
// todo
};
#### 3)媒体文件加载完成事件
> 媒体文件当前加载成功,可以进行播放
* 示例
`javascript`
player.onLoadFinish = () => {
// todo
};
#### 4)播放器当前播放PTS(时刻)更新
| 回调参数 | 类型 | 默认值 | 必填 | 说明 |
| ---- | ---- | ---- | ---- | ---- |
| videoPTS | float64 | - | - | 当前播放时间 |
* 示例
`javascript`
player.onPlayTime = (videoPTS) => {
// todo
console.log(videoPTS)
};
#### 5)播放器媒体播放结束事件
* 示例
`javascript`
player.onPlayFinish = () => {
// finished
};
#### 1)加载播放器
> 一般在配置完成【播放器配置】和【事件】之后进行播放器加载
* 示例
`javascript`
player.do();
#### 2)获取当前播放状态
| 调用函数 | 返回 | 说明 |
| ---- | ---- | ---- |
| isPlaying() | bool | 是否正在播放中 |
* 示例
`javascript`
if (player.isPlaying()) {
// 正在播放中
} else {
// 当前是暂停状态
}
#### 3)开始播放
| 调用函数 | 返回 | 说明 |
| ---- | ---- | ---- |
| play() | - | 开始播放 |
* 示例
`javascript`
player.play();
#### 4)暂停播放
| 调用函数 | 返回 | 说明 |
| ---- | ---- | ---- |
| pause() | - | 暂停播放 |
* 示例
`javascript`
player.pause();
#### 5)开启/关闭渲染过程中 回调YUV帧数据
> 开启之后,onRender事件才可以收到数据
| 调用函数 | 返回 | 说明 |
| ---- | ---- | ---- |
| setRenderScreen({param1}) | - | 开启/关闭渲染过程中 回调YUV帧数据 |
* 参数
| 参数 | 类型 | 默认值 | 说明 |
| ---- | ---- | ---- | ---- |
| param1 | bool | false | 开启/关闭渲染过程中 回调YUV帧数据 |
* 示例
`javascript`
// 开启
player.setRenderScreen(true);
// 关闭
player.setRenderScreen(false);
#### 6)Seek: 跳转到某个时刻
| 调用函数 | 返回 | 说明 |
| ---- | ---- | ---- |
| seek({pts}) | - | Seek到某一个时刻 |
* 参数
| 参数 | 类型 | 默认值 | 说明 |
| ---- | ---- | ---- | ---- |
| pts | float64 | - | Seek到某一个时刻的时间点 |
* 示例
`javascript`
// Seek到10.01秒
player.seek(10.01);
#### 7)调整音量
> 调整视频的播放音量
| 调用函数 | 返回 | 说明 |
| ---- | ---- | ---- |
| setVoice({volume}) | - | 调整音量 |
* 参数
| 参数 | 类型 | 默认值 | 说明 |
| ---- | ---- | ---- | ---- |
| volume | float64 | - | 范围区间是[0, 1.0], 0为mute,1.0为全开音量 |
* 示例
`javascript`
// 音量开启一半
player.setVoice(0.5);
#### 8)获取媒资数据
> 获取当前播放的视频文件的信息数据
| 调用函数 | 返回 | 说明 |
| ---- | ---- | ---- |
| mediaInfo() | Object | 媒资详情 |
* 返回值示例
`json`
meta:
audioNone: false // 是否不包含音频轨
durationMs: 600000 // 时长 毫秒级
fps: 25 // 帧率
sampleRate: 44100 // 音频采样率
size: // 视频分辨率
height: 720
width: 1280
videoCodec: 0
videoType: "vod" // 点播vod 直播live
* 示例
`javascript`
let mediaInfo = player.mediaInfo();
* mp4
`bash`
ffmpeg -i input.mp4 \
-vcodec libx265 -pix_fmt \
-acodec aac -ac 2 -ar 44100 \
-preset medium -maxrate 1000k -bufsize 1000k \
-vtag hev1 \
-movflags faststart \
-y video.mp4
* hls/m3u8 录屏
`bash`
ffmpeg -f avfoundation -i 1:0 \
-q 4 -r 10 \
-filter_complex "scale=1280:720" \
-pix_fmt yuv420p \
-vcodec libx265 \
-ar 22050 -ab 64k -ac 1 -acodec aac \
-threads 4 \
-preset veryfast \
-f segment \
-segment_list test.m3u8 \
-segment_time 5 \
-y /Users/numberwolf/Documents/webroot/VideoMissile/VideoMissilePlayer/res/hls1/v-%03d.ts
* mpeg-ts
`bash``
ffmpeg -ss 20 -t 10 -i ./res/xinxiaomen.mp4 \
-vcodec libx265 -x265-params "bframes=0:keyint=10" -r 24 -filter_complex "scale=720:1280" -preset fast -maxrate 800k -bufsize 800k \
-acodec aac -ar 22050 -ac 1 \
-pix_fmt yuv420p \
-f mpegts -y ./res/veilside2.ts