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

mstf-kit

v0.5.0

Published

一个现代化的 JavaScript/TypeScript 工具库,提供了丰富的常用工具函数

Downloads

249

Readme

mstf-kit

English | 简体中文

一个现代化的 JavaScript/TypeScript 工具库,提供了丰富的常用工具函数。

✨ 特性

  • 📦 支持 Tree Shaking
  • 🔧 TypeScript 支持
  • 📚 完整的类型定义
  • 🎯 模块化设计
  • 💪 全面的测试覆盖
  • 📝 详细的文档
  • 🔒 代码混淆保护

📦 安装

npm install mstf-kit
# 或
yarn add mstf-kit
# 或
pnpm add mstf-kit

🚀 使用方法

// 导入所需的工具函数
import { formatDate, isEmail } from 'mstf-kit';

// 使用日期格式化
const date = formatDate(new Date(), 'YYYY-MM-DD');
console.log(date); // 2024-03-10

// 验证邮箱
const isValidEmail = isEmail('[email protected]');
console.log(isValidEmail); // true

按需导入

为了减小打包体积,推荐使用 tree-shaking 按需导入具体的工具函数:

// 只导入需要的函数
import { capitalize, truncate } from 'mstf-kit';
import { formatDate } from 'mstf-kit';
import { createLottiePlayer } from 'mstf-kit';

// 不要这样导入整个库
// import * as mstfKit from 'mstf-kit'; // ❌ 不推荐

现代打包工具(如 webpack、rollup、vite)会自动进行 tree-shaking,只打包您实际使用的代码。

📚 API 文档

🔤 字符串工具 (String Utils)

字符串处理相关的工具函数。

  • capitalize(str: string): string - 首字母大写
  • camelCase(str: string): string - 转换为驼峰命名
  • truncate(str: string, length: number): string - 截断字符串

🔢 数字工具 (Number Utils)

数字处理和计算相关的工具函数。

  • formatNumber(num: number, locale?: string): string - 数字格式化
  • round(num: number, decimals?: number): number - 四舍五入
  • clamp(num: number, min: number, max: number): number - 限制数字范围
  • random(min: number, max: number, isInteger?: boolean): number - 生成随机数
  • percentage(value: number, total: number, decimals?: number): number - 计算百分比

📋 数组工具 (Array Utils)

数组操作和处理的工具函数。

  • unique<T>(arr: T[]): T[] - 数组去重
  • groupBy<T>(arr: T[], key: string | ((item: T) => string)): Record<string, T[]> - 数组分组
  • flatten<T>(arr: any[], depth?: number): T[] - 数组扁平化
  • sample<T>(arr: T[], count?: number): T | T[] - 随机采样
  • shuffle<T>(arr: T[]): T[] - 数组乱序
  • closest(arr: number[], target: number): number - 查找最接近的值

📦 对象工具 (Object Utils)

对象操作和处理的工具函数。

  • deepClone<T>(obj: T): T - 深拷贝
  • get(obj: any, path: string | string[], defaultValue?: any): any - 获取嵌套属性
  • set(obj: any, path: string | string[], value: any): void - 设置嵌套属性
  • pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> - 选择属性
  • omit<T, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> - 排除属性
  • merge<T>(...objects: T[]): T - 对象合并

📅 日期工具 (Date Utils)

日期和时间处理的工具函数。

  • formatDate(date: Date | number | string, format?: string): string - 日期格式化
  • getRelativeTime(date: Date | number | string, now?: Date): string - 相对时间
  • getDateRange(start: Date | number | string, end: Date | number | string): Date[] - 日期范围
  • addTime(date: Date | number | string, amount: number, unit: string): Date - 添加时间
  • isSameDay(date1: Date | number | string, date2: Date | number | string): boolean - 判断同一天

✅ 验证工具 (Validation Utils)

数据验证相关的工具函数。

  • isEmail(email: string): boolean - 验证邮箱
  • isChinesePhone(phone: string): boolean - 验证手机号(中国大陆)
  • isChineseIdCard(idCard: string): boolean - 验证身份证号(中国大陆)
  • isUrl(url: string): boolean - 验证URL
  • isIPv4(ip: string): boolean - 验证IPv4地址
  • validatePassword(password: string, options?: object): boolean - 验证密码强度
  • isSafeString(str: string): boolean - 验证XSS安全

🛠️ 工具类 (Utils)

📝 Logger 日志工具

统一的日志工具类,提供可配置的日志输出功能。支持多种日志级别、时间戳、自定义前缀等特性。

