h265web.js-wasm-decoder icon indicating copy to clipboard operation
h265web.js-wasm-decoder copied to clipboard

🔥WebAssembly API H.265/HEVC Decoder, return YUV Frame.

h265web.js-wasm-decoder

h265web.js播放器 - https://github.com/numberwolf/h265web.js 底层解码API

可以直接用于自定义开发H.265播放器

Demo 媒资信息
Input #0, hevc, from 'res/video40_265_moov.hevc':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: hevc (Main), yuv420p(tv), 1280x720, 25 fps, 25 tbr, 1200k tbn, 25 tbc

目录

  • 0、说明

    • 当前能力

    • 当前版本token

    • 联系我

  • 1、快捷方式使用 - 完整Demo

  • 2、解码SDK使用文档

    • 文件说明

    • 安装

    • H.265/HEVC 数据解析器使用 - 分割帧

    • H.265/HEVC 解码器使用

  • 3、其它

    • 捐赠

    • FFmpeg转码H.265/HEVC编码的265测试文件

0、说明

当前能力

  • 能力
能力 是否支持 其他
HEVC/H.265 Nalu解析 ----
HEVC/H.265 帧解码 ----
HEVC/H.265 多窗口播放 ----
  • 协议
协议 是否支持 说明
HEVC/H.265 点播 ----
HEVC/H.265 点播 ----

当前版本的token

token = "base64:QXV0aG9yOmNoYW5neWFubG9uZ3xudW1iZXJ3b2xmLEdpdGh1YjpodHRwczovL2dpdGh1Yi5jb20vbnVtYmVyd29sZixFbWFpbDpwb3JzY2hlZ3QyM0Bmb3htYWlsLmNvbSxRUTo1MzEzNjU4NzIsSG9tZVBhZ2U6aHR0cDovL3h2aWRlby52aWRlbyxEaXNjb3JkOm51bWJlcndvbGYjODY5NCx3ZWNoYXI6bnVtYmVyd29sZjExLEJlaWppbmcsV29ya0luOkJhaWR1";

联系我

  • Github: https://github.com/numberwolf
  • Email([email protected])
  • QQ: 531365872
  • Discord:numberwolf#8694
  • 微信:numberwolf11

1、快捷方式使用

  • 1)使用流程也可以直接看 example.jsexample.html 的Demo使用

  • 2)自己直接运行Demo

    • 将以下文件拷贝到http服务器下同目录访问即可

      • example.html
      • example-dist.js
      • missile-dec.wasm
  • 3)或者自己编译Demo


2、播放器SDK使用文档

文件说明

  • 核心文件
文件 必要 说明 其他
index.js SDK入口文件 ----
decoder.js H.265解码能力 ----
missile-dec.wasm 解码WASM ----
raw-parser.js 解析265流并分割Nalu ----
package.json ---- ----
package-lock.js ---- ----

  • Sdk使用示例Demo文件
文件 说明 其他
example.html 示例Html ----
example.js 示例API使用方法JS文件 ----
example-dist.js 直接编译好的可以直接使用的js文件 与wasm放同一个目录
render-yuv420p.js 渲染YUV420P 这个最好自己写 这里只是一个demo

安装

  • 核心文件拷贝到你项目下同一目录

    • index.js
    • decoder.js
    • missile-dec.wasm
    • raw-parser.js
  • 在你的工程文件引入 index.js


