Javascript nodejs在播放过程中获得视频
我已经尝试了很多年了,但没有任何进展。 我在谷歌上找到了这个 它正在运行,但当我把它放在一个函数中,并尝试在代码中使用它时,它不会运行 代码: 输出:Javascript nodejs在播放过程中获得视频,javascript,html,node.js,Javascript,Html,Node.js,我已经尝试了很多年了,但没有任何进展。 我在谷歌上找到了这个 它正在运行,但当我把它放在一个函数中,并尝试在代码中使用它时,它不会运行 代码: 输出: [ Group { _name: 'vid', _video: 'vid.mp4', _master: null, _maxTime: undefined, _currentTime: 0 }, Group { _name: 'vid2', _video: 'vid2.mp4',
[
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
它正确地记录了信息,但返回的是未定义的这似乎是一个没有什么好处的大量额外工作,因此我将参考
get video duration
,它在以秒、分和小时获取任何视频文件的持续时间方面做得非常好我已经找到了解决此问题的方法
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上运行。复制您发送的要点,我得出以下结论:
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();
const fs=require(“fs”)。承诺;
班级{
构造函数(名称、视频、主控、maxTime、currentTime){
这个。_name=name;
这个._video=video;
这个。_master=master;
这是.\u maxTime=maxTime;
这是。_currentTime=currentTime;
}
setMaster(主控){
如果(此._master!=null){
这个。_master.emit('master');
}
这个。_master=master;
这个。_master.emit('master');
}
};
常量asyncForEach=async(数组,回调)=>{
for(让index=0;index{
if(文件.endsWith(“.mp4”)){
const duration=wait getVideoDuration(`${uuu dirname}/data/${file}`);
const group=新组(file.split(“.”[0],file,null,duration,0);
组。推(组);
}
});
控制台日志(组);
}
异步函数getVideoDuration(视频){
常量buff=缓冲区分配(100);
const header=Buffer.from(“mvhd”);
const file=wait fs.open(视频,“r”);
常数{
缓冲器
}=等待文件.read(buff,0,100,0);
等待文件。关闭();
const start=buffer.indexOf(header)+17;
const timeScale=buffer.readUInt32BE(开始);
const duration=buffer.readUInt32BE(start+4);
const audioLength=数学楼层((持续时间/时间刻度)*1000)/1000;
返回长度;
}
加载组();
至于您的原始代码不起作用的原因,我猜返回到
fs.open
或fs.read
的回调不会返回getVideoDuration
。我无法从fs
文档中轻松找到返回回调值的方法,因此我只切换到Promissions和async/await,它们基本上会同步运行代码。通过这种方式,您可以保存fs.open
和fs.read
的输出,并使用它们在getVideoDuration
范围内返回一个值,我已经看到了,但我需要在raspberry pi上运行此操作,显然该库给了我一个错误:抛出新错误(“不支持的平台/架构:”+平台);^错误:不支持的平台/体系结构:linux-arm64Aah bummer,大多数节点模块依赖于amd体系结构它运行在我的ubuntu PC上大多数PC和笔记本电脑都有amd体系结构,而大多数便携式设备(如手机和控制器)都运行arm处理器,这就是为什么它在你的ubuntu pclib上运行这个使用ffprobe的可执行文件,也许你必须安装它,我猜在回调中返回并不是在getVideoDuration中返回。您可以尝试在fs.open和fs.read前面放一个return,或者只使用这些函数的同步版本,这样您就不必处理回调,只需在末尾返回。我尝试在末尾返回,但它仍然未定义。您可以发布完整的代码吗?什么是团体目标?谢谢!我忘了在fs常量上加上承诺!返回的时间单位是多少?我需要它是第二个,因为它已经在几秒钟内。但是我有一个视频,大约40分钟长,50.223秒?说实话,我不确定这背后的数学原理,我只是根据要点改编了代码。我试着查看get video duration软件包,但它在幕后使用ffprobe,而不是从缓冲区读取数据。没关系,我找到了一种“更好”的获取持续时间的方法,我会尽快发布答案
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();