import { createLogger, LogLevel } from 'mstf-kit';

// 创建 Logger
const logger = createLogger({
  enabled: true,
  prefix: '[MyApp]',
  level: LogLevel.DEBUG,
  showTimestamp: true
});

// 使用日志
logger.log('应用启动');
logger.warn('这是一条警告');
logger.error('这是一条错误');

// 创建子 Logger
const authLogger = logger.createChild('Auth');
authLogger.log('用户登录'); // [MyApp:Auth] 用户登录

📖 查看 Logger 完整文档

🎵 音频处理 (Audio)

非流式音频处理 (audioNonStream)

处理非流式接口返回的音频数据,支持多种数据格式(Base64、Blob、ArrayBuffer、File)和灵活的字段路径提取。

import { processNonStreamAudio } from 'mstf-kit';

// 处理嵌套字段的 Base64 数据
const response = {
  msg: 'success',
  code: 200,
  data: {
    audio: 'UklGRiQAAABXQVZFZm10...' // Base64音频数据
  }
};

const result = await processNonStreamAudio(response, {
  audioField: 'data.audio',  // 指定音频数据的路径
  dataType: 'base64',        // 指定数据类型
  mimeType: 'audio/wav',     // 指定MIME类型
  autoPlay: true             // 自动播放
});

console.log('音频URL:', result.url);
console.log('音频大小:', result.size);

📖 查看非流式音频处理完整文档

流式音频处理器 V2 (audioStreamV2)

新版流式音频处理器,支持有头部和无头部两种流式音频格式,提供更灵活的配置。

import { processStreamAudioV2 } from 'mstf-kit';

// 处理流式音频
const response = await fetch('/api/audio/stream');
const reader = response.body.getReader();

const { pause, resume, abort, isPlaying } = await processStreamAudioV2(reader, {
  autoPlay: true,
  dataFormat: 'auto',          // 自动检测格式:'with-header' | 'without-header' | 'auto'
  audioField: 'data.audio',
  debug: true,
  
  onStart: () => console.log('开始播放'),
  onEnded: () => console.log('播放结束'),
  onAudioData: (blob) => console.log('收到音频块:', blob.size)
});

// 控制播放
pauseButton.onclick = () => pause();
playButton.onclick = () => resume();

主要特性:

  • 支持有头部格式(每个块都有完整头部)
  • 支持无头部格式(只有第一个块有头部)
  • 自动格式检测
  • 集成 Logger 日志系统
  • 完整的 TypeScript 类型支持

📖 查看流式音频处理器 V2 完整文档

音频流处理 (audioStream)

音频流处理工具,用于处理音频数据流,支持ArrayBuffer和流式数据,并提供自动播放功能。

import { 
  createAudioStreamHandler, 
  handleAudioBuffer, 
  createAudioHandlers 
} from 'mstf-kit';

// 示例1: 处理ArrayBuffer响应
const response = await axios.post('/api/voice/synthesize', {
  voice_id: 'my-voice',
  text: '你好,世界!'
}, {
  responseType: 'arraybuffer',
  headers: { Accept: 'audio/mp3' }
});

// 方式1: 直接处理
const { blob, url, handler } = await handleAudioBuffer(response, {
  mimeType: 'audio/mp3',
  autoPlay: true,
  logLevel: 'debug'
});

// 示例2: 处理流式数据
// 创建处理器
const audioHandler = createAudioStreamHandler({
  mimeType: 'audio/mp3',
  logLevel: 'debug'
});

// 示例3: 最简单的方式 (一步到位)
const { config, handler } = createAudioHandlers(
  {
    responseType: 'arraybuffer',
    headers: { Accept: 'audio/mp3' }
  },
  {
    mimeType: 'audio/mp3',
    autoPlayOnComplete: true,
    logLevel: 'debug'
  }
);

// 使用增强的配置发送请求
const response = await axios.post('/api/voice/synthesize', data, config);

轻量级音频请求处理 (audioRequest)

轻量级音频处理工具,专注于处理流式和非流式音频数据,无需额外依赖,支持各种响应格式。

import { 
  processStreamResponse, 
  processArrayBuffer, 
  processBlob,
  processBase64Audio,
  createBase64StreamProcessor
} from 'mstf-kit';

// 示例1: 使用fetch和getReader处理流式响应
const response = await fetch('https://api.example.com/audio/stream', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ text: '要合成的文本' })
});

// 获取响应流的Reader
const reader = response.body.getReader();
// 处理流式音频数据
const { pause, resume, abort, isPlaying, finalBlob } = await processStreamResponse(reader, {
  autoPlay: true,             // 自动播放
  returnBlob: true,           // 返回完整Blob
  audioField: 'data.audio',   // 音频数据在响应中的路径
  onStart: () => {            // 音频开始播放回调
    console.log('音频开始播放');
    playButton.classList.add('playing');
  },
  onEnded: () => {            // 音频播放结束回调
    console.log('音频播放结束');
    playButton.classList.remove('playing');
    statusElement.textContent = '播放完成';
  },
  onAudioData: (blob) => {     // 接收到新音频块时的回调
    console.log('收到音频数据块:', blob.size);
  },
  onComplete: (blob) => {      // 处理完成回调
    if (blob) {
      console.log('完整音频大小:', blob.size);
    }
  }
});

// 播放控制
pauseButton.addEventListener('click', () => {
  pause();
  playButton.classList.remove('playing');
});

playButton.addEventListener('click', () => {
  resume();
  playButton.classList.add('playing');
});

// 监控播放状态
setInterval(() => {
  const playing = isPlaying();
  statusElement.textContent = playing ? '播放中' : '已暂停';
}, 100);

// 中止处理
cancelButton.addEventListener('click', () => {
  abort();
});

// 获取完整音频
if (finalBlob) {
  const blob = await finalBlob;
  const url = URL.createObjectURL(blob);
  audio.src = url;
}

支持的选项:

// 音频处理选项
{
  autoPlay?: boolean;         // 是否自动播放
  returnBlob?: boolean;       // 是否返回完整Blob
  mimeType?: string;          // MIME类型,默认为'audio/wav'
  audioField?: string;        // 音频数据字段路径,如'data.audio'
  onAudioData?: (audioBlob: Blob) => void;      // 接收到音频数据回调
  onError?: (error: Error) => void;             // 错误回调
  onComplete?: (blob?: Blob) => void;           // 完成回调
  onStart?: () => void;                  // 音频开始播放回调
  onEnded?: () => void;                  // 音频播放结束回调
}
Axios支持

使用 Axios 处理流式和非流式音频请求:

import axios from 'axios';
import { createAxiosAudioOptions } from 'mstf-kit';

// 流式音频请求 - 创建配置
const { axiosConfig, pause, resume, abort, isPlaying, finalBlob } = createAxiosAudioOptions({
  autoPlay: true,              // 自动播放
  returnBlob: true,            // 返回完整Blob
  audioField: 'data.audio',    // 音频数据在响应JSON中的路径
  mimeType: 'audio/wav',       // 音频MIME类型
  onStart: () => {             // 音频开始播放回调
    console.log('音频开始播放');
    playButton.disabled = false;
  },
  onAudioData: (blob) => {       // 接收到音频块的回调
    console.log('收到音频数据块:', blob.size);
  }
});

// 发送请求
const response = await axios.post(
  'https://api.example.com/audio/stream',
  { text: '要合成的文本' },
  axiosConfig
);

// 控制播放
const togglePlay = () => {
  if (isPlaying()) {
    pause();
    playButton.textContent = '播放';
  } else {
    resume();
    playButton.textContent = '暂停';
  }
};

playButton.addEventListener('click', togglePlay);
自定义数据格式

可以处理多种服务器返回的数据格式:

  1. 标准格式data: {"audio":"base64数据","is_last":false}
  2. 自定义路径:通过 audioField 指定音频数据的路径
// 标准格式处理
const { pause, resume, abort, isPlaying } = await processStreamResponse(reader, {
  autoPlay: true
});

// 自定义路径处理
const { pause, resume, abort, isPlaying } = await processStreamResponse(reader, {
  autoPlay: true,
  audioField: 'result.data.audioContent' // 指定自定义路径
});

// Axios处理自定义格式
const { axiosConfig, pause, resume, abort, isPlaying } = createAxiosAudioOptions({
  autoPlay: true,
  audioField: 'response.voice.content'
});

智能数据提取:如果未指定 audioField,将自动尝试从以下位置提取音频数据:

  • 直接以字符串形式提供的数据
  • 对象的 audio 属性
  • 嵌套在 data.audio 中的数据
停止/中止处理

支持通过AbortController中止处理过程:

// 创建AbortController
const controller = new AbortController();
const signal = controller.signal;

// 方法1: 通过配置传入
const { config, handler } = createAudioHandlers(
  { /* axios配置 */ },
  { 
    abortSignal: signal,
    // 其他选项...
  }
);

// 方法2: 直接设置
audioHandler.setAbortSignal(signal);

// 方法3: 直接调用abort方法
audioHandler.abort();