H265数据解析器使用

  • 1)引入文件

    mport MissileEngineDecoder from './index';
    
  • 2)新建H265数据解析器

    ar rawParserObj = new MissileEngineDecoder.CRawParser();
    
  • 3)将H265的字节流数据喂给解析器

    输入数据 Uint8Array 类型
    / Uint8Array chunk
    awParserObj.appendStreamRet(chunk);
    
  • 4)从解析器吐出 一帧H265 数据

    返回数据 Uint8Array 类型 (失败为false)
    et nalBuf = rawParserObj.nextNalu(); // nal
    if (nalBuf != false) {
    	// todo
    }
    
  • 5)完整示例代码

    mport MissileEngineDecoder from './index';
    ar url265 = "res/video40_265_moov.hevc";
    ar rawParserObj = new MissileEngineDecoder.CRawParser();
    fetch(url265).then(function(response) {
        let pump = function(reader) {
            return reader.read().then(function(result) {
                if (result.done) {
                    // todo
                }
                let chunk = result.value;
                rawParserObj.appendStreamRet(chunk);
                return pump(reader);
            });
        }
        return pump(response.body.getReader());
    })
    .catch(function(error) {
        console.log(error);
    });
    for(var i = 0; i < 100; i++) {
       let nalBuf = rawParserObj.nextNalu(); // nal
       if (nalBuf != false) {
       	// todo
       }
    
    

H265解码器使用

  • 1)引入文件

    mport MissileEngineDecoder from './index';
    
  • 2)新建H265解码器

    ar token = "base64:QXV0aG9yOmNoYW5neWFubG9uZ3xudW1iZXJ3b2xmLEdpdGh1YjpodHRwczovL2dpdGh1Yi5jb20vbnVtYmVyd29sZixFbWFpbDpwb3JzY2hlZ3QyM0Bmb3htYWlsLmNvbSxRUTo1MzEzNjU4NzIsSG9tZVBhZ2U6aHR0cDovL3h2aWRlby52aWRlbyxEaXNjb3JkOm51bWJlcndvbGYjODY5NCx3ZWNoYXI6bnVtYmVyd29sZjExLEJlaWppbmcsV29ya0luOkJhaWR1";
    ar version = '100.1.0';
    ar decoderMod = null;
    ecoderMod = new MissileEngineDecoder.CMissileDecoder(token, version);
    
  • 3)解码器绑定回调事件 - 获取解码结果数据

    • 初始化成功回调 decoderMod.initFinish = xxx

    • 绑定解码成功事件 decoderMod.bindCallback(callback)

      a)解码成功事件函数原型
      unction(
      y, u, v, 
      stride_y, stride_u, stride_v, 
      width, height, pts,
      pix_name
       {
      // @TODO
      
      

      b)解码回调数据说明

      • y, u, v
        • 说明:解码最终YUV数据 Uint8Array 类型
      • stride_y, stride_u, stride_v
        • 说明:解码stride长度 int 类型
      • width, height, pts
        • 说明:解码图像 长、宽、时间戳(用户传入一致)
      • pix_name
        • 说明:解码YUV格式
    • 代码如下

      / 解码器初始化成功事件
      ecoderMod.initFinish = () => {
      console.log("init Finshed");
      
      // 解码结果回调
      let bind_ret = decoderMod.bindCallback(function(
      	y, u, v, 
      	stride_y, stride_u, stride_v, 
      	width, height, pts,
      	pix_name) {
      
      	console.log("======> One Frame ");
      	console.log("======> ======> width, height, pts", width, height, pts);
      	console.log("======> ======> pix_name", pix_name);
      	console.log("======> ======> Y ", stride_y, y);
      	console.log("======> ======> U ", stride_u, u);
      	console.log("======> ======> V ", stride_v, v);
      });
      
      // todo
      ;
      
  • 4)解码器初始化

    初始化成功后,会调用 decoderMod.initFinish

    ecoderMod.initDecoder();
    
  • 5)解码一帧数据 - 解码结果最终会通过 decoderMod.bindCallback(callback) 回调回来

    • Uint8Array nalBuf 一帧265数据
    • float32 pts 时间戳毫秒数据
    ecoderMod.decodeNalu(nalBuf, pts);
    

3、其它

捐赠

微信 支付宝 PayPal
TODO

FFmpeg转码H265编码的265测试文件

  • ffmpeg转码一个测试 H.265/HEVC的 Demo文件

    fmpeg -i input265.mp4 -vcodec libx265 -an -vtag hev1 -y video40_265_moov.h265