繁体   English   中英

node.js ffmpeg spawn child_process 意外数据输出

[英]node.js ffmpeg spawn child_process unexpected data output


我对后端的东西很陌生,所以请原谅,如果我的问题是微不足道的。
对于一个 Intranet 项目,我想在网页(React、HLS.js Player)中呈现一个视频元素。
视频源是作为 udp 多播传送的 mpeg-ts 流。
一个小的 node.js / express 服务器应该处理 ffmpeg 命令,将多播转码为 hls 以在浏览器中显示它们。

问题是输出:
输出在 stderr 上发出......甚至该过程也按预期工作。
这是迄今为止我为转码编写的相应代码:

const express = require("express");
const { spawn, exec } = require("child_process");
const process = require("process")

let ls;

const app = express();

app.get('/cam/:source', (body) => {
    const cam = body.params.source;
    console.log(cam);

    let source = "udp://239.1.1.1:4444";
    let stream = "/var/www/html/streams/tmp/cam1.m3u8"


    stream = spawn("ffmpeg", ["-re", "-i", source, "-c:v", "libx264", "-crf", "21", "-preset", "veryfast", "-c:a", "aac", "-b:a", "128k", "-ac", "2", "-f", "hls", "-hls_list_size", "5", "-hls_flags", "delete_segments", stream], {detached: true});

    stream.stdout.on("data", data => {
        console.log(`stdout: ${data}`);
    });

    stream.stderr.on("data", data => {
        console.log(`stderr: ${data}`);
    });

    stream.on("error", error => {
        console.log(`error: ${error.message}`);
    });

    stream.on("close", code => {
        console.log(`child process exited with code ${code}`);
    });
})

app.listen(5000, ()=> {
    console.log('Listening');
})

这可能只是化妆品,但它让我想知道。
这是终端输出:

[nodemon] starting `node server.js`
Listening
camera stream reloaded
stderr: ffmpeg version 4.3.2-0+deb11u1ubuntu1 Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 10 (Ubuntu 10.2.1-20ubuntu1)

  --shortend--


pid:  4206
stderr: frame=    8 fps=0.0 q=0.0 size=N/A time=00:00:00.46 bitrate=N/A speed=0.931x    
pid:  4206
stderr: frame=   21 fps= 21 q=26.0 size=N/A time=00:00:00.96 bitrate=N/A speed=0.95x    
pid:  4206
stderr: frame=   33 fps= 22 q=26.0 size=N/A time=00:00:01.49 bitrate=N/A speed=0.982x    
pid:  4206
stderr: frame=   46 fps= 23 q=26.0 size=N/A time=00:00:02.00 bitrate=N/A speed=0.989x    
pid:  4206
stderr: frame=   58 fps= 23 q=26.0 size=N/A time=00:00:02.49 bitrate=N/A speed=0.986x    
pid:  4206

等等...

任何有用的信息将不胜感激!
提前谢谢了

如果它正常工作,您无需担心该输出。

使用spawn您已经创建了一个围绕特定进程的包装器,来自stream.stderr的输出是由继承进程的warn/error触发的, warn不是值得关注的,特别是如果您的应用程序行为正确。

我在下面放了一个关于如何触发warnerror的简单演示,以便您可以更清楚地看到发生了什么:

索引.js

const {spawn} = require('child_process');

const output = (label) => (data) => {
    let str = data.toString().split(/(\r\n|\n)+/).filter(i => i.trim().length);
    str.forEach(row => {
        console.log(`[${label}]`, row);
    })
};
let proc = spawn('node', ['proc.js'], {
    shell: true,
    env: {
        ...process.env
    },
})

proc.stdout.on('data', output('data'));
proc.stderr.on('data', output('error'));

程序.js

setInterval(()=>{
    console.log('default log',new Date())
    console.info('info log', new Date())
    console.error('error log', new Date());
    console.warn('warn log', new Date());
}, 1000);