// 在需要中止时:
controller.abort(); // 这将触发中止处理
控制播放
// 暂停播放
handler.pause();

// 恢复播放
handler.resume();

// 停止播放
handler.stop();

// 设置音量 (0-1)
handler.setVolume(0.5);

// 释放资源
handler.release();
配置选项

AudioStreamOptions 支持以下选项:

{
  // 日志级别: 'none' | 'error' | 'warn' | 'info' | 'debug'
  logLevel?: LogLevel;
  
  // 是否自动播放
  autoPlay?: boolean;
  
  // 自定义的MIME类型
  mimeType?: string;
  
  // 是否循环播放
  loop?: boolean;
  
  // 初始音量 (0-1)
  volume?: number;
  
  // 播放完成回调
  onEnded?: () => void;
  
  // 播放错误回调
  onError?: (error: Error) => void;
  
  // 播放开始回调
  onPlay?: () => void;
  
  // 播放进度回调
  onProgress?: (currentTime: number, duration: number) => void;
  
  // 数据加载回调
  onDataLoaded?: (blob: Blob) => void;
  
  // 处理被中止回调
  onAborted?: () => void;
}

DownloadProgressConfig 支持以下选项:

{
  // 是否需要解析处理
  needParse?: boolean;
  
  // 音频数据路径,如 "audio.b"
  audioPath?: string;
  
  // MIME类型
  mimeType?: string;
  
  // 是否在接收到第一块数据时自动播放
  autoPlayOnFirstChunk?: boolean;
  
  // 是否在下载完成时自动播放
  autoPlayOnComplete?: boolean;
  
  // 用于停止处理的AbortSignal
  abortSignal?: AbortSignal;
}

🔊 音频播放器

mstf-kit 提供了功能强大的音频播放工具,支持背景播放和页面渲染两种模式:

背景播放模式

import { createAudioPlayer, playAudio } from 'mstf-kit';

// 简易播放方式
const audioBlob = new Blob([...]); // 音频数据
const player = await playAudio(audioBlob, {
  volume: 0.8,
  loop: true
});

// 或使用完整API
const backgroundPlayer = createAudioPlayer();
await backgroundPlayer.load('https://example.com/audio.mp3');
await backgroundPlayer.play();

// 控制播放
backgroundPlayer.pause();
backgroundPlayer.setVolume(0.5);
backgroundPlayer.seek(30); // 跳转到30秒位置

页面渲染模式

import { createAudioPlayer, AUDIO_FORMATS } from 'mstf-kit';

// 创建一个带UI界面的播放器
const uiPlayer = createAudioPlayer({
  renderUI: true,           // 启用UI渲染
  container: '#player-box', // 指定容器元素
  theme: 'dark',            // 使用暗色主题
  showVisualization: true,  // 显示音频可视化
  visualizationType: 'bars' // 使用柱状频谱图
});

// 加载音频
await uiPlayer.load(audioBlob);
await uiPlayer.play();

// 播放结束后的回调
uiPlayer.onEnded = () => {
  console.log('播放完成');
};

// 不需要时释放资源
uiPlayer.destroy();

Vue 集成

与 Vue3 框架无缝集成,支持直接使用 ref 作为容器:

import { ref, onMounted, onUnmounted } from 'vue';
import { createAudioPlayer } from 'mstf-kit';

export default {
  setup() {
    // 创建容器引用
    const playerContainer = ref(null);
    let audioPlayer = null;
    
    onMounted(async () => {
      // 创建播放器并使用ref作为容器
      audioPlayer = createAudioPlayer({
        renderUI: true,
        container: playerContainer, // 直接传入ref
        theme: 'dark',
        showVisualization: true
      });
      
      // 加载并播放音频
      await audioPlayer.load('/audio/example.mp3');
      await audioPlayer.play();
    });
    
    // 组件卸载时清理资源
    onUnmounted(() => {
      if (audioPlayer) {
        audioPlayer.destroy();
      }
    });
    
    return { playerContainer };
  }
}

可视化类型

播放器支持三种可视化类型:

  • waveform: 波形图显示
  • bars: 频谱柱状图
  • circle: 圆形频谱图

支持的主题

  • default: 默认主题(浅色)
  • dark: 暗色主题
  • minimal: 简约主题(透明背景)

🎭 Lottie动画

mstf-kit 支持 Lottie 动画的加载、渲染和控制,可以轻松地在您的应用中展示高质量的矢量动画。

基本使用

import { createLottiePlayer, playLottie } from 'mstf-kit';

