Я хочу сделать автоматическую генерацию видео. В настоящее время я делаю это с помощью библиотеки узлов editly, которой нужен объект. Теперь я хочу получить музыку/аудио из папки, затем я хочу получить продолжительность каждого файла, чтобы я мог динамически объединять их вместе.
Проблема в том, что я хочу вернуть объект в функцию Array.map, этот объект редактируется внутри обратного вызова. НО, когда я возвращаю объект (который должен быть отредактирован в моей голове), он возвращает «по умолчанию».
Вот мой код:
var editly = require("editly");
var duration = require("mp3d");
var fs = require("fs");
var idx = 0;
var editObj = {
enableFfmpegLog: true,
outPath: "./vids/"+idx+".mp4",
width: 1280,
height: 720,
fps: 24,
defaults: {
transition: null
},
clips: [
{
layers: [
{
type: "image",
path: "./bgs/"+idx+".jpg"
}
]
}
],
audioTracks: fs.readdirSync("./audio/"+idx+"/").map((song, index, arr) => {
if (index == 0) {
var obj = { path: "./audio/"+idx+"/"+song, start: 0 };
return obj;
} else {
var obj = { path: "./audio/"+idx+"/"+song };
duration("./audio/"+idx+"/"+arr[index-1], (err, result) => {
obj.start = Number((result / 1000).toFixed(0));
});
return obj;
}
})
};
(async function() {
console.info(editObj);
// await editly(editObj).then(console.info).catch(console.error);
})();
ОБНОВЛЯТЬ: Вот новый и рабочий код:
var editly = require("editly");
var duration = require("mp3d");
var fs = require("fs");
(async function() {
var idx = 0;
var editObj = {
enableFfmpegLog: true,
outPath: "./vids/"+idx+".mp4",
width: 1280,
height: 720,
fps: 24,
defaults: {
transition: null
},
clips: [
{
layers: [
{
type: "image",
path: "./bgs/"+idx+".jpg"
}
]
}
],
audioTracks: await Promise.all(fs.readdirSync("./audio/"+idx+"/").map(async(song, index, arr) => {
if (index == 0) {
var obj = { path: "./audio/"+idx+"/"+song, start: 0 };
return obj;
} else {
var obj = { path: "./audio/"+idx+"/"+song };
await duration("./audio/"+idx+"/"+arr[index-1], (err, result) => {
obj.start = Number((result / 1000).toFixed(0));
});
return obj;
}
}))
};
console.info(editObj);
// await editly(editObj).then(console.info).catch(console.error);
})();



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я считаю, что происходит то, что происходит в вашей ветке else, где вы изменяете объект внутри обратного вызова. Он не выполняется, пока вы его не вернете. Поскольку js является асинхронным, вы можете использовать обещание и дождаться результата мутации, прежде чем вернуться.
У Джея Гарзона есть идея: ваш вызов функции
durationв ветке else является асинхронным — он не завершается вовремя и не модифицируетobj.startдо возврата, хотя его решение не совсем работает. См. stackoverflow.com/questions/40140149/… -- Вам также нужно будет вызватьPromise.all, чтобы вернуть простой массив.