# mstf-kit **Repository Path**: xsid/mstf-kit ## Basic Information - **Project Name**: mstf-kit - **Description**: 一个现代化的 JavaScript/TypeScript 工具库,提供了丰富的常用工具函数。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: https://gitee.com/xsid/projects - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2025-03-11 - **Last Updated**: 2026-01-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mstf-kit [English](./README.en.md) | 简体中文 一个现代化的 JavaScript/TypeScript 工具库,提供了丰富的常用工具函数。 ## ✨ 特性 - 📦 支持 Tree Shaking - 🔧 TypeScript 支持 - 📚 完整的类型定义 - 🎯 模块化设计 - 💪 全面的测试覆盖 - 📝 详细的文档 - 🔒 代码混淆保护 ## 📦 安装 ```bash npm install mstf-kit # 或 yarn add mstf-kit # 或 pnpm add mstf-kit ``` ## 🚀 使用方法 ```typescript // 导入所需的工具函数 import { formatDate, isEmail } from 'mstf-kit'; // 使用日期格式化 const date = formatDate(new Date(), 'YYYY-MM-DD'); console.log(date); // 2024-03-10 // 验证邮箱 const isValidEmail = isEmail('example@email.com'); console.log(isValidEmail); // true ``` ### 按需导入 为了减小打包体积,推荐使用 tree-shaking 按需导入具体的工具函数: ```typescript // 只导入需要的函数 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(arr: T[]): T[]` - 数组去重 - `groupBy(arr: T[], key: string | ((item: T) => string)): Record` - 数组分组 - `flatten(arr: any[], depth?: number): T[]` - 数组扁平化 - `sample(arr: T[], count?: number): T | T[]` - 随机采样 - `shuffle(arr: T[]): T[]` - 数组乱序 - `closest(arr: number[], target: number): number` - 查找最接近的值 ### 📦 对象工具 (Object Utils) 对象操作和处理的工具函数。 - `deepClone(obj: T): T` - 深拷贝 - `get(obj: any, path: string | string[], defaultValue?: any): any` - 获取嵌套属性 - `set(obj: any, path: string | string[], value: any): void` - 设置嵌套属性 - `pick(obj: T, keys: K[]): Pick` - 选择属性 - `omit(obj: T, keys: K[]): Omit` - 排除属性 - `merge(...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 日志工具 统一的日志工具类,提供可配置的日志输出功能。支持多种日志级别、时间戳、自定义前缀等特性。 ```typescript 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 完整文档](./docs/logger.md)** ### 🎵 音频处理 (Audio) #### 非流式音频处理 (audioNonStream) 处理非流式接口返回的音频数据,支持多种数据格式(Base64、Blob、ArrayBuffer、File)和灵活的字段路径提取。 ```typescript 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); ``` **📖 [查看非流式音频处理完整文档](./docs/audio-nonstream.md)** #### 流式音频处理器 V2 (audioStreamV2) 新版流式音频处理器,支持有头部和无头部两种流式音频格式,提供更灵活的配置。 ```typescript 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 完整文档](./docs/audio-stream-v2.md)** #### 音频流处理 (audioStream) 音频流处理工具,用于处理音频数据流,支持ArrayBuffer和流式数据,并提供自动播放功能。 ```typescript 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) 轻量级音频处理工具,专注于处理流式和非流式音频数据,无需额外依赖,支持各种响应格式。 ```typescript 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; } ``` 支持的选项: ```typescript // 音频处理选项 { 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 处理流式和非流式音频请求: ```typescript 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` 指定音频数据的路径 ```typescript // 标准格式处理 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中止处理过程: ```typescript // 创建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(); // 这将触发中止处理 ``` ##### 控制播放 ```typescript // 暂停播放 handler.pause(); // 恢复播放 handler.resume(); // 停止播放 handler.stop(); // 设置音量 (0-1) handler.setVolume(0.5); // 释放资源 handler.release(); ``` ##### 配置选项 `AudioStreamOptions` 支持以下选项: ```typescript { // 日志级别: '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` 支持以下选项: ```typescript { // 是否需要解析处理 needParse?: boolean; // 音频数据路径,如 "audio.b" audioPath?: string; // MIME类型 mimeType?: string; // 是否在接收到第一块数据时自动播放 autoPlayOnFirstChunk?: boolean; // 是否在下载完成时自动播放 autoPlayOnComplete?: boolean; // 用于停止处理的AbortSignal abortSignal?: AbortSignal; } ``` ### 🔊 音频播放器 `mstf-kit` 提供了功能强大的音频播放工具,支持背景播放和页面渲染两种模式: #### 背景播放模式 ```typescript 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秒位置 ``` #### 页面渲染模式 ```typescript 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 作为容器: ```typescript 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 动画的加载、渲染和控制,可以轻松地在您的应用中展示高质量的矢量动画。 #### 基本使用 ```typescript 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 作为容器: ```typescript 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 }; } } ``` #### 多种库加载模式 支持多种加载方式: ```typescript // 默认使用内置的 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渲染模式,提供高性能的动画播放体验。 #### 动画控制 播放器支持丰富的控制方法: ```typescript // 播放控制 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。 ```typescript 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 作为容器引用: ```typescript 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 }; } } ``` #### 播放列表支持 ```typescript // 创建播放列表 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**: 完整的类型定义 #### 支持的配置选项 - **自定义控件**: 可定制控制栏按钮 - **视频比例**: 支持多种纵横比设置 - **播放速度**: 可调节的播放速率 - **字幕**: 支持多语言字幕轨道 - **质量切换**: 支持视频质量选择 ##### 强大的增强功能 ```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) 可用的控制栏按钮选项: ```typescript controls: [ 'play-large', // 大播放按钮 'play', // 播放/暂停按钮 'progress', // 进度条 'current-time', // 当前时间 'duration', // 总时长 'mute', // 静音按钮 'volume', // 音量控制 'captions', // 字幕按钮 'settings', // 设置按钮 'pip', // 画中画按钮 'airplay', // AirPlay按钮 'fullscreen', // 全屏按钮 'restart', // 重新播放按钮 'fast-forward', // 快进按钮 'rewind' // 快退按钮 ] ``` ##### 完整配置选项 ```typescript // 完整的播放器配置选项 { // 基本配置 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 特有选项 ```typescript // 创建Plyr播放器的额外选项 { // Plyr库加载选项 plyrLibOptions: { source: 'npm', // 从哪里加载Plyr库: 'cdn'(默认), 'npm', 'local', 'external' cdnUrl: 'https://unpkg.com/plyr@3.7.8/dist/plyr.min.js', // 自定义CDN URL cssUrl: 'https://unpkg.com/plyr@3.7.8/dist/plyr.css', // 自定义CSS URL externalLib: null // 外部提供的Plyr库实例(当source为'external'时使用) }, initOnLoad: true, // 是否在加载时立即初始化 autoCreateCss: true // 是否自动引入CSS } ``` #### 增强型播放器API 创建的增强型Plyr播放器提供以下API: ```typescript // 基础播放控制 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 ```typescript // 播放列表控制器 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`) 提供以下核心功能: - **自动重连** - 网络中断时自动尝试重新连接 - **心跳检测** - 保持连接活跃并检测断线 - **消息队列** - 离线时自动缓存消息,连接恢复后发送 - **消息优先级** - 支持高、中、低三种优先级消息处理 - **事件系统** - 提供丰富的事件监听接口 - **批量发送** - 支持消息批处理以优化网络传输 - **超时处理** - 自动处理消息超时和重试 - **完整指标** - 提供详细的连接和性能统计数据 #### 基本使用示例 ```typescript 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](./LICENSE) © [mustafa]