// 快速加载并播放Lottie动画
const player = await playLottie(
  'https://assets.lottiefiles.com/packages/lf20_UJNc2t.json',
  '#animation-container',
  { loop: true, speed: 1.5 }
);

// 或使用完整API
const lottiePlayer = await createLottiePlayer({
  container: '#animation-container',
  renderer: 'canvas', // dotlottie-web 使用 canvas 渲染
  loop: true,
  autoplay: true
});

// 加载动画
await lottiePlayer.load('https://assets.lottiefiles.com/packages/lf20_UJNc2t.json');

// 控制动画
lottiePlayer.pause();
lottiePlayer.setSpeed(2.0);
lottiePlayer.play();

Vue 集成

与 Vue3 框架无缝集成,支持直接使用 ref 作为容器:

import { ref } from 'vue';
import { playLottie } from 'mstf-kit';

export default {
  setup() {
    // 创建容器引用
    const animationContainer = ref(null);
    
    // 加载动画(在onMounted中)
    onMounted(async () => {
      const player = await playLottie(
        'https://assets.lottiefiles.com/packages/lf20_UJNc2t.json',
        animationContainer,
        { loop: true }
      );
    });
    
    return { animationContainer };
  }
}

多种库加载模式

支持多种加载方式:

// 默认使用内置的 dotlottie-web
const player1 = await createLottiePlayer({
  container: '#animation-container',
  loop: true
});

// 使用自定义外部库
import customLottieLib from 'custom-lottie-lib';
const player2 = await createLottiePlayer({
  container: '#animation-container',
  libOptions: {
    source: 'external',
    externalLib: customLottieLib
  }
});

// 从CDN加载
const player3 = await createLottiePlayer({
  container: '#animation-container',
  libOptions: {
    source: 'cdn',
    cdnURL: 'https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web/+esm'
  }
});

渲染模式

Lottie播放器默认使用Canvas渲染模式,提供高性能的动画播放体验。

动画控制

播放器支持丰富的控制方法:

// 播放控制
player.play();
player.pause();
player.stop();

// 播放速度和方向
player.setSpeed(1.5);  // 1.5倍速
player.setDirection(-1); // 反向播放

// 跳转控制
player.goToFrame(24);  // 跳转到第24帧
player.goToAndPlay(24); // 跳转并播放
player.setSegment(10, 50); // 只播放10-50帧

// 循环控制
player.setLoop(true);  // 无限循环
player.setLoop(3);     // 循环3次

// 动画信息
console.log(`总帧数: ${player.getTotalFrames()}`);
console.log(`当前帧: ${player.getCurrentFrame()}`);
console.log(`时长: ${player.getDuration()}ms`);
console.log(`是否播放中: ${player.isPlaying()}`);

// 资源释放
player.destroy();

高级特性

  • 小巧高效: 使用 dotlottie-web 库,体积更小,性能更好
  • 多种库来源: 支持内置库(默认)、CDN加载或外部提供的自定义库
  • Vue框架支持: 无缝支持Vue3的ref作为容器引用
  • 多种来源: 支持从URL、JSON字符串或对象加载动画
  • 动画事件: 提供丰富的回调函数,可监听动画状态变化
  • 响应式: 通过resize()方法支持自适应容器大小

🎬 Plyr 播放器 (plyrPlayer)

提供对 Plyr 媒体播放器的封装,支持视频和音频播放,带有丰富的功能和易用的 API。

import { createPlyrPlayer, playWithPlyr, createPlaylist } from 'mstf-kit';

// 快速创建简单播放器
const player = await playWithPlyr(
  'https://example.com/video.mp4',
  '#player-container',
  { autoplay: true, muted: true }
);

// 使用完整 API
const advancedPlayer = await createPlyrPlayer({
  container: '#player-container',
  source: {
    type: 'video',
    title: '示例视频',
    sources: [
      {
        src: 'https://example.com/video.mp4',
        type: 'video/mp4'
      }
    ],
    poster: 'https://example.com/poster.jpg'
  },
  controls: ['play', 'progress', 'current-time', 'mute', 'volume', 'settings', 'fullscreen'],
  i18n: {
    play: '播放',
    pause: '暂停',
    mute: '静音',
    volume: '音量'
  }
});

// 访问增强功能
await advancedPlayer.play();
advancedPlayer.addMarker(30, '重要时刻');
const screenshot = advancedPlayer.getCaptureImage();
advancedPlayer.downloadMedia('视频.mp4');

Vue 集成

无缝支持 Vue3 的 ref 作为容器引用:

