This commit is contained in:
fengchuanhn@gmail.com
2026-05-21 00:19:11 +08:00
parent 1325ff92e5
commit 7f57dfa9ed
31 changed files with 10437 additions and 12 deletions

View File

@@ -169,8 +169,36 @@ async function uploadFile(baseUrl, apiKey, filePath) {
return fileName;
}
function locateFfmpegBinary() {
const fromEnv = process.env.AICLIENT_FFMPEG_PATH;
if (fromEnv && fs.existsSync(fromEnv)) return fromEnv;
return process.platform === "win32" ? "ffmpeg.exe" : "ffmpeg";
}
function locateFfprobeBinary() {
const fromEnv = process.env.AICLIENT_FFPROBE_PATH;
if (fromEnv && fs.existsSync(fromEnv)) return fromEnv;
const ffmpeg = locateFfmpegBinary();
if (ffmpeg && ffmpeg !== "ffmpeg" && ffmpeg !== "ffmpeg.exe") {
const dir = path.dirname(ffmpeg);
const sibling = path.join(dir, process.platform === "win32" ? "ffprobe.exe" : "ffprobe");
if (fs.existsSync(sibling)) return sibling;
}
return process.platform === "win32" ? "ffprobe.exe" : "ffprobe";
}
function parseDurationFromFfmpegStderr(text) {
const m = String(text || "").match(/Duration:\s*(\d+):(\d+):(\d+(?:\.\d+)?)/);
if (!m) return 0;
const h = parseFloat(m[1]);
const min = parseFloat(m[2]);
const s = parseFloat(m[3]);
if (!Number.isFinite(h + min + s)) return 0;
return h * 3600 + min * 60 + s;
}
function probeAudioDuration(audioPath) {
const ffprobe = process.env.AICLIENT_FFPROBE_PATH || "ffprobe";
const ffprobe = locateFfprobeBinary();
const r = spawnSync(
ffprobe,
[
@@ -184,9 +212,19 @@ function probeAudioDuration(audioPath) {
],
{ encoding: "utf8", windowsHide: true },
);
if (r.status !== 0) return 0;
const n = parseFloat(String(r.stdout || "").trim());
return Number.isFinite(n) && n > 0 ? n : 0;
if (r.status === 0) {
const n = parseFloat(String(r.stdout || "").trim());
if (Number.isFinite(n) && n > 0) return n;
}
const ffmpeg = locateFfmpegBinary();
const r2 = spawnSync(ffmpeg, ["-i", audioPath], {
encoding: "utf8",
windowsHide: true,
});
const fromStderr = parseDurationFromFfmpegStderr(r2.stderr || "");
if (fromStderr > 0) return fromStderr;
return 0;
}
async function createTask(config, videoFileName, audioFileName, audioDuration) {
@@ -379,6 +417,14 @@ globalThis.__nodejsMain = async function (params) {
if (!Number.isFinite(audioDuration) || audioDuration <= 0) {
audioDuration = probeAudioDuration(audioPath);
}
if (audioDuration <= 0) {
return {
success: false,
error:
"无法获取音频时长。云端口播需将时长传给 RunningHub请安装 ffmpeg/ffprobe或升级客户端后重试",
};
}
const durationSec = Math.ceil(audioDuration);
try {
const videoFileName = await uploadFile(config.baseUrl, config.apiKey, videoPath);
@@ -387,7 +433,7 @@ globalThis.__nodejsMain = async function (params) {
config,
videoFileName,
audioFileName,
audioDuration,
durationSec,
);
const done = await waitForTask(config, taskId);
const remoteUrl = pickResultUrl(done.results);
@@ -398,7 +444,12 @@ globalThis.__nodejsMain = async function (params) {
};
}
const localPath = await ensureLocalVideo(remoteUrl);
return { success: true, videoPath: localPath, taskId };
return {
success: true,
videoPath: localPath,
taskId,
audioDuration: durationSec,
};
} catch (e) {
return { success: false, error: e.message || String(e) };
}