@mixvideo/cli
Advanced tools
+147
-13
| #!/usr/bin/env node | ||
| "use strict"; | ||
| var __create = Object.create; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __getProtoOf = Object.getPrototypeOf; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
| // If the importer is in node compatibility mode or this is not an ESM | ||
| // file that has been converted to a CommonJS file using a Babel- | ||
| // compatible transform (i.e. "__esModule" has not been set), then set | ||
| // "default" to the CommonJS "module.exports" for node compatibility. | ||
| isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
| mod | ||
| )); | ||
@@ -7,20 +29,132 @@ // src/index.ts | ||
| var import_promises = require("fs/promises"); | ||
| var import_path = require("path"); | ||
| var import_path = __toESM(require("path")); | ||
| var import_commander = require("commander"); | ||
| var import_video_analyzer = require("@mixvideo/video-analyzer"); | ||
| var import_fs = __toESM(require("fs")); | ||
| var root = process.cwd(); | ||
| async function main() { | ||
| const draft = (0, import_jianying.parse)((0, import_path.join)(root, "draft_content.json")); | ||
| draft.materials.videos = await Promise.all(draft.materials.videos.map(async (video) => { | ||
| const material_name = video.material_name; | ||
| const videoPath = await getMaterialVideoByName(material_name); | ||
| video.path = videoPath; | ||
| return video; | ||
| })); | ||
| await (0, import_promises.writeFile)((0, import_path.join)(root, "draft_content.json"), JSON.stringify(draft, null, 2)); | ||
| const program = new import_commander.Command(); | ||
| program.name(`mixvideo`).version(`1.0.0`).description(`MixVideo CLI tool`); | ||
| program.command(`login`).description(`Login to MixVideo`).action(() => { | ||
| console.log(`Login`); | ||
| }); | ||
| program.command(`logout`).description(`Logout from MixVideo`).action(() => { | ||
| console.log(`Logout`); | ||
| }); | ||
| program.command(`analyze`).description(`Analyze a product video`).argument(`<dir>`, `Product video file`).action(async (dir) => { | ||
| try { | ||
| console.log("\u{1F3AC} \u5F00\u59CB\u89C6\u9891\u5206\u6790..."); | ||
| const root2 = process.cwd(); | ||
| const analyzer = (0, import_video_analyzer.createVideoAnalyzer)({ | ||
| upload: { | ||
| bucketName: "dy-media-storage", | ||
| filePrefix: "processed", | ||
| maxRetries: 3 | ||
| } | ||
| }); | ||
| const resourcesDir = import_path.default.join(root2, dir); | ||
| if (!import_fs.default.existsSync(resourcesDir)) { | ||
| console.log("\u{1F4C1} \u521B\u5EFA resources \u76EE\u5F55..."); | ||
| import_fs.default.mkdirSync(resourcesDir, { recursive: true }); | ||
| console.log("\u2705 resources \u76EE\u5F55\u5DF2\u521B\u5EFA\uFF0C\u8BF7\u5C06\u89C6\u9891\u6587\u4EF6\u653E\u5165\u8BE5\u76EE\u5F55"); | ||
| return; | ||
| } | ||
| const analysisMode = { | ||
| type: "gemini", | ||
| model: "gemini-2.5-flash", | ||
| analysisType: "comprehensive" | ||
| }; | ||
| const analysisOptions = { | ||
| enableProductAnalysis: true, | ||
| // 启用产品分析 | ||
| maxScenes: 20, | ||
| // 最大场景数 | ||
| confidenceThreshold: 0.7 | ||
| // 置信度阈值 | ||
| }; | ||
| const onProgress = (progress) => { | ||
| console.log(`\u{1F4CA} ${progress.step}: ${progress.progress}% (${progress.currentFile || ""})`); | ||
| }; | ||
| console.log(`\u{1F50D} \u626B\u63CF\u76EE\u5F55: ${resourcesDir}`); | ||
| const result = await analyzer.analyzeDirectoryComplete( | ||
| resourcesDir, | ||
| analysisMode, | ||
| { | ||
| // 扫描选项 | ||
| scanOptions: { | ||
| recursive: true, | ||
| maxFileSize: 1024 * 1024 * 1024, | ||
| // 1GB | ||
| minFileSize: 1024 | ||
| // 1KB | ||
| }, | ||
| // 分析选项 | ||
| analysisOptions, | ||
| // 文件夹匹配配置 | ||
| folderConfig: { | ||
| baseDirectory: resourcesDir, | ||
| maxDepth: 2, | ||
| minConfidence: 0.4, | ||
| enableSemanticAnalysis: true | ||
| }, | ||
| // 报告生成选项 | ||
| reportOptions: { | ||
| format: "xml", | ||
| outputPath: import_path.default.join(__dirname, "../analysis-report.xml"), | ||
| includeFolderMatching: true, | ||
| includeDetailedAnalysis: true, | ||
| title: "MixVideo \u89C6\u9891\u5206\u6790\u62A5\u544A" | ||
| }, | ||
| // 进度跟踪 | ||
| onProgress | ||
| } | ||
| ); | ||
| console.log("\n\u{1F389} \u5206\u6790\u5B8C\u6210\uFF01"); | ||
| console.log(`\u{1F4F9} \u5206\u6790\u89C6\u9891\u6570\u91CF: ${result.analysisResults.length}`); | ||
| console.log(`\u{1F4C2} \u6587\u4EF6\u5939\u5339\u914D\u6570\u91CF: ${Object.keys(result.folderMatches).length}`); | ||
| console.log(`\u{1F4C4} \u62A5\u544A\u4FDD\u5B58\u4F4D\u7F6E: ${result.reportPath}`); | ||
| const stats = analyzer.getAnalysisStatistics(result.analysisResults); | ||
| console.log("\n\u{1F4CA} \u8BE6\u7EC6\u7EDF\u8BA1:"); | ||
| console.log(`- \u603B\u5904\u7406\u65F6\u95F4: ${stats.totalProcessingTime}ms`); | ||
| console.log(`- \u603B\u573A\u666F\u6570: ${stats.totalScenes}`); | ||
| console.log(`- \u603B\u5BF9\u8C61\u6570: ${stats.totalObjects}`); | ||
| console.log(`- \u5E73\u5747\u8D28\u91CF\u5206\u6570: ${stats.averageQualityScore.toFixed(2)}`); | ||
| if (Object.keys(result.folderMatches).length > 0) { | ||
| console.log("\n\u{1F4C1} \u667A\u80FD\u6587\u4EF6\u5939\u5339\u914D\u5EFA\u8BAE:"); | ||
| for (const [videoPath, matches] of Object.entries(result.folderMatches)) { | ||
| const videoName = import_path.default.basename(videoPath); | ||
| console.log(` | ||
| \u{1F3AC} ${videoName}:`); | ||
| matches.slice(0, 3).forEach((match, index) => { | ||
| console.log(` ${index + 1}. ${match.folderPath} (\u7F6E\u4FE1\u5EA6: ${(match.confidence * 100).toFixed(1)}%)`); | ||
| if (match.reasons && match.reasons.length > 0) { | ||
| console.log(` \u7406\u7531: ${match.reasons.join(", ")}`); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| } catch (error) { | ||
| console.error("\u274C \u5206\u6790\u8FC7\u7A0B\u4E2D\u51FA\u73B0\u9519\u8BEF:", error); | ||
| process.exit(1); | ||
| } | ||
| }); | ||
| program.command(`generate`).description(`Generate a video`).argument(`<dir>`, `Product video path`).option(`-t, --template [template]`, `Template to use`, `draft_content.json`).action(async (dir, options) => { | ||
| const draft = (0, import_jianying.parse)((0, import_path.join)(root, options.template)); | ||
| draft.materials.videos = await Promise.all(draft.materials.videos.map(async (video) => { | ||
| const material_name = video.material_name; | ||
| const videoPath = await getMaterialVideoByName(dir, material_name); | ||
| video.path = videoPath; | ||
| return video; | ||
| })); | ||
| await (0, import_promises.writeFile)((0, import_path.join)(root, options.template), JSON.stringify(draft, null, 2)); | ||
| console.log(`\u606D\u559C\u60A8\uFF0C\u751F\u6210\u6210\u529F`); | ||
| }); | ||
| program.parse(); | ||
| } | ||
| var set = /* @__PURE__ */ new Set(); | ||
| async function getMaterialVideoByName(name) { | ||
| const files = await (0, import_promises.readdir)((0, import_path.join)(root, "videos")); | ||
| async function getMaterialVideoByName(dir, name) { | ||
| const files = await (0, import_promises.readdir)((0, import_path.join)(root, dir)); | ||
| const file = files[Math.floor(Math.random() * files.length)]; | ||
| const used = (0, import_path.join)(root, "videos", file); | ||
| if (set.has(used)) return getMaterialVideoByName(name); | ||
| const used = (0, import_path.join)(root, dir, file); | ||
| if (set.has(used)) return getMaterialVideoByName(dir, name); | ||
| set.add(used); | ||
@@ -27,0 +161,0 @@ return used; |
+125
-13
@@ -6,20 +6,132 @@ #!/usr/bin/env node | ||
| import { readdir, writeFile } from "fs/promises"; | ||
| import { join } from "path"; | ||
| import path, { join } from "path"; | ||
| import { Command } from "commander"; | ||
| import { createVideoAnalyzer } from "@mixvideo/video-analyzer"; | ||
| import fs from "fs"; | ||
| var root = process.cwd(); | ||
| async function main() { | ||
| const draft = parse(join(root, "draft_content.json")); | ||
| draft.materials.videos = await Promise.all(draft.materials.videos.map(async (video) => { | ||
| const material_name = video.material_name; | ||
| const videoPath = await getMaterialVideoByName(material_name); | ||
| video.path = videoPath; | ||
| return video; | ||
| })); | ||
| await writeFile(join(root, "draft_content.json"), JSON.stringify(draft, null, 2)); | ||
| const program = new Command(); | ||
| program.name(`mixvideo`).version(`1.0.0`).description(`MixVideo CLI tool`); | ||
| program.command(`login`).description(`Login to MixVideo`).action(() => { | ||
| console.log(`Login`); | ||
| }); | ||
| program.command(`logout`).description(`Logout from MixVideo`).action(() => { | ||
| console.log(`Logout`); | ||
| }); | ||
| program.command(`analyze`).description(`Analyze a product video`).argument(`<dir>`, `Product video file`).action(async (dir) => { | ||
| try { | ||
| console.log("\u{1F3AC} \u5F00\u59CB\u89C6\u9891\u5206\u6790..."); | ||
| const root2 = process.cwd(); | ||
| const analyzer = createVideoAnalyzer({ | ||
| upload: { | ||
| bucketName: "dy-media-storage", | ||
| filePrefix: "processed", | ||
| maxRetries: 3 | ||
| } | ||
| }); | ||
| const resourcesDir = path.join(root2, dir); | ||
| if (!fs.existsSync(resourcesDir)) { | ||
| console.log("\u{1F4C1} \u521B\u5EFA resources \u76EE\u5F55..."); | ||
| fs.mkdirSync(resourcesDir, { recursive: true }); | ||
| console.log("\u2705 resources \u76EE\u5F55\u5DF2\u521B\u5EFA\uFF0C\u8BF7\u5C06\u89C6\u9891\u6587\u4EF6\u653E\u5165\u8BE5\u76EE\u5F55"); | ||
| return; | ||
| } | ||
| const analysisMode = { | ||
| type: "gemini", | ||
| model: "gemini-2.5-flash", | ||
| analysisType: "comprehensive" | ||
| }; | ||
| const analysisOptions = { | ||
| enableProductAnalysis: true, | ||
| // 启用产品分析 | ||
| maxScenes: 20, | ||
| // 最大场景数 | ||
| confidenceThreshold: 0.7 | ||
| // 置信度阈值 | ||
| }; | ||
| const onProgress = (progress) => { | ||
| console.log(`\u{1F4CA} ${progress.step}: ${progress.progress}% (${progress.currentFile || ""})`); | ||
| }; | ||
| console.log(`\u{1F50D} \u626B\u63CF\u76EE\u5F55: ${resourcesDir}`); | ||
| const result = await analyzer.analyzeDirectoryComplete( | ||
| resourcesDir, | ||
| analysisMode, | ||
| { | ||
| // 扫描选项 | ||
| scanOptions: { | ||
| recursive: true, | ||
| maxFileSize: 1024 * 1024 * 1024, | ||
| // 1GB | ||
| minFileSize: 1024 | ||
| // 1KB | ||
| }, | ||
| // 分析选项 | ||
| analysisOptions, | ||
| // 文件夹匹配配置 | ||
| folderConfig: { | ||
| baseDirectory: resourcesDir, | ||
| maxDepth: 2, | ||
| minConfidence: 0.4, | ||
| enableSemanticAnalysis: true | ||
| }, | ||
| // 报告生成选项 | ||
| reportOptions: { | ||
| format: "xml", | ||
| outputPath: path.join(__dirname, "../analysis-report.xml"), | ||
| includeFolderMatching: true, | ||
| includeDetailedAnalysis: true, | ||
| title: "MixVideo \u89C6\u9891\u5206\u6790\u62A5\u544A" | ||
| }, | ||
| // 进度跟踪 | ||
| onProgress | ||
| } | ||
| ); | ||
| console.log("\n\u{1F389} \u5206\u6790\u5B8C\u6210\uFF01"); | ||
| console.log(`\u{1F4F9} \u5206\u6790\u89C6\u9891\u6570\u91CF: ${result.analysisResults.length}`); | ||
| console.log(`\u{1F4C2} \u6587\u4EF6\u5939\u5339\u914D\u6570\u91CF: ${Object.keys(result.folderMatches).length}`); | ||
| console.log(`\u{1F4C4} \u62A5\u544A\u4FDD\u5B58\u4F4D\u7F6E: ${result.reportPath}`); | ||
| const stats = analyzer.getAnalysisStatistics(result.analysisResults); | ||
| console.log("\n\u{1F4CA} \u8BE6\u7EC6\u7EDF\u8BA1:"); | ||
| console.log(`- \u603B\u5904\u7406\u65F6\u95F4: ${stats.totalProcessingTime}ms`); | ||
| console.log(`- \u603B\u573A\u666F\u6570: ${stats.totalScenes}`); | ||
| console.log(`- \u603B\u5BF9\u8C61\u6570: ${stats.totalObjects}`); | ||
| console.log(`- \u5E73\u5747\u8D28\u91CF\u5206\u6570: ${stats.averageQualityScore.toFixed(2)}`); | ||
| if (Object.keys(result.folderMatches).length > 0) { | ||
| console.log("\n\u{1F4C1} \u667A\u80FD\u6587\u4EF6\u5939\u5339\u914D\u5EFA\u8BAE:"); | ||
| for (const [videoPath, matches] of Object.entries(result.folderMatches)) { | ||
| const videoName = path.basename(videoPath); | ||
| console.log(` | ||
| \u{1F3AC} ${videoName}:`); | ||
| matches.slice(0, 3).forEach((match, index) => { | ||
| console.log(` ${index + 1}. ${match.folderPath} (\u7F6E\u4FE1\u5EA6: ${(match.confidence * 100).toFixed(1)}%)`); | ||
| if (match.reasons && match.reasons.length > 0) { | ||
| console.log(` \u7406\u7531: ${match.reasons.join(", ")}`); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| } catch (error) { | ||
| console.error("\u274C \u5206\u6790\u8FC7\u7A0B\u4E2D\u51FA\u73B0\u9519\u8BEF:", error); | ||
| process.exit(1); | ||
| } | ||
| }); | ||
| program.command(`generate`).description(`Generate a video`).argument(`<dir>`, `Product video path`).option(`-t, --template [template]`, `Template to use`, `draft_content.json`).action(async (dir, options) => { | ||
| const draft = parse(join(root, options.template)); | ||
| draft.materials.videos = await Promise.all(draft.materials.videos.map(async (video) => { | ||
| const material_name = video.material_name; | ||
| const videoPath = await getMaterialVideoByName(dir, material_name); | ||
| video.path = videoPath; | ||
| return video; | ||
| })); | ||
| await writeFile(join(root, options.template), JSON.stringify(draft, null, 2)); | ||
| console.log(`\u606D\u559C\u60A8\uFF0C\u751F\u6210\u6210\u529F`); | ||
| }); | ||
| program.parse(); | ||
| } | ||
| var set = /* @__PURE__ */ new Set(); | ||
| async function getMaterialVideoByName(name) { | ||
| const files = await readdir(join(root, "videos")); | ||
| async function getMaterialVideoByName(dir, name) { | ||
| const files = await readdir(join(root, dir)); | ||
| const file = files[Math.floor(Math.random() * files.length)]; | ||
| const used = join(root, "videos", file); | ||
| if (set.has(used)) return getMaterialVideoByName(name); | ||
| const used = join(root, dir, file); | ||
| if (set.has(used)) return getMaterialVideoByName(dir, name); | ||
| set.add(used); | ||
@@ -26,0 +138,0 @@ return used; |
+4
-2
| { | ||
| "name": "@mixvideo/cli", | ||
| "version": "1.0.2", | ||
| "version": "1.0.3", | ||
| "description": "Gemini AI API client library for MixVideo project", | ||
@@ -29,3 +29,5 @@ "main": "dist/index.js", | ||
| "dependencies": { | ||
| "@mixvideo/jianying": "1.0.0" | ||
| "commander": "^14.0.0", | ||
| "@mixvideo/jianying": "1.0.0", | ||
| "@mixvideo/video-analyzer": "1.0.0" | ||
| }, | ||
@@ -32,0 +34,0 @@ "devDependencies": { |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
14129
367.54%300
455.56%5
66.67%5
66.67%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added