import { ref, onMounted } from 'vue';
import { createPlyrPlayer } from 'mstf-kit';

export default {
  setup() {
    const playerRef = ref(null);
    let player = null;
    
    onMounted(async () => {
      player = await createPlyrPlayer({
        container: () => playerRef.value, // 使用函数返回 ref 引用的元素
        source: { /* 媒体源配置 */ }
      });
    });
    
    return { playerRef };
  }
}

播放列表支持

// 创建播放列表
const { player, next, previous, playIndex } = await createPlaylist(
  [
    'https://example.com/video1.mp4',
    'https://example.com/audio1.mp3',
    {
      type: 'video',
      sources: [{ src: 'https://example.com/video2.mp4', type: 'video/mp4' }]
    }
  ],
  '#playlist-container',
  { loop: { active: true } }
);

// 播放控制
next();       // 播放下一个
previous();   // 播放上一个
playIndex(2); // 播放指定索引的媒体

主要特性

  • 多种加载模式: 支持 CDN、npm 或外部提供的 Plyr 库
  • 增强功能: 截图捕获、纵横比控制、标记点、画中画等
  • Vue 集成: 直接支持 Vue ref 作为容器
  • 播放列表: 支持混合媒体类型的播放列表
  • 中文本地化: 内置中文界面文本支持
  • 丰富事件: 提供完整的事件回调系统
  • TypeScript: 完整的类型定义

支持的配置选项

  • 自定义控件: 可定制控制栏按钮
  • 视频比例: 支持多种纵横比设置
  • 播放速度: 可调节的播放速率
  • 字幕: 支持多语言字幕轨道
  • 质量切换: 支持视频质量选择
强大的增强功能
// 修改播放比例
player.changeAspectRatio('16:9');

// 进入画中画模式
await player.enterPictureInPicture();

// 添加时间轴标记
player.addMarker(45, '精彩片段', 'red');

// 截取当前画面
const imageDataUrl = player.getCaptureImage();

// 下载媒体文件
player.downloadMedia('downloaded-video.mp4');

// 自定义快捷键
player.addShortcut('m', () => player.toggleMute());

配置选项详解

控制栏按钮 (controls)

可用的控制栏按钮选项:

controls: [
  'play-large',  // 大播放按钮
  'play',        // 播放/暂停按钮
  'progress',    // 进度条
  'current-time', // 当前时间
  'duration',    // 总时长
  'mute',        // 静音按钮
  'volume',      // 音量控制
  'captions',    // 字幕按钮
  'settings',    // 设置按钮
  'pip',         // 画中画按钮
  'airplay',     // AirPlay按钮
  'fullscreen',  // 全屏按钮
  'restart',     // 重新播放按钮
  'fast-forward', // 快进按钮
  'rewind'       // 快退按钮
]
完整配置选项
// 完整的播放器配置选项
{
  // 基本配置
  container: '#player', // 播放器容器(字符串选择器、DOM元素或返回DOM元素的函数)
  source: {             // 媒体源配置
    type: 'video',      // 'video' 或 'audio'
    title: '视频标题',   // 媒体标题
    sources: [          // 媒体源列表
      {
        src: 'https://example.com/video.mp4',
        type: 'video/mp4',
        size: 720       // 清晰度标识(像素高度)
      }
    ],
    poster: 'https://example.com/poster.jpg', // 视频封面图片URL
    tracks: [           // 字幕/章节轨道
      {
        kind: 'captions',
        label: '中文',
        src: 'https://example.com/captions.zh.vtt',
        srclang: 'zh',
        default: true
      }
    ]
  },
  autoplay: false,      // 是否自动播放
  muted: false,         // 是否静音
  loop: { active: false }, // 是否循环播放
  volume: 1.0,          // 默认音量(0-1)
  
  // UI配置
  controls: ['play', 'progress', 'current-time', 'mute', 'volume', 'settings', 'fullscreen'],
  hideControls: true,   // 是否自动隐藏控制栏
  resetOnEnd: false,    // 播放结束后是否重置
  fullscreen: {         // 全屏设置
    enabled: true,      // 是否启用全屏
    fallback: true,     // 如果浏览器不支持原生全屏,是否使用回退方案
    iosNative: true     // 在iOS上使用原生全屏
  },
  ratio: '16:9',        // 视频比例
  storage: {            // 本地存储
    enabled: true,      // 是否启用存储
    key: 'plyr-volume'  // 存储键名
  },
  speed: {              // 播放速度设置
    selected: 1,        // 默认速度
    options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] // 可选速度列表
  },
  quality: {            // 视频质量设置
    default: '720',     // 默认质量
    options: ['1080', '720', '480', '360'] // 可选质量列表(对应sources中的size)
  },
  invertTime: false,    // 是否反转时间显示(显示剩余时间)
  displayDuration: true, // 是否显示总时长
  markers: {            // 时间轴标记点
    enabled: true,      // 是否启用标记点
    points: [           // 标记点列表
      {
        time: 15,       // 标记点时间(秒)
        label: '精彩片段', // 标记点标签
        color: 'red'    // 标记点颜色
      }
    ]
  },
  
  // 本地化文本
  i18n: {
    restart: '重播',
    play: '播放',
    pause: '暂停',
    volume: '音量',
    mute: '静音',
    unmute: '取消静音',
    pip: '画中画',
    normal: '默认',
    settings: '设置',
    speed: '速度',
    quality: '质量',
    loop: '循环',
    start: '开始',
    end: '结束',
    all: '全部',
    reset: '重置',
    disabled: '禁用',
    enabled: '启用',
    advertisement: '广告',
    qualityLabel: {
      1080: '1080p',
      720: '720p',
      480: '480p',
      360: '360p'
    },
    captions: '字幕',
    download: '下载',
    enterFullscreen: '全屏',
    exitFullscreen: '退出全屏'
  },
  
  // 调试设置
  debug: false,         // 是否开启调试模式
  loadSprite: true      // 是否加载SVG雪碧图
}
createPlyrPlayer 特有选项
// 创建Plyr播放器的额外选项
{
  // Plyr库加载选项
  plyrLibOptions: {
    source: 'npm', // 从哪里加载Plyr库: 'cdn'(默认), 'npm', 'local', 'external'
    cdnUrl: 'https://unpkg.com/[email protected]/dist/plyr.min.js', // 自定义CDN URL
    cssUrl: 'https://unpkg.com/[email protected]/dist/plyr.css',    // 自定义CSS URL
    externalLib: null // 外部提供的Plyr库实例(当source为'external'时使用)
  },
  initOnLoad: true,     // 是否在加载时立即初始化
  autoCreateCss: true   // 是否自动引入CSS
}

