NodeJS 用带元数据长度的ffmpeg实现音频到视频的Map

vulvrdjw  于 2023-06-22  发布在  Node.js
关注(0)|答案(1)|浏览(116)

我使用node.js ffmpeg-static将视频和音频Map到一起。

var VideoStream = ytdl(video, { filter: 'videoonly', quality: 'highestvideo' });
var AduioStream = ytdl(video, { filter: "audioonly", quality: 'highestaudio' });

const ffmpegProcess = cp.spawn(ffmpeg, [
  '-i', `pipe:3`,
  '-i', `pipe:4`,
  '-map', '0:v',
  '-map', '1:a',
  '-c:v', 'copy',
  '-c:a', 'aac',
  '-movflags', 'frag_keyframe',
  '-f', 'mp4',
  '-'
 ], {
  stdio: [
    'pipe', 'pipe', 'pipe', 'pipe', 'pipe',
  ],
});

VideoStream.pipe(ffmpegProcess.stdio[3]);
AduioStream.pipe(ffmpegProcess.stdio[4]);
ffmpegProcess.stdio[1].pipe(fs.createWriteStream('./out.mp4'));

保存的文件包含预期的音频和视频,但使用-movflags frag_keyframe时文件的长度仅为4秒。虽然视频在那之后继续(00:10 / 00:04)
-movflags faststart从不工作
如何自动或手动(Ytdl允许我下载视频长度)设置长度?
谢谢你

eit6fx6z

eit6fx6z1#

您所遇到的生成视频只有4秒长的问题可能与您使用的-movflags frag_keyframe选项有关。此选项会创建碎片化的MP4文件,这可能会导致某些播放器的播放时间出现问题。
要为生成的视频文件设置正确的持续时间,可以尝试从FFmpeg命令中删除-movflags frag_keyframe选项。这将生成一个没有碎片的常规MP4文件,它应该正确地表示视频的实际持续时间。
下面是不带-movflags frag_keyframe选项的代码的更新版本:

var VideoStream = ytdl(video, { filter: 'videoonly', quality: 'highestvideo' });
var AudioStream = ytdl(video, { filter: "audioonly", quality: 'highestaudio' });

const ffmpegProcess = cp.spawn(ffmpeg, [
  '-i', 'pipe:3',
  '-i', 'pipe:4',
  '-map', '0:v',
  '-map', '1:a',
  '-c:v', 'copy',
  '-c:a', 'aac',
  '-f', 'mp4',
  '-'
], {
  stdio: [
    'pipe', 'pipe', 'pipe', 'pipe', 'pipe',
  ],
});

VideoStream.pipe(ffmpegProcess.stdio[3]);
AudioStream.pipe(ffmpegProcess.stdio[4]);
ffmpegProcess.stdio[1].pipe(fs.createWriteStream('./out.mp4'));

通过删除-movflags frag_keyframe选项,生成的视频文件应具有基于原始视频和音频流的正确持续时间。
请注意,您提到的-movflags faststart选项用于将输出文件中的元数据移动到开头,以实现更快的流式传输。这与视频持续时间的问题无关,也不是解决您所描述的问题所必需的。

相关问题