UNPKG

mstf-kit

Version:

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

1,191 lines (954 loc) 35.3 kB
# 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]