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

@mm-custom/player

v1.0.0

Published

播放器

Readme

@mm-custom/player

一个支持多种流媒体协议的现代播放器核心库。

功能特性

支持的协议

  • WHEP - WebRTC HTTP Egress Protocol(实时低延迟流)
  • FLV - HTTP-FLV 流媒体
  • DASH/HLS - 通过 Shaka Player 支持

核心功能

播放控制

  • 播放/暂停/停止
  • 跳转到指定时间(seek)
  • 播放速度调节
  • 音量控制
  • 静音状态切换
  • 全屏/退出全屏
  • 轨道/清晰度切换
  • 图片截图
  • 字幕加载

状态管理

  • 完整的播放状态机(idle, ready, loading, playing, paused, ended, error)
  • 实时播放统计信息
  • 网络质量指标监控
  • 缓冲状态检测
  • 错误处理与恢复

事件系统

  • 完整的视频元素事件
  • 适配器特定事件(连接、重连、缓冲等)
  • 自定义事件支持
  • 一次性事件监听

WHEP 特性

  • WebRTC 连接管理
  • ICE 候选收集
  • 自动重连机制(指数退避)
  • 连接状态监控
  • 实时网络统计
  • 资源清理

FLV 特性

  • flv.js 动态加载
  • 直播/点播支持
  • 统计信息收集
  • 带宽自适应
  • 错误处理

DASH/HLS 特性

  • Shaka Player 动态加载
  • 自适应码率(ABR)
  • 多清晰度切换
  • DRM 支持
  • 宽带估计
  • 轨道管理

使用方法

基本使用

import { PlayerCore } from '@mm-custom/player';

// 创建视频元素
const video = document.getElementById('video') as HTMLVideoElement;

// 创建播放器实例
const player = new PlayerCore(video, {
  url: 'https://example.com/stream.m3u8',
  autoplay: false,
  muted: false,
  bandwidthMode: 'high',
  adapter: 'shaka' // 'whep', 'flv', or 'shaka'
});

// 加载媒体
await player.load({ url: 'https://example.com/stream.m3u8' });

// 播放
await player.play();

// 暂停
player.pause();

// 获取当前时间
const currentTime = player.getCurrentTime();

// 跳转
await player.seek(30);

事件监听

// 监听播放事件
player.on('playing', () => {
  console.log('开始播放');
});

// 监听暂停事件
player.on('pause', () => {
  console.log('暂停播放');
});

// 监听错误事件
player.on('error', (error) => {
  console.error('播放错误:', error);
});

// 监听缓冲事件
player.on('buffering', (isBuffering) => {
  console.log(isBuffering ? '开始缓冲' : '缓冲结束');
});

// 监听网络统计
player.on('monitoring:metrics', (metrics) => {
  console.log('网络指标:', metrics);
});

// 一次性监听
player.once('loaded', () => {
  console.log('媒体加载完成');
});

WHEP 播放

const player = new PlayerCore(video, {
  url: 'https://whep-server.com/stream',
  adapter: 'whep',
  rtcConfig: {
    iceServers: [
      { urls: 'stun:stun.l.google.com:19302' }
    ]
  }
});

await player.load({ url: 'https://whep-server.com/stream' });
await player.play();

// 设置重连配置
player.setReconnectConfig({
  maxAttempts: 5,
  delay: 2000,
  backoffFactor: 2,
  maxDelay: 30000
});

// 获取连接状态
console.log(player.getConnectionState());

FLV 播放

const player = new PlayerCore(video, {
  url: 'https://example.com/stream.flv',
  adapter: 'flv',
  bandwidthMode: 'low' // 直播模式
});

await player.load({ url: 'https://example.com/stream.flv' });
await player.play();

DASH/HLS 播放

const player = new PlayerCore(video, {
  url: 'https://example.com/stream.mpd',
  adapter: 'shaka'
});

await player.load({ url: 'https://example.com/stream.mpd' });
await player.play();

// 获取可用清晰度
const levels = player.getQualityLevels();
console.log('可用清晰度:', levels);

// 切换清晰度
player.switchQuality(1);

API 文档

PlayerCore

构造函数

方法

