3 回答
TA贡献1813条经验 获得超2个赞
这似乎有很多额外的工作却没有什么好处,所以我将参考get-video-duration
https://www.npmjs.com/package/get-video-duration,它在获取任何视频文件的持续时间方面做得很好秒分时
TA贡献1824条经验 获得超6个赞
复制你发送的要点的最后评论,我想出了这个:
const fs = require("fs").promises;
class Group {
constructor(name, video, master, maxTime, currentTime) {
this._name = name;
this._video = video;
this._master = master;
this._maxTime = maxTime;
this._currentTime = currentTime;
}
setMaster(master) {
if (this._master != null) {
this._master.emit('master');
}
this._master = master;
this._master.emit('master');
}
};
const asyncForEach = async (array, callback) => {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
};
async function loadGroups() {
const files = await fs.readdir(`${__dirname}/data`);
const groups = []
await asyncForEach(files, async file => {
if (file.endsWith(".mp4")) {
const duration = await getVideoDuration(`${__dirname}/data/${file}`);
const group = new Group(file.split(".")[0], file, null, duration, 0);
groups.push(group);
}
});
console.log(groups);
}
async function getVideoDuration(video) {
const buff = Buffer.alloc(100);
const header = Buffer.from("mvhd");
const file = await fs.open(video, "r");
const {
buffer
} = await file.read(buff, 0, 100, 0);
await file.close();
const start = buffer.indexOf(header) + 17;
const timeScale = buffer.readUInt32BE(start);
const duration = buffer.readUInt32BE(start + 4);
const audioLength = Math.floor((duration / timeScale) * 1000) / 1000;
return audioLength;
}
loadGroups();
至于为什么您的原始代码不起作用,我的猜测是在回调内部返回fs.open或fs.read不返回 for getVideoDuration。我无法轻易地从fs文档中找到一种方法来弄清楚如何返回回调的值,所以我只是切换到 promises 和 async/await,它们基本上会同步运行代码。这样您就可以保存 和 的输出,fs.open并fs.read使用它们返回 . 范围内的值getVideoDuration。
TA贡献1790条经验 获得超9个赞
我已经找到解决此问题的方法。
async function test() {
const duration = await getDuration(`${__dirname}/data/vid.mp4`);
console.log(duration);
}
test();
function getDuration(file) {
return new Promise((resolve, reject) => {
exec(`ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 ${file}`, (err, stdout, stderr) => {
if (err) return console.error(err);
resolve(stdout ? stdout : stderr);
});
});
}
我只在 linux 上测试过,所以我不知道它是否可以在 windows 上运行
添加回答
举报