0

我有一个 mediasoup 服务器设置,现在我需要录制功能。为此,我正在执行以下操作 -
在让事件开始录制时,我调用此函数:

async handleStartRecording(peer, router)
    {
        let transports = [],
            consumers = [],
            ffmpegInput = {};
        for(let entry of peer.producers.entries())
        {
            const rtpTransport = await router.createPlainTransport({
                comedia: false,
                rtcpMux: false,
                listenIp: { ip: '127.0.0.1', announcedIp: null }
            });
            transports.push(rtpTransport);

            const port = (entry[1].kind === 'audio') ? 8994 : 8996;
            const rtcpPort = port+1;

            await rtpTransport.connect({
                ip: '127.0.0.1',
                port: port,
                rtcpPort: rtcpPort,
                rtcpMux: false
            });
            peer.addTransport(rtpTransport.id, rtpTransport);

            const rtpConsumer = await rtpTransport.consume({
                producerId: entry[0],
                rtpCapabilities: router.rtpCapabilities, 
                paused: true,
            });
            consumers.push(rtpConsumer);

            const codecs = [];
            const routerCodec = router.rtpCapabilities.codecs.find(
              codec => codec.kind === entry[1].kind
            );
            codecs.push(routerCodec);
            const rtpCapabilities = {
                codecs,
                rtcpFeedback: []
            };

            ffmpegInput[entry[1].kind] = {
                port,
                rtcpPort,
                localRtcpPort: rtpTransport.rtcpTuple ? rtpTransport.rtcpTuple.localPort : undefined,
                rtpCapabilities,
                rtpParameters: rtpConsumer.rtpParameters,
                preferredPayloadType: routerCodec.payloadType
            };
        }
        
        ffmpegInput.fileName = Date.now().toString();
        peer._process = new FFmpeg(ffmpegInput, consumers);
    }

ffmpeg 类是:

class FFmpeg {
    constructor(rtpParameters, consumers) {
        this._rtpParameters = rtpParameters;
        this._consumers = consumers;
        this._process = undefined;
        this._createProcess();
    }
    _createProcess() {
        this._process = child_process.spawn('ffmpeg', this._commandArgs);
        consumers.forEach((consumer) =>
        {
            consumer.resume();
        });
    }
get _commandArgs() {
        let commandArgs = [
            '-loglevel',
            'debug',
            '-protocol_whitelist',
            'file,crypto,pipe,udp,rtp',
            '-fflags',
            '+genpts',
            '-i',
            '/recording/input-h264.sdp', //path to sdp file has full path this is sample
            '-map',            // video
            '0:v:0',
            '-c:v',
            'copy',
            '-map',            //audio
            '0:a:0',
            '-strict',
            '-2',
            '-c:a',
            'copy',
            '-f',
            'webm',
            '-flags',
            '+global_header',
            '-y',
            `/files/${this._rtpParameters.fileName}.webm`
        ]);
        return commandArgs;
    }
}

sdp文件:

v=0
o=- 0 0 IN IP4 127.0.0.1
s=FFmpeg
c=IN IP4 127.0.0.1
t=0 0
m=video 8996 RTP/AVPF 101
a=rtcp:8997
a=rtpmap:101 VP8/90000
a=fmtp:101 level-asymmetry-allowed=1
m=audio 8994 RTP/AVPF 100
a=rtcp:8995
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1

现在,我得到一个未找到流 0 错误的编解码器参数。

createProcess() [sdpString:v=0
            o=- 0 0 IN IP4 127.0.0.1
            s=FFmpeg
            c=IN IP4 127.0.0.1
            t=0 0
            m=video 8996 RTP/AVP 101
            a=rtpmap:101 VP8/90000
            a=sendonly
            m=audio 8994 RTP/AVP 100
            a=rtpmap:100 opus/48000/2
            a=sendonly
            ]
commandArgs:[ '-analyzeduration',
  '2147483647',
  '-probesize',
  '2147483647',
  '-loglevel',
  'debug',
  '-protocol_whitelist',
  'file,crypto,pipe,udp,rtp',
  '-fflags',
  '+genpts',
  '-i',
  '/recording/input-h264.sdp',
  '-map',
  '0:v:0',
  '-c:v',
  'copy',
  '-map',
  '0:a:0',
  '-strict',
  '-2',
  '-c:a',
  'copy',
  '-f',
  'webm',
  '-flags',
  '+global_header',
  '-y',
  '/files/1623939179824.webm',
  [length]: 28 ]
