使用Webassembly播放AVIF动画文件。单帧的图像也是支持的,但是因为每个图像都会创建一个解码器和Worker线程,而且解码时间过长,所以意义不大。这个库使用了Emscripten编译Libavif为Webassembly从而提供向后兼容的AVIF文件的支持。如何编译WASM版的Libavif查看这个项目libavif-decode-wasm
只支持8bit
色深文件,每个AvifPlayerWeb对象创建播放时都会新建一个Worker线程
# 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;
}
异步解码本质就是缓存提前解码后的图像数据,这个功能是能提高播放动画流畅度的,特别是对于帧率较高的动画文件来说
上图 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 |
解码的流程