| 方法 | 说明 | 返回值 | |-----------------------------------|----------|--------------------| | load(config) | 加载媒体源 | Promise<void> | | play() | 开始播放 | Promise<void> | | pause() | 暂停播放 | void | | stop() | 停止播放 | void | | destroy() | 销毁播放器 | void | | seek(time) | 跳转到指定时间 | Promise<void> | | switchQuality(level) | 切换清晰度 | void | | setVolume(volume) | 设置音量 | void | | getVolume() | 获取当前音量 | number | | setMuted(muted) | 设置静音状态 | void | | getMuted() | 获取静音状态 | boolean | | setPlaybackRate(rate) | 设置播放速度 | void | | getPlaybackRate() | 获取播放速度 | number | | getStats() | 获取播放统计 | PlaybackStats | | getNetworkMetrics() | 获取网络指标 | NetworkMetrics | | getState() | 获取播放状态 | PlayState | | getCurrentTime() | 获取当前时间 | number | | getDuration() | 获取总时长 | number | | getQualityLevels() | 获取清晰度列表 | any[] | | getVideoElement() | 获取视频元素 | HTMLVideoElement | | captureFrame(type, quality) | 图片截图 | string | | requestFullscreen() | 全屏播放 | Promise<void> | | exitFullscreen() | 退出全屏 | Promise<void> | | loadTextTrack(src, label, lang) | 加载字幕 | TextTrack | | on(name, listener, remove) | 注册事件监听器 | void | | off(name, listener) | 移除事件监听器 | void | | once(name, listener) | 注册一次性监听器 | void | | emit(name, data) | 触发事件 | void | | clear(name) | 清除事件监听器 | void |

配置选项

PlayerConfig

interface PlayerConfig {
  url?: string | string[];           // 媒体资源URL
  autoplay?: boolean;                // 自动播放
  muted?: boolean;                   // 静音
  loop?: boolean;                    // 循环播放
  preload?: 'auto' | 'metadata' | 'none';  // 预加载策略
  adapter?: 'whep' | 'flv' | 'shaka';      // 适配器类型
  bandwidthMode?: 'low' | 'high';    // 带宽模式
  rtcConfig?: RTCConfiguration;      // WebRTC配置
}

支持的事件

视频元素事件

  • loadedmetadata - 元数据加载完成
  • canplay - 可以播放
  • canplaythrough - 可以流畅播放
  • play - 开始播放
  • pause - 暂停播放
  • ended - 播放结束
  • timeupdate - 时间更新
  • progress - 缓冲进度
  • error - 错误
  • waiting - 等待缓冲
  • playing - 恢复播放
  • ratechange - 播放速度变化
  • volumechange - 音量变化
  • seeking - 开始跳转
  • seeked - 跳转结束
  • resize - 尺寸变化

适配器特定事件

  • loaded - 媒体加载完成
  • loading - 开始加载
  • playing - 开始播放
  • buffering - 缓冲状态变化
  • statechange - 状态变化
  • stats - 统计数据更新
  • monitoring:metrics - 监控指标更新

WHEP 特定事件

  • connecting - 连接中
  • connected - 已连接
  • disconnected - 连接断开
  • reconnecting - 重连中
  • reconnected - 重连成功
  • reconnectfailed - 重连失败

错误处理

播放器使用统一的错误处理机制:

interface PlayerError extends Error {
  code: PlayerErrorType;      // 错误类型
  fatal: boolean;              // 是否致命错误
  timestamp: number;           // 时间戳
  details?: any;               // 详细信息
}

enum PlayerErrorType {
  NETWORK_ERROR = 'network',
  MEDIA_ERROR = 'media',
  DECODER_ERROR = 'decoder',
  ADAPTER_ERROR = 'adapter',
  CONFIG_ERROR = 'config',
  UNKNOWN_ERROR = 'unknown'
}

类型定义

PlaybackStats

interface PlaybackStats {
  buffered: number;      // 已缓冲时长
  currentTime: number;   // 当前播放位置
  duration: number;      // 媒体总时长
  playbackRate: number;  // 播放速率
  volume: number;        // 音量大小
  paused: boolean;       // 暂停状态
  ended: boolean;        // 播放结束状态
}

NetworkMetrics

interface NetworkMetrics {
  bandwidth: number;       // 可用带宽
  bufferingTime: number;   // 缓冲耗时
  segmentsLoaded: number;  // 已加载片段数
  segmentsFailed: number;  // 加载失败片段数
  latency: number;         // 网络延迟
  bitrate: number;         // 当前码率
}

许可证

ISC