以下代码用于:
但当前,在执行代码时,它在转换时会串联在一起,并最终引发错误。我需要按其各自的顺序优先执行每个功能。
const glob = require('glob');
const exec = require('child_process').exec;
const { unlink } = require("fs").promises;
function start(index) {
const path = `./files/${index}`;
const ConvertedVideos=path+"/converted/*.mp4";
const videos = glob.sync(path+"/videos/*.mp4");
const outputnoaudio = path+"/outputnoaudio.mp4";
//THIS IS THE ORDER OF EXECUTION
await convertVideos()
await withFfmpegConcatVideo()
await clearConverted()
//HERE THE DEFINITION OF EACH FUNCTION
async function convertVideos() {
return new Promise((resolve) => {
console.log('>>>Starting conversion!!!');
const promises = videos.map(
(video, index) => {
var command = `ffmpeg -i ${video} -c:v libx264 -vf scale=1920:1080 -r 60 -c:a aac -ar 48000 -b:a 160k -strict experimental -f mp4 ./converted/${index}.mp4`;
return new Promise((resolve) => {
exec(command, (error, stdout, stderr) => {
if (error) {
console.warn(error);
}
resolve(stdout ? stdout : stderr);
console.log('Converted video', index);
});
});
}
)
Promise.all(promises);
resolve();
})
}
async function withFfmpegConcatVideo() {
return new Promise((resolve) => {
console.log('Starting concatenation...');
var converted = glob.sync(ConvertedVideos);
console.log('There is ', converted.length, 'converted videos');
if (converted.length > 0) {
(async () =>
await concat({
output: outputnoaudio,
videos: converted,
transition: {
name: 'fade',
duration: 200
}
}))()
}
resolve(console.log('Conversion finished'));
})
}
async function clearConverted() {
return new Promise((resolve) => {
const converted =
glob.sync(ConvertedVideos)
if (converted.length === 0)
return Promise.resolve([])
const promises =
converted.map(v => unlink(v).then(_ => {
v
}))
Promise.all(promises).then('Clean done.')
resolve();
})
}
}
start(1);
我想保持干净且可重复使用的代码。 你能帮我吗?
答案 0 :(得分:1)
您的start
函数看起来不正确,因为您缺少async
运算符。
为清楚起见,建议将其更像C文件一样对待,并在其中调用async function main() {}
和await
的三个函数。
在您的convertVideos
函数中,您正在呼叫Promise.all()
,但是您没有等待它。请注意,Promise.all()
实际上也返回了一个Promise,您必须等待它,但是为了让您等待它,周围的函数还必须具有async
关键字。我在clearConverted
函数中看到了同样的问题。
尝试等待您的Promise.all
通话,看看是否可以解决您的问题。
实际上,您的convertVideos
函数似乎将所有内容包装在Promise中,我认为您不需要。试试这个:
function convertVideos() {
console.log('>>>Starting conversion!!!');
const promises = videos.map(
(video, index) => {
var command = `ffmpeg -i ${video} -c:v libx264 -vf scale=1920:1080 -r 60 -c:a aac -ar 48000 -b:a 160k -strict experimental -f mp4 ./converted/${index}.mp4`;
return new Promise((resolve) => {
exec(command, (error, stdout, stderr) => {
if (error) {
console.warn(error);
}
resolve(stdout ? stdout : stderr);
console.log('Converted video', index);
});
});
});
// Notice that you can return this promise from Promise.all.
// The caller can then await this promise that will let you know when
// all the videos are converted.
return Promise.all(promises);
}
答案 1 :(得分:1)
withFfmpegConcatVideo().then(() => clearConverted());
应该做到这一点
答案 2 :(得分:0)
由于您的评论,我刚刚修复了代码,并找到了解决方案。
const glob = require('glob');
const concat = require('ffmpeg-concat');
const {
unlink
} =
require("fs").promises;
const exec = require("child_process").exec;
async function start(index){
const path = `./files/${index}`;
const pathToConverted = `${path}/converted`;
const videos = glob.sync(`${path}/[0-99]/videoKeywords/[0-99]/*output.mp4`);
const output = `${path}/output.mp4`;
const outputmuted = `${path}/outputmuted.mp4`;
async function clearConverted() {
await new Promise(async (resolve) => {
console.log('Starting cleaning...');
const converted = glob.sync(`${pathToConverted}/*.mp4`)
if (converted.length === 0)
return Promise.resolve([])
const promises =
converted.map(v => unlink(v).then(_ => {
console.log(" File Deleted");
v
}))
await Promise.all(promises).then(async () => await console.log('Clean done.'))
resolve()
})
}
async function convertVideos() {
await new Promise(async (resolve) => {
console.log('>>>Starting conversion of', videos.length, 'files!!!');
for (let i = 0; i < videos.length; i++) {
let video = videos[i];
var command = `ffmpeg -i ${video} -c:v libx264 -vf scale=1920:1080 -r 60 -c:a aac -ar 48000 -b:a 160k -strict experimental -f mp4 ${pathToConverted}/${i}.mp4`;
await new Promise((resolve) => {
exec(command, (error, stdout, stderr) => {
if (error) {
console.warn(error);
}
resolve(stdout ? stdout : stderr);
console.log(' Converted video', i);
});
});
}
resolve();
}).then(async () => await console.log('Conversion finished!!!'))
}
async function clearConverted() {
await new Promise(async (resolve) => {
console.log('Starting cleaning...');
const converted = glob.sync(`${pathToConverted}/*.mp4`)
if (converted.length === 0)
return Promise.resolve([])
const promises =
converted.map(v => unlink(v).then(_ => {
console.log(" File Deleted");
v
}))
await Promise.all(promises).then(async () => await console.log('Clean done.'))
resolve()
})
}
}
start(0);
请注意,function convertVideos()
的此实现顺序执行异步转换,这意味着它将逐步转换一个文件。
在此功能的先前实现上,执行是并行执行的,如果您有多个内核,这对于转换几个视频来说是最佳选择。
如果您有任何代码建议可同时处理大量视频,请随时提供支持。