Initial commit: import Operit protocol plugins from xiaoli-cli
This commit is contained in:
commit
c6600fc47d
52 files changed
+31492
No files matched your search
@@ -0,0 +1,143 @@
|
||||
/* METADATA
|
||||
{
|
||||
"name": "ffmpeg",
|
||||
|
||||
"display_name": {
|
||||
"zh": "FFmpeg 工具集",
|
||||
"en": "FFmpeg Toolkit"
|
||||
},
|
||||
"description": {
|
||||
"zh": "提供FFmpeg工具,用于处理多媒体内容。",
|
||||
"en": "FFmpeg utilities for processing multimedia content."
|
||||
},
|
||||
"enabledByDefault": true,
|
||||
"category": "Media",
|
||||
"tools": [
|
||||
{
|
||||
"name": "ffmpeg_execute",
|
||||
"description": { "zh": "执行自定义FFmpeg命令(仅填写参数,不要包含前缀 ffmpeg)。", "en": "Execute a custom FFmpeg command (arguments only; do not include the leading ffmpeg)." },
|
||||
"parameters": [
|
||||
{ "name": "command", "description": { "zh": "要执行的FFmpeg命令参数(不要包含前缀 ffmpeg)", "en": "FFmpeg command arguments to execute (do not include the leading ffmpeg)" }, "type": "string", "required": true }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ffmpeg_info",
|
||||
"description": { "zh": "获取FFmpeg系统信息,包括版本、构建配置和支持的编解码器。", "en": "Get FFmpeg system info, including version, build config, and supported codecs." },
|
||||
"parameters": []
|
||||
},
|
||||
{
|
||||
"name": "ffmpeg_convert",
|
||||
"description": { "zh": "使用简化参数转换视频文件。", "en": "Convert a video file using simplified parameters." },
|
||||
"parameters": [
|
||||
{ "name": "input_path", "description": { "zh": "源视频文件路径", "en": "Input video file path" }, "type": "string", "required": true },
|
||||
{ "name": "output_path", "description": { "zh": "目标视频文件路径", "en": "Output video file path" }, "type": "string", "required": true },
|
||||
{ "name": "video_codec", "description": { "zh": "可选,要使用的视频编解码器。推荐使用 'h264'。支持的值: 'h264', 'hevc', 'vp8', 'vp9', 'av1', 'libx265', 'libvpx', 'libaom', 'mpeg4', 'mjpeg', 'prores'。", "en": "Optional. Video codec to use. Prefer 'h264'. Supported values: 'h264', 'hevc', 'vp8', 'vp9', 'av1', 'libx265', 'libvpx', 'libaom', 'mpeg4', 'mjpeg', 'prores'." }, "type": "string", "required": false },
|
||||
{ "name": "audio_codec", "description": { "zh": "可选,要使用的音频编解码器。支持的值: 'aac', 'mp3', 'opus', 'vorbis', 'flac', 'pcm', 'wav', 'ac3', 'eac3'。", "en": "Optional. Audio codec to use. Supported values: 'aac', 'mp3', 'opus', 'vorbis', 'flac', 'pcm', 'wav', 'ac3', 'eac3'." }, "type": "string", "required": false },
|
||||
{ "name": "resolution", "description": { "zh": "可选,输出分辨率,例如 '1280x720'。", "en": "Optional. Output resolution, e.g. '1280x720'." }, "type": "string", "required": false },
|
||||
{ "name": "bitrate", "description": { "zh": "可选,视频比特率,例如 '1000k'。", "en": "Optional. Video bitrate, e.g. '1000k'." }, "type": "string", "required": false }
|
||||
]
|
||||
}
|
||||
]
|
||||
}*/
|
||||
|
||||
const FFmpegTools = (function () {
|
||||
|
||||
type FFmpegVideoCodec = 'h264' | 'hevc' | 'vp8' | 'vp9' | 'av1' | 'libx265' | 'libvpx' | 'libaom' | 'mpeg4' | 'mjpeg' | 'prores';
|
||||
type FFmpegAudioCodec = 'aac' | 'mp3' | 'opus' | 'vorbis' | 'flac' | 'pcm' | 'wav' | 'ac3' | 'eac3';
|
||||
type FFmpegResolution = '1280x720' | '1920x1080' | '3840x2160' | '7680x4320' | `${number}x${number}`;
|
||||
type FFmpegBitrate = '500k' | '1000k' | '2000k' | '4000k' | '8000k' | `${number}k` | `${number}M`;
|
||||
|
||||
interface ToolResponse {
|
||||
success: boolean;
|
||||
message: string;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
async function ffmpeg_execute(params: { command: string }): Promise<ToolResponse> {
|
||||
const result = await Tools.FFmpeg.execute(params.command);
|
||||
return {
|
||||
success: result.returnCode === 0,
|
||||
message: result.returnCode === 0 ? "FFmpeg command executed successfully." : `FFmpeg command failed with return code ${result.returnCode}.`,
|
||||
data: result.output
|
||||
};
|
||||
}
|
||||
|
||||
async function ffmpeg_info(): Promise<ToolResponse> {
|
||||
const result = await Tools.FFmpeg.info();
|
||||
return {
|
||||
success: result.returnCode === 0,
|
||||
message: result.returnCode === 0 ? "FFmpeg info retrieved successfully." : "Failed to retrieve FFmpeg info.",
|
||||
data: result.output
|
||||
};
|
||||
}
|
||||
|
||||
async function ffmpeg_convert(params: {
|
||||
input_path: string,
|
||||
output_path: string,
|
||||
video_codec?: FFmpegVideoCodec,
|
||||
audio_codec?: FFmpegAudioCodec,
|
||||
resolution?: FFmpegResolution,
|
||||
bitrate?: FFmpegBitrate
|
||||
}): Promise<ToolResponse> {
|
||||
const result = await Tools.FFmpeg.convert(params.input_path, params.output_path, {
|
||||
video_codec: params.video_codec,
|
||||
audio_codec: params.audio_codec,
|
||||
resolution: params.resolution,
|
||||
bitrate: params.bitrate,
|
||||
});
|
||||
return {
|
||||
success: result.returnCode === 0,
|
||||
message: result.returnCode === 0 ? "FFmpeg conversion completed successfully." : `FFmpeg conversion failed with return code ${result.returnCode}.`,
|
||||
data: result.output
|
||||
};
|
||||
}
|
||||
|
||||
async function wrapToolExecution<P>(func: (params: P) => Promise<ToolResponse>, params: P) {
|
||||
try {
|
||||
const result = await func(params);
|
||||
complete(result);
|
||||
} catch (error: any) {
|
||||
console.error(`Tool ${func.name} failed unexpectedly`, error);
|
||||
complete({
|
||||
success: false,
|
||||
message: `工具执行时发生意外错误: ${error.message}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log("--- FFmpeg Tools Test ---");
|
||||
|
||||
console.log("\n[1/3] Testing ffmpeg_info...");
|
||||
const infoResult = await ffmpeg_info();
|
||||
console.log(JSON.stringify(infoResult, null, 2));
|
||||
|
||||
console.log("\n[2/3] Testing ffmpeg_execute (example: getting help for a decoder)...");
|
||||
const executeResult = await ffmpeg_execute({ command: '-h decoder=h264' });
|
||||
console.log(JSON.stringify(executeResult, null, 2));
|
||||
|
||||
console.log("\n[3/3] Testing ffmpeg_convert (example)...");
|
||||
console.log("Skipping ffmpeg_convert test as it requires input files.");
|
||||
|
||||
complete({ success: true, message: "Test finished." });
|
||||
}
|
||||
|
||||
return {
|
||||
ffmpeg_execute: (params: { command: string }) => wrapToolExecution(ffmpeg_execute, params),
|
||||
ffmpeg_info: (params: {}) => wrapToolExecution(ffmpeg_info, params),
|
||||
ffmpeg_convert: (params: {
|
||||
input_path: string,
|
||||
output_path: string,
|
||||
video_codec?: FFmpegVideoCodec,
|
||||
audio_codec?: FFmpegAudioCodec,
|
||||
resolution?: FFmpegResolution,
|
||||
bitrate?: FFmpegBitrate
|
||||
}) => wrapToolExecution(ffmpeg_convert, params),
|
||||
main,
|
||||
};
|
||||
})();
|
||||
|
||||
exports.ffmpeg_execute = FFmpegTools.ffmpeg_execute;
|
||||
exports.ffmpeg_info = FFmpegTools.ffmpeg_info;
|
||||
exports.ffmpeg_convert = FFmpegTools.ffmpeg_convert;
|
||||
exports.main = FFmpegTools.main;
|
||||
Reference in new issue
Block a user