增强型播放器API

创建的增强型Plyr播放器提供以下API:

// 基础播放控制
player.play();            // 播放
player.pause();           // 暂停
player.stop();            // 停止
player.restart();         // 重新播放
player.rewind(10);        // 后退10秒
player.forward(10);       // 前进10秒
player.increaseVolume(0.1); // 增加10%音量
player.decreaseVolume(0.1); // 减少10%音量
player.togglePlay();      // 切换播放/暂停
player.toggleMute();      // 切换静音/非静音

// 状态获取
player.isPlaying();       // 是否正在播放
player.isPaused();        // 是否已暂停
player.playing;           // 播放状态
player.paused;            // 暂停状态
player.stopped;           // 停止状态

// 媒体属性
player.volume = 0.8;      // 设置音量(0-1)
player.muted = true;      // 设置静音
player.currentTime = 30;  // 设置当前播放位置(秒)
player.speed = 1.5;       // 设置播放速度

// 增强功能
player.getContainer();    // 获取容器元素
player.getDefaultOptions(); // 获取默认选项
player.setSource(newSource); // 设置新媒体源
player.changeAspectRatio('4:3'); // 修改视频比例
player.addShortcut('m', () => player.toggleMute()); // 添加快捷键
player.getCaptureImage(); // 截取当前画面
player.downloadMedia('video.mp4'); // 下载媒体
player.setPoster('https://example.com/poster.jpg'); // 设置视频封面
player.isFullscreen();    // 是否全屏
player.enterPictureInPicture(); // 进入画中画模式
player.exitPictureInPicture();  // 退出画中画模式
player.togglePictureInPicture(); // 切换画中画模式
player.reload();          // 重新加载媒体
player.getQualityOptions(); // 获取可用质量选项
player.setQuality('720'); // 设置视频质量
player.getSpeedOptions(); // 获取可用速度选项
player.setCustomControls(['play', 'volume']); // 设置自定义控制栏
player.addMarker(45, '精彩片段'); // 添加时间轴标记
player.removeMarker(45);  // 移除标记
player.clearMarkers();    // 清除所有标记

// 事件监听
player.on('play', () => console.log('开始播放'));
player.once('ended', () => console.log('播放结束'));
player.off('play', callback); // 移除事件监听

播放列表API

