How can I display the progress from execSync (ffmpeg) running in node.js to the browser?

702 views Asked by At

I'm trying to copy the video with Next.js API Routes.
With the command below, we were able to copy the video to the public folder.

./pages/api/copy-video.ts

import type { NextApiResponse } from "next";
import { execSync } from "child_process";

const copyVideo = async (res: NextApiResponse) => {
  const cmd = `ffmpeg -i public/input.mp4 -c copy -progress - public/output.mp4`;
  execSync(cmd, { stdio: "inherit" });
  res.status(200).end();
};

export default copyVideo;

Now that I can copy the video, I want to show the progress of the copy in the browser.
If possible, could you please tell me how to use execSync to display the progress in the browser?


The -progress - included in the command will cause the terminal to display the progress as follows.

[hls @ 0000026d93626a80] Opening 'crypto+input.mp4' for reading
frame=46975 fps=321 q=-1.0 size=  663552kB time=00:26:07.36 bitrate=3468.1kbits/s speed=10.7x    
fps=321.04
stream_0_0_q=-1.0
bitrate=3468.1kbits/s
total_size=679477296
out_time_us=1567365811
out_time_ms=1567365811
out_time=00:26:07.365811
dup_frames=0
drop_frames=0
speed=10.7x
progress=continue
[hls @ 0000026d93626a80] Opening 'crypto+input.mp4' for reading
frame=47098 fps=321 q=-1.0 size=  665600kB time=00:26:11.49 bitrate=3469.7kbits/s speed=10.7x    
fps=320.68
stream_0_0_q=-1.0
bitrate=3469.7kbits/s
total_size=681574448
out_time_us=1571498667
out_time_ms=1571498667
out_time=00:26:11.498667
dup_frames=0
drop_frames=0
speed=10.7x
progress=continue
frame=47255 fps=322 q=-1.0 Lsize=  667437kB time=00:26:16.78 bitrate=3467.6kbits/s speed=10.7x    
frame=47255
fps=321.67
stream_0_0_q=-1.0
bitrate=3467.6kbits/s
total_size=683455072
out_time_us=1576789333
out_time_ms=1576789333
out_time=00:26:16.789333
dup_frames=0
drop_frames=0
speed=10.7x
progress=end
video:653447kB audio:12778kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.181925%

I thought I could prepare an API to pass this display as an object to the browser, and get it from the browser every few seconds to display the progress in the browser.
However, I couldn't figure out how to extract this progress status displayed in the terminal as an object.


fluent-ffmpeg and FFMPEG Progress Wrapper had a method to return the progress. However, compared to execSync, the time it takes for the copy to complete is very slow and not practical.
The reason you want to use execSync is to reduce the time it takes for the copy to complete, as described above.
Therefore, we are willing to use fluent-ffmpeg or FFMPEG Progress Wrapper if you can get the same performance as the execution speed by execSync.

0

There are 0 answers