mstf-kit
Version:
一个现代化的 JavaScript/TypeScript 工具库,提供了丰富的常用工具函数
1,191 lines (954 loc) • 35.3 kB
Markdown
# mstf-kit
English | [简体中文](./README.md)
A modern JavaScript/TypeScript utility library providing a rich set of commonly used utility functions.
## ✨ Features
- 📦 Tree Shaking Support
- 🔧 TypeScript Support
- 📚 Complete Type Definitions
- 🎯 Modular Design
- 💪 Comprehensive Test Coverage
- 📝 Detailed Documentation
- 🔒 Code Obfuscation Protection
## 📦 Installation
```bash
npm install mstf-kit
# or
yarn add mstf-kit
# or
pnpm add mstf-kit
```
## 🚀 Usage
```typescript
// Import the utility functions you need
import { formatDate, isEmail } from 'mstf-kit';
// Use date formatting
const date = formatDate(new Date(), 'YYYY-MM-DD');
console.log(date); // 2024-03-10
// Validate email
const isValidEmail = isEmail('example@email.com');
console.log(isValidEmail); // true
```
### Importing on Demand
To reduce bundle size, it is recommended to use tree-shaking and import only the specific functions you need:
```typescript
// Only import the functions you need
import { capitalize, truncate } from 'mstf-kit';
import { formatDate } from 'mstf-kit';
import { createLottiePlayer } from 'mstf-kit';
// Don't import the entire library like this
// import * as mstfKit from 'mstf-kit'; // ❌ Not recommended
```
Modern bundlers (like webpack, rollup, and vite) will automatically perform tree-shaking, only including the code you actually use.
## 📚 API Documentation
### 🔤 String Utils
Utility functions for string manipulation.
- `capitalize(str: string): string` - Capitalize first letter
- `camelCase(str: string): string` - Convert to camelCase
- `truncate(str: string, length: number): string` - Truncate string
### 🔢 Number Utils
Utility functions for number handling and calculations.
- `formatNumber(num: number, locale?: string): string` - Format number
- `round(num: number, decimals?: number): number` - Round number
- `clamp(num: number, min: number, max: number): number` - Clamp number
- `random(min: number, max: number, isInteger?: boolean): number` - Generate random number
- `percentage(value: number, total: number, decimals?: number): number` - Calculate percentage
### 📋 Array Utils
Utility functions for array operations and manipulation.
- `unique<T>(arr: T[]): T[]` - Remove duplicates
- `groupBy<T>(arr: T[], key: string | ((item: T) => string)): Record<string, T[]>` - Group array
- `flatten<T>(arr: any[], depth?: number): T[]` - Flatten array
- `sample<T>(arr: T[], count?: number): T | T[]` - Random sampling
- `shuffle<T>(arr: T[]): T[]` - Shuffle array
- `closest(arr: number[], target: number): number` - Find closest value
### 📦 Object Utils
Utility functions for object operations and manipulation.
- `deepClone<T>(obj: T): T` - Deep clone
- `get(obj: any, path: string | string[], defaultValue?: any): any` - Get nested property
- `set(obj: any, path: string | string[], value: any): void` - Set nested property
- `pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>` - Pick properties
- `omit<T, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>` - Omit properties
- `merge<T>(...objects: T[]): T` - Merge objects
### 📅 Date Utils
Utility functions for date and time handling.
- `formatDate(date: Date | number | string, format?: string): string` - Format date
- `getRelativeTime(date: Date | number | string, now?: Date): string` - Get relative time
- `getDateRange(start: Date | number | string, end: Date | number | string): Date[]` - Get date range
- `addTime(date: Date | number | string, amount: number, unit: string): Date` - Add time
- `isSameDay(date1: Date | number | string, date2: Date | number | string): boolean` - Check same day
### ✅ Validation Utils
Utility functions for data validation.
- `isEmail(email: string): boolean` - Validate email
- `isChinesePhone(phone: string): boolean` - Validate Chinese phone number
- `isChineseIdCard(idCard: string): boolean` - Validate Chinese ID card
- `isUrl(url: string): boolean` - Validate URL
- `isIPv4(ip: string): boolean` - Validate IPv4 address
- `validatePassword(password: string, options?: object): boolean` - Validate password strength
- `isSafeString(str: string): boolean` - Validate XSS safety
### 🎵 Audio Utils
#### Audio Stream Handler (audioStream)
Audio stream processing tool for handling audio data streams, supporting ArrayBuffer and streaming data formats with auto-play capability.
```typescript
import {
createAudioStreamHandler,
handleAudioBuffer,
createAudioHandlers
} from 'mstf-kit';
// Example 1: Handling ArrayBuffer response
const response = await axios.post('/api/voice/synthesize', {
voice_id: 'my-voice',
text: 'Hello, world!'
}, {
responseType: 'arraybuffer',
headers: { Accept: 'audio/mp3' }
});
// Method 1: Direct processing
const { blob, url, handler } = await handleAudioBuffer(response, {
mimeType: 'audio/mp3',
autoPlay: true,
logLevel: 'debug'
});
// Example 2: Handling streaming data
// Create a handler
const audioHandler = createAudioStreamHandler({
mimeType: 'audio/mp3',
logLevel: 'debug'
});
// Example 3: Simplest approach (all-in-one)
const { config, handler } = createAudioHandlers(
{
responseType: 'arraybuffer',
headers: { Accept: 'audio/mp3' }
},
{
mimeType: 'audio/mp3',
autoPlayOnComplete: true,
logLevel: 'debug'
}
);
// Use the enhanced config to send the request
const response = await axios.post('/api/voice/synthesize', data, config);
```
#### Lightweight Audio Request Handler (audioRequest)
A lightweight audio processing utility focused on handling streaming and non-streaming audio data without additional dependencies, supporting various response formats.
```typescript
import {
processStreamResponse,
processArrayBuffer,
processBlob,
processBase64Audio,
createBase64StreamProcessor
} from 'mstf-kit';
// Example 1: Using fetch and getReader to process streaming response
const response = await fetch('https://api.example.com/audio/stream', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: 'Text to synthesize' })
});
// Get the reader from response stream
const reader = response.body.getReader();
// Process streaming audio data
const { pause, resume, abort, isPlaying, finalBlob } = await processStreamResponse(reader, {
autoPlay: true, // Auto-play audio
returnBlob: true, // Return complete blob
audioField: 'data.audio', // Audio data path in the response
onStart: () => { // Audio playback start callback
console.log('Audio playback started');
playButton.classList.add('playing');
},
onEnded: () => { // Audio playback end callback
console.log('Audio playback ended');
playButton.classList.remove('playing');
statusElement.textContent = 'Playback completed';
},
onAudioData: (blob) => { // Callback when receiving new audio chunks
console.log('Audio chunk received:', blob.size);
},
onComplete: (blob) => { // Processing complete callback
if (blob) {
console.log('Complete audio size:', blob.size);
}
}
});
// Playback control
pauseButton.addEventListener('click', () => {
pause();
playButton.classList.remove('playing');
});
playButton.addEventListener('click', () => {
resume();
playButton.classList.add('playing');
});
// Monitor playback status
setInterval(() => {
const playing = isPlaying();
statusElement.textContent = playing ? 'Playing' : 'Paused';
}, 100);
// Abort processing
cancelButton.addEventListener('click', () => {
abort();
});
// Get complete audio
if (finalBlob) {
const blob = await finalBlob;
const url = URL.createObjectURL(blob);
audio.src = url;
}
```
Supported options:
```typescript
// Audio processing options
{
autoPlay?: boolean; // Whether to auto-play
returnBlob?: boolean; // Whether to return complete blob
mimeType?: string; // MIME type, defaults to 'audio/wav'
audioField?: string; // Audio data field path, e.g., 'data.audio'
onAudioData?: (audioBlob: Blob) => void; // Callback when audio data is received
onError?: (error: Error) => void; // Error callback
onComplete?: (blob?: Blob) => void; // Completion callback
onStart?: () => void; // Audio playback start callback
onEnded?: () => void; // Audio playback end callback
}
```
##### Axios Support
Using Axios for streaming and non-streaming audio requests:
```typescript
import axios from 'axios';
import { createAxiosAudioOptions } from 'mstf-kit';
// Streaming audio request - create configuration
const { axiosConfig, pause, resume, abort, isPlaying, finalBlob } = createAxiosAudioOptions({
autoPlay: true, // Auto-play audio
returnBlob: true, // Return complete blob
audioField: 'data.audio', // Path to audio data in response JSON
mimeType: 'audio/wav', // Audio MIME type
onStart: () => {
console.log('Audio playback started');
playButton.disabled = false;
},
onAudioData: (blob) => { // Callback when receiving audio chunks
console.log('Audio chunk received:', blob.size);
}
});
// Send request
const response = await axios.post(
'https://api.example.com/audio/stream',
{ text: 'Text to synthesize' },
axiosConfig
);
// Control playback
const togglePlay = () => {
if (isPlaying()) {
pause();
playButton.textContent = 'Play';
} else {
resume();
playButton.textContent = 'Pause';
}
};
playButton.addEventListener('click', togglePlay);
```
##### Custom Data Formats
Handles multiple server response data formats:
1. **Standard format**: `data: {"audio":"base64data","is_last":false}`
2. **Custom paths**: Specify path to audio data using `audioField`
```typescript
// Standard format processing
const { pause, resume, abort } = await processStreamResponse(reader, {
autoPlay: true
});
// Custom path processing
const { pause, resume, abort } = await processStreamResponse(reader, {
autoPlay: true,
audioField: 'result.data.audioContent' // Specify custom path
});
// Axios with custom format
const { axiosConfig } = createAxiosAudioOptions({
autoPlay: true,
audioField: 'response.voice.content'
});
```
Intelligent data extraction: If `audioField` is not specified, it will automatically attempt to extract audio data from:
- Data provided directly as a string
- The `audio` property of the object
- Data nested in `data.audio`
##### Stopping/Aborting Processing
Supports aborting the processing using AbortController:
```typescript
// Create an AbortController
const controller = new AbortController();
const signal = controller.signal;
// Method 1: Pass through config
const { config, handler } = createAudioHandlers(
{ /* axios config */ },
{
abortSignal: signal,
// other options...
}
);
// Method 2: Set directly
audioHandler.setAbortSignal(signal);
// Method 3: Call abort method directly
audioHandler.abort();
// When you need to abort:
controller.abort(); // This will trigger the abort processing
```
##### Playback Control
```typescript
// Pause playback
handler.pause();
// Resume playback
handler.resume();
// Stop playback
handler.stop();
// Set volume (0-1)
handler.setVolume(0.5);
// Release resources
handler.release();
```
##### Configuration Options
`AudioStreamOptions` supports these options:
```typescript
{
// Log level: 'none' | 'error' | 'warn' | 'info' | 'debug'
logLevel?: LogLevel;
// Whether to autoplay
autoPlay?: boolean;
// Custom MIME type
mimeType?: string;
// Whether to loop playback
loop?: boolean;
// Initial volume (0-1)
volume?: number;
// Callback when playback ends
onEnded?: () => void;
// Callback on error
onError?: (error: Error) => void;
// Callback when playback starts
onPlay?: () => void;
// Callback for playback progress
onProgress?: (currentTime: number, duration: number) => void;
// Callback when data is loaded
onDataLoaded?: (blob: Blob) => void;
// Callback when processing is aborted
onAborted?: () => void;
}
```
`DownloadProgressConfig` supports these options:
```typescript
{
// Whether parsing is required
needParse?: boolean;
// Audio data path, e.g. "audio.b"
audioPath?: string;
// MIME type
mimeType?: string;
// Whether to autoplay on first chunk
autoPlayOnFirstChunk?: boolean;
// Whether to autoplay when download completes
autoPlayOnComplete?: boolean;
// AbortSignal for stopping processing
abortSignal?: AbortSignal;
}
```
**Question 5: How do I determine which responseType to use?**
- Use `responseType: 'arraybuffer'` when API returns binary audio data directly
- Use `responseType: 'json'` when API returns a JSON structure containing audio data, and specify `audioDataField`
- Use `responseType: 'text'` when API returns text-formatted audio data (like Base64 encoded)
Combine server API documentation and actual testing to determine the most suitable type.
### 🔊 Audio Player
`mstf-kit` provides powerful audio playback tools supporting both background playback and UI rendering modes:
#### Background Playback Mode
```typescript
import { createAudioPlayer, playAudio } from 'mstf-kit';
// Simple playback method
const audioBlob = new Blob([...]); // Audio data
const player = await playAudio(audioBlob, {
volume: 0.8,
loop: true
});
// Or use the complete API
const backgroundPlayer = createAudioPlayer();
await backgroundPlayer.load('https://example.com/audio.mp3');
await backgroundPlayer.play();
// Playback controls
backgroundPlayer.pause();
backgroundPlayer.setVolume(0.5);
backgroundPlayer.seek(30); // Jump to 30 seconds position
```
#### UI Rendering Mode
```typescript
import { createAudioPlayer, AUDIO_FORMATS } from 'mstf-kit';
// Create a player with UI interface
const uiPlayer = createAudioPlayer({
renderUI: true, // Enable UI rendering
container: '#player-box', // Specify container element
theme: 'dark', // Use dark theme
showVisualization: true, // Show audio visualization
visualizationType: 'bars' // Use bar spectrum visualization
});
// Load audio
await uiPlayer.load(audioBlob);
await uiPlayer.play();
// Callback when playback ends
uiPlayer.onEnded = () => {
console.log('Playback completed');
};
// Release resources when not needed
uiPlayer.destroy();
```
#### Vue Integration
Seamlessly integrates with Vue3 framework, supporting the use of ref as container:
```typescript
import { ref, onMounted, onUnmounted } from 'vue';
import { createAudioPlayer } from 'mstf-kit';
export default {
setup() {
// Create container reference
const playerContainer = ref(null);
let audioPlayer = null;
onMounted(async () => {
// Create player and use ref as container
audioPlayer = createAudioPlayer({
renderUI: true,
container: playerContainer, // Pass ref directly
theme: 'dark',
showVisualization: true
});
// Load and play audio
await audioPlayer.load('/audio/example.mp3');
await audioPlayer.play();
});
// Clean up resources when component is unmounted
onUnmounted(() => {
if (audioPlayer) {
audioPlayer.destroy();
}
});
return { playerContainer };
}
}
```
#### Visualization Types
The player supports three visualization types:
- `waveform`: Waveform display
- `bars`: Spectrum bar chart
- `circle`: Circular spectrum visualization
#### Supported Themes
- `default`: Default theme (light)
- `dark`: Dark theme
- `minimal`: Minimal theme (transparent background)
### 🎭 Lottie Animation
`mstf-kit` supports loading, rendering, and controlling Lottie animations, making it easy to showcase high-quality vector animations in your application.
#### Basic Usage
```typescript
import { createLottiePlayer, playLottie } from 'mstf-kit';
// Quickly load and play a Lottie animation
const player = await playLottie(
'https://assets.lottiefiles.com/packages/lf20_UJNc2t.json',
'#animation-container',
{ loop: true, speed: 1.5 }
);
// Or use the complete API
const lottiePlayer = await createLottiePlayer({
container: '#animation-container',
renderer: 'canvas', // dotlottie-web uses canvas rendering
loop: true,
autoplay: true
});
// Load animation
await lottiePlayer.load('https://assets.lottiefiles.com/packages/lf20_UJNc2t.json');
// Control animation
lottiePlayer.pause();
lottiePlayer.setSpeed(2.0);
lottiePlayer.play();
```
#### Vue Integration
Seamlessly integrates with Vue3 framework, supporting the use of refs as containers:
```typescript
import { ref } from 'vue';
import { playLottie } from 'mstf-kit';
export default {
setup() {
// Create container reference
const animationContainer = ref(null);
// Load animation (in onMounted)
onMounted(async () => {
const player = await playLottie(
'https://assets.lottiefiles.com/packages/lf20_UJNc2t.json',
animationContainer,
{ loop: true }
);
});
return { animationContainer };
}
}
```
#### Multiple Library Loading Modes
Supports various loading methods:
```typescript
// Use the built-in dotlottie-web library (default)
const player1 = await createLottiePlayer({
container: '#animation-container',
loop: true
});
// Use a custom external library
import customLottieLib from 'custom-lottie-lib';
const player2 = await createLottiePlayer({
container: '#animation-container',
libOptions: {
source: 'external',
externalLib: customLottieLib
}
});
// Load from CDN
const player3 = await createLottiePlayer({
container: '#animation-container',
libOptions: {
source: 'cdn',
cdnURL: 'https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web/+esm'
}
});
```
#### Rendering Modes
The Lottie player uses Canvas rendering by default, providing high-performance animation playback.
#### Animation Controls
The player supports a rich set of control methods:
```typescript
// Playback controls
player.play();
player.pause();
player.stop();
// Speed and direction
player.setSpeed(1.5); // 1.5x speed
player.setDirection(-1); // Play in reverse
// Navigation controls
player.goToFrame(24); // Jump to frame 24
player.goToAndPlay(24); // Jump to frame and play
player.setSegment(10, 50); // Only play frames 10-50
// Loop controls
player.setLoop(true); // Infinite loop
player.setLoop(3); // Loop 3 times
// Animation information
console.log(`Total frames: ${player.getTotalFrames()}`);
console.log(`Current frame: ${player.getCurrentFrame()}`);
console.log(`Duration: ${player.getDuration()}ms`);
console.log(`Is playing: ${player.isPlaying()}`);
// Resource cleanup
player.destroy();
```
#### Advanced Features
- **Lightweight and Efficient**: Uses dotlottie-web library for smaller size and better performance
- **Multiple Library Sources**: Supports built-in library (default), CDN loading, or externally provided custom libraries
- **Vue Framework Support**: Seamlessly supports Vue3 refs as container references
- **Multiple Sources**: Supports loading animations from URLs, JSON strings, or objects
- **Animation Events**: Provides rich callback functions to monitor animation state changes
- **Responsiveness**: Supports adaptive container sizing through the `resize()` method
### 🎬 Plyr Player (plyrPlayer)
Provides a wrapper for the Plyr media player, supporting both video and audio playback, with rich features and an easy-to-use API.
```typescript
import { createPlyrPlayer, playWithPlyr, createPlaylist } from 'mstf-kit';
// Quickly create a simple player
const player = await playWithPlyr(
'https://example.com/video.mp4',
'#player-container',
{ autoplay: true, muted: true }
);
// Use the complete API
const advancedPlayer = await createPlyrPlayer({
container: '#player-container',
source: {
type: 'video',
title: 'Example Video',
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: 'Play',
pause: 'Pause',
mute: 'Mute',
volume: 'Volume'
}
});
// Access enhanced features
await advancedPlayer.play();
advancedPlayer.addMarker(30, 'Important moment');
const screenshot = advancedPlayer.getCaptureImage();
advancedPlayer.downloadMedia('video.mp4');
```
#### Vue Integration
Seamlessly supports Vue3 refs as container references:
```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, // Use function to return the ref element
source: { /* media source config */ }
});
});
return { playerRef };
}
}
```
#### Playlist Support
```typescript
// Create a playlist
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 } }
);
// Playback controls
next(); // Play next item
previous(); // Play previous item
playIndex(2); // Play item at specific index
```
#### Key Features
- **Multiple Loading Modes**: Supports CDN, npm, or externally provided Plyr library
- **Enhanced Functionality**: Screenshot capture, aspect ratio control, markers, picture-in-picture, etc.
- **Vue Integration**: Direct support for Vue refs as containers
- **Playlist**: Support for mixed media type playlists
- **Internationalization**: Built-in support for multiple languages
- **Rich Events**: Complete event callback system
- **TypeScript**: Full type definitions
#### Supported Configuration Options
- **Custom Controls**: Customizable control bar buttons
- **Video Ratio**: Support for various aspect ratios
- **Playback Speed**: Adjustable playback rate
- **Captions**: Support for multilingual subtitle tracks
- **Quality Switching**: Support for video quality selection
##### Powerful Enhanced Features
```typescript
// Change aspect ratio
player.changeAspectRatio('16:9');
// Enter picture-in-picture mode
await player.enterPictureInPicture();
// Add timeline markers
player.addMarker(45, 'Highlight', 'red');
// Capture current frame
const imageDataUrl = player.getCaptureImage();
// Download media file
player.downloadMedia('downloaded-video.mp4');
// Custom shortcuts
player.addShortcut('m', () => player.toggleMute());
```
#### Configuration Options in Detail
##### Control Buttons (controls)
Available control button options:
```typescript
controls: [
'play-large', // Large play button in the center
'play', // Play/pause button
'progress', // Progress bar
'current-time', // Current time display
'duration', // Total duration display
'mute', // Mute button
'volume', // Volume control
'captions', // Captions button
'settings', // Settings button
'pip', // Picture-in-picture button
'airplay', // AirPlay button
'fullscreen', // Fullscreen button
'restart', // Restart button
'fast-forward', // Fast-forward button
'rewind' // Rewind button
]
```
##### Complete Configuration Options
```typescript
// Complete player configuration options
{
// Basic configuration
container: '#player', // Player container (string selector, DOM element, or function returning DOM element)
source: { // Media source configuration
type: 'video', // 'video' or 'audio'
title: 'Video Title', // Media title
sources: [ // Media source list
{
src: 'https://example.com/video.mp4',
type: 'video/mp4',
size: 720 // Quality indicator (pixel height)
}
],
poster: 'https://example.com/poster.jpg', // Video poster image URL
tracks: [ // Subtitle/chapter tracks
{
kind: 'captions',
label: 'English',
src: 'https://example.com/captions.en.vtt',
srclang: 'en',
default: true
}
]
},
autoplay: false, // Whether to autoplay
muted: false, // Whether to mute
loop: { active: false }, // Whether to loop
volume: 1.0, // Default volume (0-1)
// UI configuration
controls: ['play', 'progress', 'current-time', 'mute', 'volume', 'settings', 'fullscreen'],
hideControls: true, // Whether to auto-hide controls
resetOnEnd: false, // Whether to reset after playback ends
fullscreen: { // Fullscreen settings
enabled: true, // Whether to enable fullscreen
fallback: true, // Whether to use fallback if browser doesn't support native fullscreen
iosNative: true // Use native fullscreen on iOS
},
ratio: '16:9', // Video aspect ratio
storage: { // Local storage
enabled: true, // Whether to enable storage
key: 'plyr-volume' // Storage key name
},
speed: { // Playback speed settings
selected: 1, // Default speed
options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] // Available speed options
},
quality: { // Video quality settings
default: '720', // Default quality
options: ['1080', '720', '480', '360'] // Available quality options (corresponds to size in sources)
},
invertTime: false, // Whether to invert time display (show remaining time)
displayDuration: true, // Whether to display total duration
markers: { // Timeline markers
enabled: true, // Whether to enable markers
points: [ // Marker list
{
time: 15, // Marker time (seconds)
label: 'Highlight', // Marker label
color: 'red' // Marker color
}
]
},
// Localization text
i18n: {
restart: 'Restart',
play: 'Play',
pause: 'Pause',
volume: 'Volume',
mute: 'Mute',
unmute: 'Unmute',
pip: 'PIP',
normal: 'Normal',
settings: 'Settings',
speed: 'Speed',
quality: 'Quality',
loop: 'Loop',
start: 'Start',
end: 'End',
all: 'All',
reset: 'Reset',
disabled: 'Disabled',
enabled: 'Enabled',
advertisement: 'Ad',
qualityLabel: {
1080: '1080p',
720: '720p',
480: '480p',
360: '360p'
},
captions: 'Captions',
download: 'Download',
enterFullscreen: 'Enter fullscreen',
exitFullscreen: 'Exit fullscreen'
},
// Debug settings
debug: false, // Whether to enable debug mode
loadSprite: true // Whether to load SVG sprite
}
```
##### createPlyrPlayer Specific Options
```typescript
// Additional options for creating Plyr player
{
// Plyr library loading options
plyrLibOptions: {
source: 'npm', // Where to load Plyr library from: 'cdn'(default), 'npm', 'local', 'external'
cdnUrl: 'https://unpkg.com/plyr@3.7.8/dist/plyr.min.js', // Custom CDN URL
cssUrl: 'https://unpkg.com/plyr@3.7.8/dist/plyr.css', // Custom CSS URL
externalLib: null // Externally provided Plyr library instance (used when source is 'external')
},
initOnLoad: true, // Whether to initialize immediately on load
autoCreateCss: true // Whether to automatically include CSS
}
```
#### Enhanced Player API
The created enhanced Plyr player provides the following API:
```typescript
// Basic playback controls
player.play(); // Play
player.pause(); // Pause
player.stop(); // Stop
player.restart(); // Restart
player.rewind(10); // Rewind 10 seconds
player.forward(10); // Forward 10 seconds
player.increaseVolume(0.1); // Increase volume by 10%
player.decreaseVolume(0.1); // Decrease volume by 10%
player.togglePlay(); // Toggle play/pause
player.toggleMute(); // Toggle mute/unmute
// Status retrieval
player.isPlaying(); // Whether playing
player.isPaused(); // Whether paused
player.playing; // Playing state
player.paused; // Paused state
player.stopped; // Stopped state
// Media properties
player.volume = 0.8; // Set volume (0-1)
player.muted = true; // Set mute
player.currentTime = 30; // Set current playback position (seconds)
player.speed = 1.5; // Set playback speed
// Enhanced features
player.getContainer(); // Get container element
player.getDefaultOptions(); // Get default options
player.setSource(newSource); // Set new media source
player.changeAspectRatio('4:3'); // Change video aspect ratio
player.addShortcut('m', () => player.toggleMute()); // Add shortcut
player.getCaptureImage(); // Capture current frame
player.downloadMedia('video.mp4'); // Download media
player.setPoster('https://example.com/poster.jpg'); // Set video poster
player.isFullscreen(); // Whether in fullscreen
player.enterPictureInPicture(); // Enter picture-in-picture mode
player.exitPictureInPicture(); // Exit picture-in-picture mode
player.togglePictureInPicture(); // Toggle picture-in-picture mode
player.reload(); // Reload media
player.getQualityOptions(); // Get available quality options
player.setQuality('720'); // Set video quality
player.getSpeedOptions(); // Get available speed options
player.setCustomControls(['play', 'volume']); // Set custom controls
player.addMarker(45, 'Highlight'); // Add timeline marker
player.removeMarker(45); // Remove marker
player.clearMarkers(); // Clear all markers
// Event listeners
player.on('play', () => console.log('Started playing'));
player.once('ended', () => console.log('Playback ended'));
player.off('play', callback); // Remove event listener
```
#### Playlist API
```typescript
// Playlist controller
const {
player, // Player instance
next, // Play next function
previous, // Play previous function
playIndex, // Play specific index function
currentIndex, // Current playing index
sources // Media source list
} = await createPlaylist(sources, container, options);
// Usage examples
next(); // Play next
previous(); // Play previous
playIndex(2); // Play media at index 2
const currentPlaying = sources[currentIndex]; // Get current playing media info
```
#### Use Cases
- **Video Learning Platforms**: Create video players with support for markers, screenshots, and advanced controls
- **Online Video Streaming**: Build professional players with multi-quality, subtitles, and custom UI
- **Audio Applications**: Create audio players with playlist functionality
- **Mixed Media Presentation**: Support seamless switching between video and audio in the same player
- **Vue Integration**: Easily integrate advanced media playback features in Vue applications
### 🔌 WebSocket Utils
Provides efficient and reliable WebSocket connection management and communication tools.
- `createWebSocketClient(options: WebSocketOptions): WebSocketClient` - Create a WebSocket client
- `isWebSocketSupported(): boolean` - Check if the current environment supports WebSocket
#### WebSocket Client API
The WebSocket client (`WebSocketClient`) provides the following core features:
- **Automatic Reconnection** - Automatically attempts to reconnect when the network is disrupted
- **Heartbeat Detection** - Keeps the connection active and detects disconnections
- **Message Queue** - Automatically caches messages when offline and sends them when the connection is restored
- **Message Priority** - Supports high, medium, and low priority message handling
- **Event System** - Provides a rich set of event listening interfaces
- **Batch Sending** - Supports message batching to optimize network transmission
- **Timeout Handling** - Automatically handles message timeouts and retries
- **Complete Metrics** - Provides detailed connection and performance statistics
#### Basic Usage Example
```typescript
import { WebSocketClient, WebSocketState, MessagePriority } from 'mstf-kit';
// Create WebSocket client
const ws = new WebSocketClient({
url: 'wss://example.com/socket',
protocols: ['v1'],
debug: true, // Enable debug logging
connectionTimeout: 8000, // Connection timeout (ms)
// Heartbeat configuration
heartbeat: {
enabled: true,
interval: 30000, // Send heartbeat every 30 seconds
message: { type: 'ping' },
timeout: 5000 // Consider timeout if no response after 5 seconds
},
// Automatic reconnection configuration
reconnect: {
enabled: true,
maxRetries: 10, // Maximum 10 retry attempts
initialDelay: 1000, // Initial retry delay of 1 second
maxDelay: 30000, // Maximum retry delay of 30 seconds
factor: 1.5, // Exponential backoff factor
jitter: 0.5 // Random jitter coefficient
}
});
// Connect to server
ws.connect()
.then(() => {
console.log('Connection successful');
// Send message
return ws.send({ type: 'hello', data: 'world' });
})
.catch(error => {
console.error('Connection error:', error);
});
// Listen for messages
ws.on('message', data => {
console.log('Message received:', data);
});
// Listen for connection state changes
ws.on('close', event => {
console.log('Connection closed:', event.code);
});
ws.on('reconnect', attempt => {
console.log(`Reconnection successful (attempt ${attempt})`);
});
// Send messages with different priorities
ws.send(criticalData, { priority: MessagePriority.HIGH });
ws.send(normalData, { priority: MessagePriority.NORMAL });
ws.send(statsData, { priority: MessagePriority.LOW });
// Message expecting a server response
ws.send({ type: 'query', id: 'user-123' }, {
expectResponse: true, // Wait for response
timeout: 5000, // Response timeout
retries: 2, // Number of retries on timeout
retryDelay: 1000 // Retry interval
}).then(response => {
console.log('Response received:', response);
}).catch(error => {
console.error('Request failed:', error);
});
// Get connection status and statistics
console.log('Current state:', ws.getState());
console.log('Connection latency:', ws.getLatency());
console.log('Statistics:', ws.getConnectionStats());
// Destroy resources when no longer used
ws.destroy();
```
#### Advanced Features
- **Batch Messages**: Suitable for scenarios requiring sending many small messages, automatically merges them into batch messages to reduce network overhead
- **Dynamic Configuration**: Adjust heartbeat, reconnection, and message handling configurations at runtime
- **Complete Lifecycle Management**: Automatically handles resource release to prevent memory leaks
- **Compatibility**: Supports various browser environments and Node.js
See the API documentation for more advanced usage.
## 📄 License
[MIT](./LICENSE) © [mustafa]