nodejs获取视频时长

我已经尝试了很长时间,但我没有取得任何进展。我在谷歌https://gist.github.com/Elements-/cf063254730cd754599e上发现了这个 ,它正在运行,但是当我把它放在一个函数中并尝试将它与我的代码一起使用时,它没有运行。


代码:


fs.readdir(`${__dirname}/data`, (err, files) => {

        if (err) return console.error(`[ERROR] ${err}`);


        files.forEach(file => {

            if (file.endsWith(".mp4")) {

                

                // getVideoDuration(`${__dirname}/data/${file}`)

                group = new Group(file.split(".")[0], file, null, getVideoDuration(`${__dirname}/data/${file}`), 0);

                groups.push(group);

            }

        });


        console.log(groups);

    });


function getVideoDuration(video) {

    var buff = new Buffer.alloc(100);

    fs.open(video, 'r', function (err, fd) {

        fs.read(fd, buff, 0, 100, 0, function (err, bytesRead, buffer) {

            var start = buffer.indexOf(new Buffer.from('mvhd')) + 17;

            var timeScale = buffer.readUInt32BE(start, 4);

            var duration = buffer.readUInt32BE(start + 4, 4);

            var movieLength = Math.floor(duration / timeScale);


            console.log('time scale: ' + timeScale);

            console.log('duration: ' + duration);

            console.log('movie length: ' + movieLength + ' seconds');

            return movieLength;

        });

    });

}

输出:


[

  Group {

    _name: 'vid',

    _video: 'vid.mp4',

    _master: null,

    _maxTime: undefined,

    _currentTime: 0

  },

  Group {

    _name: 'vid2',

    _video: 'vid2.mp4',

    _master: null,

    _maxTime: undefined,

    _currentTime: 0

  }

]

time scale: 153600

duration: 4636416

movie length: 30 seconds

time scale: 153600

duration: 4636416

movie length: 30 seconds

它正确记录信息但返回未定义


慕仙森
浏览 309回答 3
3回答

慕姐8265434

这似乎有很多额外的工作却没有什么好处,所以我将参考get-video-duration https://www.npmjs.com/package/get-video-duration,它在获取任何视频文件的持续时间方面做得很好秒分时

慕妹3242003

复制你发送的要点的最后评论,我想出了这个:const fs = require("fs").promises;class Group {&nbsp; constructor(name, video, master, maxTime, currentTime) {&nbsp; &nbsp; this._name = name;&nbsp; &nbsp; this._video = video;&nbsp; &nbsp; this._master = master;&nbsp; &nbsp; this._maxTime = maxTime;&nbsp; &nbsp; this._currentTime = currentTime;&nbsp; }&nbsp; setMaster(master) {&nbsp; &nbsp; if (this._master != null) {&nbsp; &nbsp; &nbsp; this._master.emit('master');&nbsp; &nbsp; }&nbsp; &nbsp; this._master = master;&nbsp; &nbsp; this._master.emit('master');&nbsp; }};const asyncForEach = async (array, callback) => {&nbsp; for (let index = 0; index < array.length; index++) {&nbsp; &nbsp; await callback(array[index], index, array);&nbsp; }};async function loadGroups() {&nbsp; const files = await fs.readdir(`${__dirname}/data`);&nbsp; const groups = []&nbsp; await asyncForEach(files, async file => {&nbsp; &nbsp; if (file.endsWith(".mp4")) {&nbsp; &nbsp; &nbsp; const duration = await getVideoDuration(`${__dirname}/data/${file}`);&nbsp; &nbsp; &nbsp; const group = new Group(file.split(".")[0], file, null, duration, 0);&nbsp; &nbsp; &nbsp; groups.push(group);&nbsp; &nbsp; }&nbsp; });&nbsp; console.log(groups);}async function getVideoDuration(video) {&nbsp; const buff = Buffer.alloc(100);&nbsp; const header = Buffer.from("mvhd");&nbsp; const file = await fs.open(video, "r");&nbsp; const {&nbsp; &nbsp; buffer&nbsp; } = await file.read(buff, 0, 100, 0);&nbsp; await file.close();&nbsp; const start = buffer.indexOf(header) + 17;&nbsp; const timeScale = buffer.readUInt32BE(start);&nbsp; const duration = buffer.readUInt32BE(start + 4);&nbsp; const audioLength = Math.floor((duration / timeScale) * 1000) / 1000;&nbsp; return audioLength;}loadGroups();至于为什么您的原始代码不起作用,我的猜测是在回调内部返回fs.open或fs.read不返回 for getVideoDuration。我无法轻易地从fs文档中找到一种方法来弄清楚如何返回回调的值,所以我只是切换到 promises 和 async/await,它们基本上会同步运行代码。这样您就可以保存 和 的输出,fs.open并fs.read使用它们返回 . 范围内的值getVideoDuration。

富国沪深

我已经找到解决此问题的方法。async function test() {&nbsp; &nbsp; const duration = await getDuration(`${__dirname}/data/vid.mp4`);&nbsp; &nbsp; console.log(duration);}test();function getDuration(file) {&nbsp; &nbsp; return new Promise((resolve, reject) => {&nbsp; &nbsp; &nbsp; &nbsp; exec(`ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 ${file}`, (err, stdout, stderr) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (err) return console.error(err);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resolve(stdout ? stdout : stderr);&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; });}我只在 linux 上测试过,所以我不知道它是否可以在 windows 上运行
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript