@eyevinn/media-event-filter

中文文档
3.4.1发布于 2024/10/30MITTypeScriptES Module零依赖近 30 天下载 5013

HTML5 媒体事件过滤器

中文使用文档
文档目录22 节
  1. 为什么
  2. 概览
  3. 限制
  4. 使用量
  5. 样本 Shaka + 反应组件
  6. 福利
  7. 活动
  8. 示例顺序
  9. 已装入
  10. 请求
  11. 已寻求
  12. 缓冲
  13. 缓冲
  14. 播放
  15. 播放
  16. 暂停
  17. 时间更新日期
  18. 结束
  19. 捐款
  20. Git 工作方法
  21. 开发
  22. 释放

媒体事件过滤器

用于从 a 对重播事件生成一个正常的默认解释的可依赖性自由而微小的套件 HTML 介质。 。 。 .

为什么

HTML5 视频元素不产生符合跟踪器和用户界面要求的更新的一致事件集,比如 loaded, (中文(简体) ), buffering 或者说 seeking。 。 。 .

在"媒体源扩展"上方所搭建的不同玩家引擎都有自己的执行功能来收听事件.

这个过滤器旨在提供一个单一的真理源,可以跨玩家引擎和浏览器本土回放使用.

坚持 Eyvinn 玩家分析规格。 。 。 .

概览

/** Loading of stream is complete, playback is ready to start */
/** It is now safe to let the user press a play button */
"loaded";
/** A seek has started */
"seeking";
/** A seek has ended  */
"seeked";
/** Buffering has started */
/** Does not trigger during seek, cancelled by a seek */
"buffering";
/** Buffering has ended */
/** Does not trigger during seek */
"buffered";
/** A request to start playing again has been made */
"play";
/** The stream has started playing after loading completed
 *  OR the stream has started playing after the stream was previously paused */
"playing";
/** The stream has been paused */
"pause";
/** The end of the stream was reached */
"ended";
/** A timeupdate event */
"timeupdate";

限制

不支持本地 HTML5 MSE 控件( N)<video controls>) (中文(简体) ). 它有效,但事件序列不会在所有浏览器中严格遵循EPAS.

使用量

npm install @eyevinn/media-event-filter

yarn add @eyevinn/media-event-filter

创建和监听事件过滤器的示例 .

import {
  getMediaEventFilter,
  FilteredMediaEvent,
} from "@eyevinn/media-event-filter";

const videoElement = document.createElement("video");

// Using a switch statement

const mediaEventFilter = getMediaEventFilter({
  mediaElement: videoElement,
  callback: (event: FilteredMediaEvent) => {
    switch (event) {
      case FilteredMediaEvent.LOADED:
        // handle loaded
        break;
      case FilteredMediaEvent.BUFFERING:
        // handle buffering
        break;
      case FilteredMediaEvent.BUFFERED:
      // handle buffered
      // ...
      default:
        break;
    }
  },
});

// Call when done
mediaEventFilter.teardown();
// Object notation can also be used

const handlers = {
  [FilteredMediaEvent.LOADED]: () => {
    /* handle loaded */
  },
  [FilteredMediaEvent.BUFFERING]: () => {
    /* handle buffering */
  },
  [FilteredMediaEvent.BUFFERED]: () => {
    /* handle buffered */
  },
  // ...
};

const mediaEventFilter = getMediaEventFilter({
  mediaElement: videoElement,
  callback: (event: FilteredMediaEvent) => handlers[event]?.(),
});
// It is safe to use destructuring

const { teardown } = getMediaEventFilter({
  /* ... */
});

teardown();

样本 Shaka + 反应组件

滤波器可以方便地在Shaka上方建立反应UI.

