Skip to content

使用Webassembly播放AVIF动画文件,向后兼容AVIF图像文件,能够在旧版的浏览器上使用AVIF

License

Notifications You must be signed in to change notification settings

cct124/avif-player-web

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

avif-player-web

使用Webassembly播放AVIF动画文件。单帧的图像也是支持的,但是因为每个图像都会创建一个解码器和Worker线程,而且解码时间过长,所以意义不大。这个库使用了Emscripten编译LibavifWebassembly从而提供向后兼容的AVIF文件的支持。如何编译WASM版的Libavif查看这个项目libavif-decode-wasm

只支持8bit色深文件,每个AvifPlayerWeb对象创建播放时都会新建一个Worker线程

npm version

安装

# npm
npm i avif-player-web

# yarn
yarn add avif-player-web

示例

播放一个动画文件

<canvas id="canvas"></canvas>
import AvifPlayerWeb from "avif-player-web";

// 每个AvifPlayerWeb对象创建播放时都会新建一个Worker线程
// 第二个参数可以是配置对象
const avifPlayerWeb = new AvifPlayerWeb.AvifPlayerWeb(
  // 你的avif文件链接
  "www.example.com/animation.avif",
  // 传入canvas DOM对象或id
  document.getElementById("canvas"),
  {
    // 配置项列出了所有配置选项
    // 自动播放
    autoplay: true,
  }
);

avifPlayerWeb.on(
  // AvifPlayerWeb对象的所有事件都在AvifPlayerWebChannel枚举中
  AvifPlayerWeb.AvifPlayerWebChannel.frameIndexChange,
  (data) => {
    console.log(data.index);
  }
);

// 播放多个动画
const avifPlayerWeb = new AvifPlayerWeb.AvifPlayer({
  source: [
    // 默认播放数组的第一个
    {
      // 指定一个id
      id: 0,
      // AVIF图像路径
      url: normal,
      // 循环播放
      loop: 0,
    },
    { id: 1, url: downgrade },
    { id: 2, url: upgrade },
  ],
  canvas: canvas.value,
  autoplay: true,
});

// 切换播放的动画,播放id为1的图像动画
avifPlayerWeb.play({
  id: 1,
  // 从这个动画的第一帧开始播放
  index: 0,
});

显示单帧的图像文件

import AvifPlayerWeb from "avif-player-web";

const avifPlayerWeb = new AvifPlayerWeb.AvifPlayerWeb(
  "www.example.com/one.avif",
  document.getElementById("canvas"),
  {
    // 这样才能一开始就显示图像
    autoplay: true,
  }
);

avifPlayerWeb.on(AvifPlayerWeb.AvifPlayerWebChannel.end, (data) => {
  // 播放完成后销毁Worker线程以节省内存
  avifPlayerWeb.destroy();
});

配置

AvifPlayerWeb对象的所有可选配置

/**
 * 可选配置项
 */
export interface AvifPlayerWebOptions {
  /**
   * 传入canvas DOM对象或id
   */
  canvas?: string | HTMLCanvasElement;
  /**
   * 启用webgl api渲染
   */
  webgl?: boolean;
  /**
   * 循环播放次数,0表示无限循环播放,默认1
   */
  loop?: number;
  /**
   * 初始化完成后立即播放
   */
  autoplay?: boolean;
  /**
   * 是否开启异步解码,开启这个播放系统将尽可能的解码每一帧,播放将会更流畅,副作用是占用内存大,暂停后重新播放时可能有延迟,默认false
   */
  async?: boolean;
  /**
   * 开启异步解码时图像数据缓冲区允许最大的内存占用,这个值是根据`pixels.byteLength`图像数据大小计算的,真正占用的内存空间会比这个值略大,默认`67108864`即`64MB`,单位`byte`
   */
  arrayBuffSize?: number;
  /**
   * 实例化对象时立刻初始化解码器,默认false
   */
  initDecoderInstantly?: boolean;
  /**
   * 实例化对象时立刻初始化解码器并开始下载解析AVIF文件,默认false
   */
  initDecoderAvifInstantly?: boolean;
  /**
   * 是否启用边下边播功能,默认开启
   */
  enableStreaming?: boolean;
}

配置项补充

async异步解码

异步解码本质就是缓存提前解码后的图像数据,这个功能是能提高播放动画流畅度的,特别是对于帧率较高的动画文件来说

为什么

alt text

上图 I、P 、B帧是H264编码方式,AV1编码使用了类似的技术

这是视频编码方式的问题,AVIF文件是使用AV1视频编码技术对图像或动图进行编码的。AV1视频编码技术使用了帧间预测的技术,简单说就是部分编码后的帧,解码时是需要通过复杂计算才能得出完整帧,所以不同的帧解码时间是不一样的。这时可以将解码快的帧缓存起来,只要当前帧播放时长大于解码时间。这样就能有时间去解码帧间预测的帧,从而保证整体的流畅播放。

其它

推荐的AVIF动画参数

推荐动画文件的分辨率不超过750px*750px,帧率不超过25帧,这样能最大程度保持播放的流畅和画面的清晰

不同格式之间的简单对比

可以看出AVIF文件大小方面的优势是很明显的,这也是为什么做这个库的原因

格式 展示 文件大小
H264(原视频文件来源(Pinterest)) 5.77MB
APNG 68.7MB
VAP(H265) 2.03MB
VAP(H264) 2.52MB
AVIF 1.65MB

如何实现

解码的流程

alt text

About

使用Webassembly播放AVIF动画文件,向后兼容AVIF图像文件,能够在旧版的浏览器上使用AVIF

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published