// 播放列表控制器
const { 
  player,                   // 播放器实例
  next,                     // 播放下一个函数
  previous,                 // 播放上一个函数
  playIndex,                // 播放指定索引函数
  currentIndex,             // 当前播放索引
  sources                   // 媒体源列表
} = await createPlaylist(sources, container, options);

// 使用举例
next();                     // 播放下一个
previous();                 // 播放上一个
playIndex(2);               // 播放索引为2的媒体
const currentPlaying = sources[currentIndex]; // 获取当前播放的媒体信息

适用场景

  • 视频教学平台: 创建支持视频标记、截图和高级控制的视频播放器
  • 在线视频点播: 构建支持多清晰度、字幕和自定义UI的专业播放器
  • 音频播放应用: 结合播放列表功能创建音频播放器
  • 混合媒体展示: 支持在同一播放器中无缝切换视频和音频
  • Vue应用集成: 在Vue应用中轻松集成高级媒体播放功能

🔌 WebSocket 工具 (WebSocket Utils)

提供高效可靠的 WebSocket 连接管理和通信工具。

  • createWebSocketClient(options: WebSocketOptions): WebSocketClient - 创建一个 WebSocket 客户端
  • isWebSocketSupported(): boolean - 检查当前环境是否支持 WebSocket

WebSocket 客户端 API

WebSocket 客户端 (WebSocketClient) 提供以下核心功能:

  • 自动重连 - 网络中断时自动尝试重新连接
  • 心跳检测 - 保持连接活跃并检测断线
  • 消息队列 - 离线时自动缓存消息,连接恢复后发送
  • 消息优先级 - 支持高、中、低三种优先级消息处理
  • 事件系统 - 提供丰富的事件监听接口
  • 批量发送 - 支持消息批处理以优化网络传输
  • 超时处理 - 自动处理消息超时和重试
  • 完整指标 - 提供详细的连接和性能统计数据

基本使用示例

import { WebSocketClient, WebSocketState, MessagePriority } from 'mstf-kit';

// 创建 WebSocket 客户端
const ws = new WebSocketClient({
  url: 'wss://example.com/socket',
  protocols: ['v1'],
  debug: true,               // 启用调试日志
  connectionTimeout: 8000,   // 连接超时 (ms)
  
  // 心跳配置
  heartbeat: {
    enabled: true,
    interval: 30000,         // 每30秒发送一次心跳
    message: { type: 'ping' },
    timeout: 5000            // 心跳5秒无响应判定为超时
  },
  
  // 自动重连配置
  reconnect: {
    enabled: true,
    maxRetries: 10,          // 最多重试10次
    initialDelay: 1000,      // 初始重试延迟1秒
    maxDelay: 30000,         // 最大重试延迟30秒
    factor: 1.5,             // 指数退避系数
    jitter: 0.5              // 随机抖动系数
  }
});

// 连接到服务器
ws.connect()
  .then(() => {
    console.log('连接成功');
    
    // 发送消息
    return ws.send({ type: 'hello', data: 'world' });
  })
  .catch(error => {
    console.error('连接错误:', error);
  });

// 监听消息
ws.on('message', data => {
  console.log('收到消息:', data);
});

// 监听连接状态变化
ws.on('close', event => {
  console.log('连接关闭:', event.code);
});

ws.on('reconnect', attempt => {
  console.log(`重连成功 (第${attempt}次尝试)`);
});

// 发送不同优先级的消息
ws.send(criticalData, { priority: MessagePriority.HIGH });
ws.send(normalData, { priority: MessagePriority.NORMAL });
ws.send(statsData, { priority: MessagePriority.LOW });

// 期望服务器响应的消息
ws.send({ type: 'query', id: 'user-123' }, {
  expectResponse: true,      // 等待响应
  timeout: 5000,             // 响应超时时间
  retries: 2,                // 超时后重试次数
  retryDelay: 1000           // 重试间隔
}).then(response => {
  console.log('收到响应:', response);
}).catch(error => {
  console.error('请求失败:', error);
});

// 获取连接状态和统计信息
console.log('当前状态:', ws.getState());
console.log('连接延迟:', ws.getLatency());
console.log('统计信息:', ws.getConnectionStats());

// 不再使用时销毁资源
ws.destroy();

高级特性

  • 批量消息: 适用于需要发送大量小消息的场景,自动合并为批量消息减少网络开销
  • 动态配置: 可在运行时调整心跳、重连、消息处理等配置
  • 完整生命周期管理: 自动处理资源释放,防止内存泄漏
  • 兼容性: 支持各种浏览器环境和 Node.js

更多高级用法详见 API 文档。

📄 许可证

MIT © [mustafa]