npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@break_happy/streamcanvasx

v0.0.5

Published

组件功能描述

Readme

@break_happy/streamcanvasx

使用

安装播放器包:

pnpm add @break_happy/streamcanvasx

准备一个有尺寸的容器:

<div id="player" style="width: 640px; height: 360px"></div>

在页面入口中创建播放器,将 url 替换为实际流地址:

import { createPlayerServiceInstance } from "@break_happy/streamcanvasx";

const player = createPlayerServiceInstance({
  url: "https://example.com/live.flv",
  contentEl: document.querySelector<HTMLElement>("#player")!,
  streamType: "flv",
  isLive: true,
});

player.createPlayer({});

// 页面退出或不再使用时调用:player.destroy();

直播重连与错误回调

下面是更完整的 JavaScript 接入示例,替换上面的最小示例使用。deviceOnline 由业务的设备状态通知更新:

import { createPlayerServiceInstance } from "@break_happy/streamcanvasx";

let deviceOnline = true;

const player = createPlayerServiceInstance({
  url: "https://example.com/live.flv",
  contentEl: document.querySelector("#player"),
  streamType: "flv",
  isLive: true, // 直播异常时自动进入重连流程
  hasVideo: true,
  hasAudio: true,
  isMuted: true, // 初始静音
  stopCallBack: async () => ({
    // 重连时查询业务状态,决定是否停止
    stop: !deviceOnline,
    message: deviceOnline ? "" : "设备已离线",
  }),
});

// 实例属性,不是构造配置项;当前默认值也是 100000。
player.maxErrorTimes = 100000;

player.on("mediaInfo", ({ hasVideo, hasAudio }) => {
  console.log("媒体轨道", { hasVideo, hasAudio });
});

player.on("otherInfo", ({ speed, decodedFrames, droppedFrames }) => {
  console.log("接收速度", speed, "KB/s");
  // 帧数统计为累计值,部分播放链路可能不提供这两个字段。
  console.log("累计帧数", decodedFrames, "累计丢帧", droppedFrames);
});

// 事件名沿用当前拼写 performaceInfo。
player.on("performaceInfo", ({ fps, duringtime }) => {
  console.log("当前 FPS", Number(fps));
  console.log("运行时长", duringtime);
});

player.createPlayer({});

// 当前 FLV 错误事件在 corePlayer 上订阅。
// 此处用于业务提示、日志上报;播放器自身已经处理自动重连。
const core = player.corePlayer;
const onError = (type, detail, info) => {
  console.error("播放异常", { type, detail, info });
};
core.on("error", onError);

// 在业务收到设备重新上线通知时调用。
function onDeviceOnline() {
  deviceOnline = true;
  player.forceReload();
}

// 页面或组件卸载时调用。
function dispose() {
  core.off("error", onError);
  player.destroy();
}

直播恢复成功后会清零失败计数。当前实现是最多连续失败 100000 次的持续重连,尚没有独立的“无限重连”配置;不要将上限设为 Infinity,现有停止逻辑依赖计数超过上限。

stopCallBack 是重连时的业务停止回调,不接收错误详情;错误详情通过 core.on('error', ...) 获取。当前重连流程不会等待这个异步回调,因此返回 stop: true 可以停止播放和后续重连,但不能保证阻止本次请求发出。

静音、增益与画面操作

播放器创建、相应音视频链路就绪后,在按钮或滑块的事件中调用:

| 操作 | 调用 | | ---------------------------------- | ------------------------------------------------------------ | | 静音 | player.audioProcessingService.mute(true) | | 取消静音 | player.audioProcessingService.mute(false) | | 调整增益 | player.audioProcessingService.setGain(1.5),1 为原始增益 | | 再旋转 90° | player.canvasVideoService.drawRotate(90) | | 重置旋转(当前实现有限制,见下文) | player.canvasVideoService.rotateReset() | | 水平镜像 | player.canvasVideoService.drawHorizontalMirror() | | 垂直镜像 | player.canvasVideoService.drawVerticalMirror() | | 重置镜像 | player.canvasVideoService.transformReset() | | 裁剪填满容器 | player.canvasVideoService.setCover(true) | | 手动重新连接 | player.forceReload() | | 销毁播放器 | player.destroy() |