/** Output: 
[data] default log 2021-09-05T10:03:22.283Z
[error] error log 2021-09-05T10:03:22.287Z
[error] warn log 2021-09-05T10:03:22.287Z
[data] info log 2021-09-05T10:03:22.287Z
[data] default log 2021-09-05T10:03:23.292Z
[error] error log 2021-09-05T10:03:23.293Z
[error] warn log 2021-09-05T10:03:23.293Z
[data] info log 2021-09-05T10:03:23.293Z
[data] default log 2021-09-05T10:03:24.299Z
[error] error log 2021-09-05T10:03:24.299Z
[error] warn log 2021-09-05T10:03:24.299Z
[data] info log 2021-09-05T10:03:24.299Z

我已经运行ffmpeg -version ,日志:

[data] ffmpeg version git-2020-06-17-0b3bd00 Copyright (c) 2000-2020 the FFmpeg developers
[data] built with gcc 9.3.1 (GCC) 20200523
[data] configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore
-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libweb
p --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --en
able-libxvid --enable-libaom --disable-w32threads --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
[data] libavutil      56. 55.100 / 56. 55.100
[data] libavcodec     58. 92.100 / 58. 92.100
[data] libavformat    58. 46.101 / 58. 46.101
[data] libavdevice    58. 11.100 / 58. 11.100
[data] libavfilter     7. 86.100 /  7. 86.100
[data] libswscale      5.  8.100 /  5.  8.100
[data] libswresample   3.  8.100 /  3.  8.100
[data] libpostproc    55.  8.100 / 55.  8.100

我还运行了一个ffmpeg过程进行转换,文件没问题,这里是日志:

[error] ffmpeg version git-2020-06-17-0b3bd00 Copyright (c) 2000-2020 the FFmpeg developers
[error]   built with gcc 9.3.1 (GCC) 20200523
[error]   configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopenc
ore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-lib
webp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex -
-enable-libxvid --enable-libaom --disable-w32threads --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-a
mf
[error]   libavutil      56. 55.100 / 56. 55.100
[error]   libavcodec     58. 92.100 / 58. 92.100
[error]   libavformat    58. 46.101 / 58. 46.101
[error]   libavdevice    58. 11.100 / 58. 11.100
[error]   libavfilter     7. 86.100 /  7. 86.100
[error]   libswscale      5.  8.100 /  5.  8.100
[error]   libswresample   3.  8.100 /  3.  8.100
[error]   libpostproc    55.  8.100 / 55.  8.100
[error] Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '2020-11-23_18-47-52.mp4':
[error]   Metadata:
[error]     major_brand     : isom
[error]     minor_version   : 512
[error]     compatible_brands: isomiso2avc1mp41
[error]     encoder         : Lavf58.29.100
[error]   Duration: 00:00:03.17, start: 0.000000, bitrate: 30039 kb/s
[error]     Stream #0:0(und)
[error] : Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 30026 kb/s, 60 fps, 60 tbr, 15360 tbn, 120 tbc (default)
[error]     Metadata:
[error]       handler_name    : VideoHandler
[error]     Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 2 kb/s (default)
[error]     Metadata:
[error]       handler_name    : SoundHandler
[error] Stream mapping:
[error]   Stream #0:0 -> #0:0 (h264 (native) -> hevc (libx265))
[error]   Stream #0:1 -> #0:1 (aac (native) -> aac (native))
[error] Press [q] to stop, [?] for help
[error] [swscaler @ 000002cddcf89d40] deprecated pixel format used, make sure you did set range correctly
[error] x265 [info]: HEVC encoder version 3.3+29-1e3dbf09ee4f
[error] x265 [info]: build info [Windows][GCC 9.3.1][64 bit] 8bit+10bit
[error] x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[error] x265 [info]: Main profile, Level-4.1 (Main tier)
[error] x265 [info]: Thread pool created using 12 threads
[error] x265 [info]: Slices                              : 1
[error] x265 [info]: frame threads / pool features       : 3 / wpp(30 rows)
[error] x265 [warning]: VBV maxrate unspecified, assuming CBR
[error] x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
[error] x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
[error] x265 [info]: ME / range / subpel / merge         : hex / 57 / 1 / 2
[error] x265 [info]: Keyframe min / max / scenecut / bias  : 25 / 250 / 40 / 5.00
[error] x265 [info]: Lookahead / bframes / badapt        : 15 / 4 / 0
[error] x265 [info]: b-pyramid / weightp / weightb       : 1 / 1 / 0
[error] x265 [info]: References / ref-limit  cu / depth  : 2 / on / on
[error] x265 [info]: AQ: mode / str / qg-size / cu-tree  : 2 / 1.0 / 32 / 1
[error] x265 [info]: Rate Control / qCompress            : ABR-800 kbps / 0.60
[error] x265 [info]: VBV/HRD buffer / max-rate / init    : 1200 / 800 / 0.750
[error] x265 [info]: tools: rd=2 psy-rd=2.00 early-skip rskip mode=1 signhide tmvp
[error] x265 [info]: tools: fast-intra strong-intra-smoothing lslices=8 deblock sao
[error] Output #0, mp4, to 'outputXZ.mp4':
[error]   Metadata:
[error]     major_brand     : isom
[error]     minor_version   : 512
[error]     compatible_brands: isomiso2avc1mp41
[error]     encoder         : Lavf58.46.101
[error]     Stream #0:0(und): Video: hevc (libx265) (hvc1 / 0x31637668), yuv420p, 1080x1920 [SAR 256:81 DAR 16:9], q=-1--1, 800 kb/s, 60 fps, 15360 tbn, 60 tbc (default)
[error]     Metadata:
[error]       handler_name    : VideoHandler
[error]       encoder         : Lavc58.92.100 libx265
[error]     Side data:
[error]       cpb: bitrate max/min/avg: 0/0/800000 buffer size: 1200000 vbv_delay: N/A
[error]     Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
[error]     Metadata:
[error]       handler_name    : SoundHandler
[error]       encoder         : Lavc58.92.100 aac
[error] frame=   47 fps=0.0 q=39.0 size=       0kB time=00:00:00.95 bitrate=   0.4kbits/s speed=1.89x
[error] frame=  110 fps=109 q=11.0 size=       0kB time=00:00:01.97 bitrate=   0.2kbits/s speed=1.96x
[error] frame=  172 fps=114 q=5.0 size=       0kB time=00:00:03.04 bitrate=   0.1kbits/s speed=2.01x
[error] frame=  190 fps=106 q=6.0 Lsize=      36kB time=00:00:03.15 bitrate=  94.2kbits/s speed=1.76x
[error] video:27kB audio:1kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: 31.662476%
[error] x265 [info]: frame I:      1, Avg QP:50.77  kb/s: 296.16
[error] x265 [info]: frame P:     38, Avg QP:22.16  kb/s: 67.17
[error] x265 [info]: frame B:    151, Avg QP:17.18  kb/s: 65.79
[error] x265 [info]: Weighted P-Frames: Y:0.0% UV:0.0%
[error] x265 [info]: consecutive B-frames: 2.6% 0.0% 0.0% 2.6% 94.9%
[error] encoded 190 frames in 1.75s (108.45 fps), 67.28 kb/s, Avg QP:18.35
[error] [aac @ 000002cddd6d0a80] Qavg: 65536.000

不幸的是,您无法控制更改输出的过程,您只需要按原样使用它。 只是不要把你所有的信心都放在应用程序输出上,它在那里,所以你可以看看事情是否顺利。

但是,您可以控制捕获的输出,您可以修改您认为合适的方式,就像我在output函数中所做的那样。

PS:任何退出的 exitCode 不是 0 的进程都被认为是失败的。 有时,程序员可以在不知道这一点的情况下对行为正确的进程强制执行process.exit(1) ,当然,如果其他人正在使用该进程,则会触发他们的error事件/条件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM