Skip to main content
Glama

Video Clip MCP

time-utils.ts4.19 kB
/** * 时间处理工具类 */ export class TimeUtils { /** * 将秒转换为毫秒 */ static secondsToMilliseconds(seconds: number): number { return Math.round(seconds * 1000); } /** * 将毫秒转换为秒 */ static millisecondsToSeconds(milliseconds: number): number { return milliseconds / 1000; } /** * 格式化时间为 HH:MM:SS.mmm 格式 */ static formatTime(milliseconds: number): string { const totalSeconds = Math.floor(milliseconds / 1000); const ms = milliseconds % 1000; const hours = Math.floor(totalSeconds / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; return `${hours.toString().padStart(2, '0')}:${minutes .toString() .padStart(2, '0')}:${seconds.toString().padStart(2, '0')}.${ms .toString() .padStart(3, '0')}`; } /** * 解析时间字符串为毫秒 * 支持格式: HH:MM:SS.mmm, MM:SS.mmm, SS.mmm, 或纯数字(秒) */ static parseTime(timeString: string): number { // 如果是纯数字,当作秒处理 if (/^\d+(\.\d+)?$/.test(timeString)) { return this.secondsToMilliseconds(parseFloat(timeString)); } // 解析 HH:MM:SS.mmm 格式 const timeRegex = /^(?:(\d+):)?(?:(\d+):)?(\d+)(?:\.(\d+))?$/; const match = timeString.match(timeRegex); if (!match) { throw new Error(`无效的时间格式: ${timeString}`); } const [, hours = '0', minutes = '0', seconds, milliseconds = '0'] = match; const totalMs = parseInt(hours) * 3600 * 1000 + parseInt(minutes) * 60 * 1000 + parseInt(seconds) * 1000 + parseInt(milliseconds.padEnd(3, '0').slice(0, 3)); return totalMs; } /** * 验证时间段是否有效 */ static validateTimeSegment(start: number, end: number, maxDuration?: number): void { if (start < 0) { throw new Error('开始时间不能为负数'); } if (end <= start) { throw new Error('结束时间必须大于开始时间'); } if (maxDuration && end > maxDuration) { throw new Error(`结束时间不能超过视频总时长 ${this.formatTime(maxDuration)}`); } } /** * 计算时间段的持续时间 */ static getDuration(start: number, end: number): number { return end - start; } /** * 将时间段数组合并(去除重叠) */ static mergeTimeSegments(segments: Array<{ start: number; end: number }>): Array<{ start: number; end: number }> { if (segments.length === 0) return []; // 按开始时间排序 const sorted = segments.slice().sort((a, b) => a.start - b.start); const merged: Array<{ start: number; end: number }> = [sorted[0]]; for (let i = 1; i < sorted.length; i++) { const current = sorted[i]; const last = merged[merged.length - 1]; if (current.start <= last.end) { // 有重叠,合并 last.end = Math.max(last.end, current.end); } else { // 无重叠,添加新段 merged.push(current); } } return merged; } /** * 计算多个时间段的总持续时间 */ static getTotalDuration(segments: Array<{ start: number; end: number }>): number { const merged = this.mergeTimeSegments(segments); return merged.reduce((total, segment) => total + this.getDuration(segment.start, segment.end), 0); } /** * 生成等间隔的时间点 */ static generateTimePoints(start: number, end: number, count: number): number[] { if (count <= 1) return [start]; const interval = (end - start) / (count - 1); const points: number[] = []; for (let i = 0; i < count; i++) { points.push(start + interval * i); } return points; } /** * 将时间戳转换为FFmpeg时间格式 */ static toFFmpegTime(milliseconds: number): string { const seconds = this.millisecondsToSeconds(milliseconds); return seconds.toFixed(3); } /** * 从FFmpeg时间格式转换为毫秒 */ static fromFFmpegTime(timeString: string): number { const seconds = parseFloat(timeString); return this.secondsToMilliseconds(seconds); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pickstar-2002/video-clip-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server