我可以下载 youtube 单独的视频和音频。但合并不起作用。 0 KB 文件正在下载
let info = await ytdl.getInfo(req.body.videoId);
let formatVideo = ytdl.chooseFormat(info.formats, { quality: req.body.format.itag, filter: 'videoonly' });
let formatAudio = ytdl.chooseFormat(info.formats, { quality: req.body.audioTag });
// res.json({video: formatVideo, audio: formatAudio});
const tracker = {
start: Date.now(),
audio: { downloaded: 0, total: Infinity },
video: { downloaded: 0, total: Infinity },
merged: { frame: 0, speed: '0x', fps: 0 },
};
res.header('Content-Disposition', `attachment; filename=${fileName}`);
cp.exec(`ffmpeg -i ${videoStream} -i ${audioStream} -c copy ${fileName}`, (error, success) => {
if (!error) {
console.log(success);
} else {
console.log(error);
}
});
// Prepare the progress bar
let progressbarHandle = null;
const progressbarInterval = 1000;
const showProgress = () => {
console.log('test');
readline.cursorTo(process.stdout, 0);
const toMB = i => (i / 1024 / 1024).toFixed(2);
process.stdout.write(`Audio | ${(tracker.audio.downloaded / tracker.audio.total * 100).toFixed(2)}% processed `);
process.stdout.write(`(${toMB(tracker.audio.downloaded)}MB of ${toMB(tracker.audio.total)}MB).${' '.repeat(10)}\n`);
process.stdout.write(`Video | ${(tracker.video.downloaded / tracker.video.total * 100).toFixed(2)}% processed `);
process.stdout.write(`(${toMB(tracker.video.downloaded)}MB of ${toMB(tracker.video.total)}MB).${' '.repeat(10)}\n`);
process.stdout.write(`Merged | processing frame ${tracker.merged.frame} `);
process.stdout.write(`(at ${tracker.merged.fps} fps => ${tracker.merged.speed}).${' '.repeat(10)}\n`);
process.stdout.write(`running for: ${((Date.now() - tracker.start) / 1000 / 60).toFixed(2)} Minutes.`);
readline.moveCursor(process.stdout, 0, -3);
};
// Start the ffmpeg child process
const ffmpegProcess = cp.spawn(ffmpeg, [
// Remove ffmpeg's console spamming
'-loglevel', '8', '-hide_banner',
// Redirect/Enable progress messages
'-progress', 'pipe:3',
// Set inputs
'-i', 'pipe:4',
'-i', 'pipe:5',
// Map audio & video from streams
'-map', '0:a',
'-map', '1:v',
// Keep encoding
'-c:v', 'copy',
// Define output file
`${fileName}`,
], {
windowsHide: true,
stdio: [
/* Standard: stdin, stdout, stderr */
'inherit', 'inherit', 'inherit',
/* Custom: pipe:3, pipe:4, pipe:5 */
'pipe', 'pipe', 'pipe', 'pipe'
],
});
ffmpegProcess.on('close', () => {
console.log('done');
// Cleanup
process.stdout.write('\n\n\n\n');
clearInterval(progressbarHandle);
console.log(tracker, '146');
});
// Link streams
// FFmpeg creates the transformer streams and we just have to insert / read data
ffmpegProcess.stdio[3].on('data', chunk => {
console.log(chunk, '152');
// Start the progress bar
if (!progressbarHandle) progressbarHandle = setInterval(showProgress, progressbarInterval);
// Parse the param=value list returned by ffmpeg
const lines = chunk.toString().trim().split('\n');
const args = {};
for (const l of lines) {
const [key, value] = l.split('=');
args[key.trim()] = value.trim();
}
tracker.merged = args;
// console.log(tracker.merged, '162');
});
// audio.pipe(ffmpegProcess.stdio[4]);
// video.pipe(ffmpegProcess.stdio[5]);
const audioStream = await requestObj.get(formatAudio.url);
const videoStream = await requestObj.get(formatVideo.url);
audioStream.pipe(ffmpegProcess.stdio[4]);
videoStream.pipe(ffmpegProcess.stdio[5]);
ffmpegProcess.stdio[6].pipe(res);
这里 requestObj 是一个 node js 'request' 模块