ffmpeg::process::data(err) [data:ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
]
ffmpeg::process::data(err) [data:  configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
]
ffmpeg::process::data(err) [data:  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
]
ffmpeg::process::data(err) [data:  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Splitting the commandline.
Reading option '-analyzeduration' ...]
ffmpeg::process::data(err) [data: matched as AVOption 'analyzeduration' with argument '2147483647'.
Reading option '-probesize' ...]
ffmpeg::process::data(err) [data: matched as AVOption 'probesize' with argument '2147483647'.
Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument 'debug'.
Reading option '-protocol_whitelist' ...]
ffmpeg::process::data(err) [data: matched as AVOption 'protocol_whitelist' with argument 'file,crypto,pipe,udp,rtp'.
Reading option '-fflags' ...]
ffmpeg::process::data(err) [data: matched as AVOption 'fflags' with argument '+genpts'.
Reading option '-i' ... matched as input url with argument '/recording/input-h264.sdp'.
Reading option '-map' ... matched as option 'map' (set input stream mapping) with argument '0:v:0'.
Reading option '-c:v' ... matched as option 'c' (codec name) with argument 'copy'.
Reading option '-map' ...]
ffmpeg::process::data(err) [data: matched as option 'map' (set input stream mapping) with argument '0:a:0'.
Reading option '-strict' ...]
ffmpeg::process::data(err) [data:Routing option strict to both codec and muxer layer
 matched as AVOption 'strict' with argument '-2'.
Reading option '-c:a' ... matched as option 'c' (codec name) with argument 'copy'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'webm'.
Reading option '-flags' ...]
ffmpeg::process::data(err) [data: matched as AVOption 'flags' with argument '+global_header'.
Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'.
Reading option '/files/1623939179824.webm' ... matched as output url.
Finished splitting the commandline.
]
ffmpeg::process::data(err) [data:Parsing a group of options: global .
Applying option loglevel (set logging level) with argument debug.
Applying option y (overwrite output files) with argument 1.
Successfully parsed a group of options.
Parsing a group of options: input url /recording/input-h264.sdp.
Successfully parsed a group of options.
Opening an input file: /recording/input-h264.sdp.
]
ffmpeg::process::data(err) [data:[NULL @ 0x55b7141c1a80] Opening '/recording/input-h264.sdp' for reading
]
ffmpeg::process::data(err) [data:[sdp @ 0x55b7141c1a80] Format sdp probed with size=2048 and score=50
]
ffmpeg::process::data(err) [data:[sdp @ 0x55b7141c1a80] video codec set to: vp8
[sdp @ 0x55b7141c1a80] audio codec set to: opus
[sdp @ 0x55b7141c1a80] audio samplerate set to: 48000
[sdp @ 0x55b7141c1a80] audio channels set to: 2
]
ffmpeg::process::data(err) [data:[udp @ 0x55b7141c4d40] end receive buffer size reported is 131072
[udp @ 0x55b7141cac00] end receive buffer size reported is 131072
[sdp @ 0x55b7141c1a80] setting jitter buffer size to 500
]
ffmpeg::process::data(err) [data:[udp @ 0x55b7141c5d40] end receive buffer size reported is 131072
]
ffmpeg::process::data(err) [data:[udp @ 0x55b7141c5e00] end receive buffer size reported is 131072
[sdp @ 0x55b7141c1a80] setting jitter buffer size to 500
]
ffmpeg::process::data(err) [data:[sdp @ 0x55b7141c1a80] Before avformat_find_stream_info() pos: 262 bytes read:262 seeks:0 nb_streams:2
]
ffmpeg::process::data(err) [data:[sdp @ 0x55b7141c1a80] Could not find codec parameters for stream 0 (Video: vp8, 1 reference frame, yuv420p): unspecified size
Consider increasing the value for the 'analyzeduration' and 'probesize' options
]
ffmpeg::process::data(err) [data:[sdp @ 0x55b7141c1a80] After avformat_find_stream_info() pos: 262 bytes read:262 seeks:0 frames:0
Input #0, sdp, from '/recording/input-h264.sdp':
  Metadata:
    title           : FFmpeg
  Duration: N/A, bitrate: N/A
    Stream #0:0, 0, 1/90000: Video: vp8, 1 reference frame, yuv420p, 90k tbr, 90k tbn, 90k tbc
    Stream #0:1, 0, 1/48000: Audio: opus, 48000 Hz, stereo, fltp
Successfully opened the file.
Parsing a group of options: output url /files/1623939179824.webm.
Applying option map (set input stream mapping) with argument 0:v:0.
Applying option c:v (codec name) with argument copy.
Applying option map (set input stream mapping) with argument 0:a:0.
]
ffmpeg::process::data(err) [data:Applying option c:a (codec name) with argument copy.
Applying option f (force format) with argument webm.
Successfully parsed a group of options.
Opening an output file: /files/1623939179824.webm.
]
ffmpeg::process::data(err) [data:[file @ 0x55b714243880] Setting default whitelist 'file,crypto'
]
ffmpeg::process::data(err) [data:Successfully opened the file.
]
ffmpeg::process::data(err) [data:[webm @ 0x55b71423e100] dimensions not set
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
    Last message repeated 1 times
[AVIOContext @ 0x55b714243b00] Statistics: 0 seeks, 0 writeouts
[AVIOContext @ 0x55b7141cacc0] Statistics: 262 bytes read, 0 seeks
]
ffmpeg::process::close

我已经做了好几天了,我什至不知道如何调试这个问题。我尝试使用 vlc 的流选项和服务器的 url 来检查传输是否正常工作,但它没有在该端口的 localhost 上检测到任何内容。
如果有人对此问题或调试方法有任何想法,请告诉我..

4

1 回答 1

-1

I couldn't get ffmpeg to record from sdp input. So I finally resorted to using gstreamer to do it.
Example here : mediasoup recording demo

于 2021-06-22T19:54:56.437 回答