裸骨样本集成(参见 代码:

import { useCallback, useEffect, useMemo, useRef, useState } from "React";
import shaka from "shaka-player";
import {
  FilteredMediaEvent,
  getMediaEventFilter,
} from "@eyevinn/media-event-filter";

const PlayerComponent = ({ videoUrl }) => {
  const videoRef = useRef(null);
  const [playing, setPlaying] = useState(false);
  const [loading, setLoading] = useState(true);
  const [blocked, setBlocked] = useState(false);

  useEffect(() => {
    if (!videoUrl || !videoRef.current) return () => {};

    const eventFilter = getMediaEventFilter({
      mediaElement: videoRef.current,
      // add your state handlers here
      callback: (event) => {
        switch (event) {
          case FilteredMediaEvent.LOADED:
            setLoading(false);

            // attempt autoplay
            videoRef.current.play().catch((e) => {
              // catch autoplay block
              if (e.name.indexOf("NotAllowedError") > -1) {
                setBlocked(true);
              }
            });
            break;
          case FilteredMediaEvent.PLAYING:
            // reset autplay blocked
            setBlocked(false);
            // we're playing!
            setPlaying(true);
            break;
          case FilteredMediaEvent.ENDED:
          case FilteredMediaEvent.PAUSE:
            setPlaying(false);
            break;
          default:
            break;
        }
      },
    });

    const player = new shaka.Player(videoRef.current);

    // Add configuration if needed
    // player.configure()

    player
      // start loading the stream
      .load(videoUrl)
      // catch errors during load
      .catch(console.error);

    // Kill player when unmounted
    return () => {
      player.destroy();
      eventFilter.teardown();
    };
  }, [videoUrl, videoRef]);

  const play = useCallback(() => {
    if (!videoRef.current) return;

    videoRef.current.play();
  }, [videoRef]);

  const pause = useCallback(() => {
    if (!videoRef.current) return;

    videoRef.current.pause();
  }, [videoRef]);

  return (
    <div style={{ width: "720px", margin: "20px auto" }}>
      {loading && <p>Video is Loading</p>}

      {!loading &&
        (playing ? (
          <button type="button" onClick={pause}>
            Pause
          </button>
        ) : (
          <button type="button" onClick={play}>
            Play
          </button>
        ))}

      {blocked && <p>Autoplay blocked, please start playback manually</p>}

      <video ref={videoRef} style={{ width: "100%", height: "auto" }} />
    </div>
  );
};
// Use it:
<PlayerComponent videoUrl="https://bitmovin-a.akamaihd.net/content/MI201109210084_1/mpds/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.mpd" />

福利

无论引擎(Shaka, Hls.js, DashJS, 原生)或浏览器(Chrome, Firefox, Safari),为回放事件获取单一的真相来源.

将事件直接插入您的 UI 状态管理中, 以获取重播状态更新的可靠真相源 .

事件序列映射直接通向受欢迎的跟踪提供者并回放SDK而不进行进一步过滤,比如Youbora,Comscore,Yosspace,或Nielsen. 如果你们也得到支持,我们欢迎公关更新这个名单!

兼容 电子考绩制度。 。 。 .

活动

事件描述及其顺序.

示例顺序

LOADED; // playback is ready to start
PLAYING; // playback started
SEEKING; // seek requested
PAUSED; // manual pause
PLAY; // manual play
SEEKED; // seek finished
PLAYING; // video is rolling again
BUFFERING; // unable to continue playing due to missing buffer
BUFFERED; // buffer ended by incoming seek request
SEEKING; // seek requested
SEEKED; // seek finished
PAUSED; // manual pause
PLAY; // manual play
PLAYING; // video is rolling again
ENDED; // video reached the end

已装入

视频的初始负载已经完成,准备开始播放.

装入前没有其它事件可以触发 .

请求

寻已起.

如果正在缓冲,则在寻求之前会被触发.

缓冲事件无法在搜索中触发 .

装入前不能触发 .

已寻求

寻觅已后.

装入前不能触发 .

没有先前的寻找事件就无法触发.

缓冲

缓起已起.

无法在搜索中触发 .

装入前不能触发 .

缓冲

缓冲已经结束,或因寻求而中断.

无法在搜索中触发 .

没有先前的缓冲事件就无法触发 .

播放

已请求播放 .

装入前不能触发 .

如果视频之前没有暂停, 则无法触发 .

播放

播放已经开始 .

装入前不能触发 .

寻找时不能触发 .

缓冲时不能触发 .

如果视频之前没有暂停, 则无法触发 .

求取或缓冲时请求的玩法会在求取或缓冲完成后触发玩法.

暂停

播放已暂停 .

寻求或缓冲并不算作穷困.

装入前不能触发 .

时间更新日期

时间更新事件

装入前不能触发 .

结束

玩家已到达一流的尽头.

允许在流尾到达后重新启动流 allowResumeAfterEnded 改为 true。 。 。 .

捐款

欢迎为改进不同引擎的兼容性或增加支持,跟踪解决方案,浏览器做出贡献.

Git 工作方法

项目使用特色分支,a 重组合并策略。 。 。 .

确保你有 git pull 设置为再基准模式 :

git config pull.rebase true

可以选择添加 --global 标记为上方命令.

要开始研究一个新的功能: git checkout <feature branch name>。 。 。 .

由于该项目使用语义释放到 自动生成释放注释 基于承诺,在作出承诺时必须遵守一些规则.

这个项目使用 常规承诺。 。 。 .

读取 使用有纪律的 Git。 。 。 .

读取 如何撰写提交信件。 。 。 .

承诺应:

  • 包含一个单一的更改集( 较小的承诺更好)
  • 通过测试、打字和打字检查
  • 无法被打破

它与能够节省时间的自动化同时,也能够通过 双节使捕虫成为几分钟而不是几天的事 外有多篇关于"分形"魔法的文章.

承诺信息的基本结构:

<type>[optional scope]: <title starting with verb in infinitive>

[optional body]

[optional footer]

自动放出注释要效果好,尝试描述被添加或被更改的内容,而不是描述代码的作用. 示例

fix(seek): rewrite calculation in seek module // bad, the consumer does not know what issue this fixes

fix(seek): stop player from freezing after seek // good, the consumer understands what is now working again

开发

要启动 Dev 服务器 : pnpm dev检查 demo 财务报告和审定财务报表 public/index.html 详细情况.

熟悉 HTML5 视频标准、 shaka、hlsjs 或其他引擎 建议在发言前先发言.

https://www.w3.org/TR/2011/WD-html5-20110113/video.html 互联网档案馆的存檔,存档日期2013-12-21

https://html.spec.whywg.org/multipage/media.html 互联网档案馆的存檔,存档日期2013-12-22

https://html.spec.whywg.org/multipage/media.html#mediaevents (中文(简体) )

试验用 Shaka 2.5.X - 4.X.X

在Safari接受本地视频测试

用hls.js测试

在Safari 13.1+、Firefox、Chrome、Edge试验过

在OSX、Windows、Linux上测试

释放

释放是通过github动作被触发的,该动作将自动递增版本并基于承诺写入更动日志.

可以通过运行进行手动发布 pnpm release。 。 。 .

支助

加入我们 slack 社区 您可以在其中张贴任何关于我们开放源代码项目的问题。 Eyevin的咨询业务也可以提供:

  • 本构成部分的进一步发展
  • 此组件定制并整合到您的平台
  • 支助和维持协定

联系人 销售量@ eyevin.se 如果你有兴趣.

关于 Eyevinn 技术

目光技术 一家独立咨询公司,专门从事录像和流媒体制作。 独立的方式,我们不与任何平台或技术供应商进行商业联系。 作为我们创新和推动工业前进的途径,我们开发了概念证明和工具。 我们学到的东西和我们写的代码 与行业分享 博客 并且通过公开提供我们写的代码.

想知道更多关于"Eyevin" 和如何工作在这里。 联系我们 工作@ eyevin.se来啊!

版本与发布记录

@eyevinn/media-event-filter 共发布 16 个版本,首次发布于 2023/03/02;过去 12 个月发布了 0 个版本。

版本发布日期距今
3.4.1latest2024/10/302 年前
3.4.02024/09/302 年前
3.3.02024/09/182 年前
3.2.02024/09/172 年前
3.1.02024/09/122 年前
3.0.02024/09/022 年前

关于 @eyevinn/media-event-filter 的常见问题

@eyevinn/media-event-filter 是什么?

HTML5 媒体事件过滤器

如何安装 @eyevinn/media-event-filter?

在项目目录运行 npm install @eyevinn/media-event-filter,或使用 pnpm add / yarn add / bun add。

@eyevinn/media-event-filter 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@eyevinn/media-event-filter 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@eyevinn/media-event-filter 可以商用吗?

@eyevinn/media-event-filter 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@eyevinn/media-event-filter 的下载量有多少?

根据 npm 官方下载统计,@eyevinn/media-event-filter 在 2026/10/14 – 2026/11/12 这 30 天内被下载 5,013 次,日均约 167 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@eyevinn/media-event-filter 还在维护吗?

最新版本 3.4.1 发布于 2024/10/30(2 年前);至今共发布 16 个版本,其中过去 12 个月发布了 0 个;首次发布于 2023/03/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。