feat(video-from-script): 批量生产支持剪映草稿地址跟踪
- 新增 `--draft-url` 命令行参数,允许为单个批次项指定草稿地址
- capcut_assemble 模块现在返回 `{ draftUrl, draftId }` 对象
- 组装阶段完成后自动将草稿地址保存到 manifest 文件中
- CSV/XLSX 导出表头新增"草稿地址"列,支持批量导出草稿链接
This commit is contained in:
@@ -43,6 +43,7 @@ function parseArgs(argv) {
|
|||||||
else if (argv[i] === '--hashtags' && argv[i + 1]) args.hashtags = argv[++i]
|
else if (argv[i] === '--hashtags' && argv[i + 1]) args.hashtags = argv[++i]
|
||||||
else if (argv[i] === '--format' && argv[i + 1]) args.format = argv[++i]
|
else if (argv[i] === '--format' && argv[i + 1]) args.format = argv[++i]
|
||||||
else if (argv[i] === '--draft-dir' && argv[i + 1]) args.draftDir = argv[++i]
|
else if (argv[i] === '--draft-dir' && argv[i + 1]) args.draftDir = argv[++i]
|
||||||
|
else if (argv[i] === '--draft-url' && argv[i + 1]) args.draftUrl = argv[++i]
|
||||||
else if (argv[i] === '--with-script') args.withScript = true
|
else if (argv[i] === '--with-script') args.withScript = true
|
||||||
else if (!args.command) args.command = argv[i]
|
else if (!args.command) args.command = argv[i]
|
||||||
}
|
}
|
||||||
@@ -258,6 +259,7 @@ function cmdMark(args) {
|
|||||||
if (args.draftName) item.draftName = args.draftName
|
if (args.draftName) item.draftName = args.draftName
|
||||||
if (args.forwardCopy) item.forwardCopy = args.forwardCopy
|
if (args.forwardCopy) item.forwardCopy = args.forwardCopy
|
||||||
if (args.hashtags) item.hashtags = args.hashtags
|
if (args.hashtags) item.hashtags = args.hashtags
|
||||||
|
if (args.draftUrl) item.draftUrl = args.draftUrl
|
||||||
|
|
||||||
batch.stats = calcStats(batch.items)
|
batch.stats = calcStats(batch.items)
|
||||||
writeJson(manifestPath, batch)
|
writeJson(manifestPath, batch)
|
||||||
@@ -314,6 +316,7 @@ function cmdNext(args) {
|
|||||||
topicA: item.topicA || '',
|
topicA: item.topicA || '',
|
||||||
topicB: item.topicB || '',
|
topicB: item.topicB || '',
|
||||||
draftName: item.draftName || '',
|
draftName: item.draftName || '',
|
||||||
|
draftUrl: item.draftUrl || '',
|
||||||
scriptFile: path.resolve(batchDir, item.scriptFile),
|
scriptFile: path.resolve(batchDir, item.scriptFile),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,6 +371,7 @@ function cmdExport(args) {
|
|||||||
音色: item.voice || '',
|
音色: item.voice || '',
|
||||||
转发文案带话题: forwardFull,
|
转发文案带话题: forwardFull,
|
||||||
草稿名称: item.draftName || '',
|
草稿名称: item.draftName || '',
|
||||||
|
草稿地址: item.draftUrl || '',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +391,7 @@ function cmdExport(args) {
|
|||||||
|
|
||||||
function exportCsv(manifestPath, rows) {
|
function exportCsv(manifestPath, rows) {
|
||||||
const outPath = manifestPath.replace('.json', '_export.csv')
|
const outPath = manifestPath.replace('.json', '_export.csv')
|
||||||
const headers = ['选题', '脚本', '账号', '模式', '音色', '转发文案带话题', '草稿名称']
|
const headers = ['选题', '脚本', '账号', '模式', '音色', '转发文案带话题', '草稿名称', '草稿地址']
|
||||||
|
|
||||||
const lines = [headers.join(',')]
|
const lines = [headers.join(',')]
|
||||||
for (const r of rows) {
|
for (const r of rows) {
|
||||||
@@ -414,7 +418,7 @@ function exportCsv(manifestPath, rows) {
|
|||||||
function exportXlsx(manifestPath, rows) {
|
function exportXlsx(manifestPath, rows) {
|
||||||
try {
|
try {
|
||||||
const XLSX = require('xlsx')
|
const XLSX = require('xlsx')
|
||||||
const headers = ['选题', '脚本', '账号', '模式', '音色', '转发文案带话题', '草稿名称']
|
const headers = ['选题', '脚本', '账号', '模式', '音色', '转发文案带话题', '草稿名称', '草稿地址']
|
||||||
const data = rows.map(r => headers.map(h => r[h] || ''))
|
const data = rows.map(r => headers.map(h => r[h] || ''))
|
||||||
data.unshift(headers)
|
data.unshift(headers)
|
||||||
|
|
||||||
|
|||||||
@@ -449,6 +449,8 @@ async function assemble(args) {
|
|||||||
if (mode === 'videos' && subtitles === 'false') {
|
if (mode === 'videos' && subtitles === 'false') {
|
||||||
console.log(`\n >> 视频模式未加字幕,请在剪映中打开草稿 → 识别字幕 → 语音识别生成\n`)
|
console.log(`\n >> 视频模式未加字幕,请在剪映中打开草稿 → 识别字幕 → 语音识别生成\n`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return { draftUrl, draftId }
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* 图片/视频 + TTS → 剪映草稿
|
* 图片/视频 + TTS → 剪映草稿
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs')
|
||||||
const { log, getManifestDir } = require('./pipeline-utils')
|
const { log, getManifestDir } = require('./pipeline-utils')
|
||||||
|
|
||||||
async function phaseAssemble(manifest, manifestPath, options) {
|
async function phaseAssemble(manifest, manifestPath, options) {
|
||||||
@@ -45,7 +46,13 @@ async function phaseAssemble(manifest, manifestPath, options) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { assemble } = require('../capcut_assemble')
|
const { assemble } = require('../capcut_assemble')
|
||||||
await assemble(assembleArgs)
|
const result = await assemble(assembleArgs)
|
||||||
|
// 保存草稿地址到 manifest,供批量导出使用
|
||||||
|
if (result && result.draftUrl) {
|
||||||
|
manifest.draftUrl = result.draftUrl
|
||||||
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8')
|
||||||
|
log('assemble', `草稿地址已保存: ${result.draftUrl}`)
|
||||||
|
}
|
||||||
log('assemble', '成片完成')
|
log('assemble', '成片完成')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log('assemble', `成片失败: ${err.message}`)
|
log('assemble', `成片失败: ${err.message}`)
|
||||||
|
|||||||
Reference in New Issue
Block a user