MediaMTX RTSP 容器不代理源

hot*_*oup 6 portforwarding docker docker-network

请注意:即使添加了端口转发标志,此问题仍然存在,因此其他 SO 答案在这里对我没有帮助。我知道我在这里询问开源MediaMTX RTSP服务器,但我相信这本质上是一个纯粹的 Docker 问题;因此,任何具有 Docker 网络经验的人都可以回答这个问题,无论他们是否有 MediaMTX 的经验。


我这里使用的是 Mac 笔记本电脑。我通过 docker 运行 MediaMTX,如下所示:

docker run --rm -it -p 8554:8554 bluenviron/mediamtx:latest
2023/10/16 15:05:22 INF MediaMTX v1.2.0
2023/10/16 15:05:22 INF configuration loaded from /mediamtx.yml
2023/10/16 15:05:22 INF [RTSP] listener opened on :8554 (TCP), :8000 (UDP/RTP), :8001 (UDP/RTCP)
2023/10/16 15:05:22 INF [RTMP] listener opened on :1935
2023/10/16 15:05:22 INF [HLS] listener opened on :8888
2023/10/16 15:05:22 INF [WebRTC] listener opened on :8889 (HTTP)
2023/10/16 15:05:22 INF [SRT] listener opened on :8890 (UDP)
Run Code Online (Sandbox Code Playgroud)

我可以确认它正在运行:

docker ps
CONTAINER ID   IMAGE                        COMMAND       CREATED          STATUS          PORTS     NAMES
ef27229a41c4   bluenviron/mediamtx:latest   "/mediamtx"   19 seconds ago   Up 18 seconds             goofy_franklin
Run Code Online (Sandbox Code Playgroud)

看看telnet它就好了:

telnet localhost 8554
Trying ::1...
Connected to localhost.
Escape character is '^]'.
Run Code Online (Sandbox Code Playgroud)

但是当我通过它发布(写入/流式传输)MP4 时,ffmpeg出现管道损坏错误:

ffmpeg -re -stream_loop -1 -i fireplace.mp4 -c copy -f rtsp rtsp://localhost:8554/mystream     
ffmpeg version 6.0 Copyright (c) 2000-2023 the FFmpeg developers
  built with Apple clang version 14.0.0 (clang-1400.0.29.202)
  configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/6.0_1 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox --enable-neon
  libavutil      58.  2.100 / 58.  2.100
  libavcodec     60.  3.100 / 60.  3.100
  libavformat    60.  3.100 / 60.  3.100
  libavdevice    60.  1.100 / 60.  1.100
  libavfilter     9.  3.100 /  9.  3.100
  libswscale      7.  1.100 /  7.  1.100
  libswresample   4. 10.100 /  4. 10.100
  libpostproc    57.  1.100 / 57.  1.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'fireplace.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
  Duration: 00:00:11.27, start: 0.000000, bitrate: 522 kb/s
  Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, smpte170m/bt470bg/smpte170m, progressive), 368x640, 448 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc59.37.100 libx264
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 64 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Output #0, rtsp, to 'rtsp://localhost:8554/mystream':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf60.3.100
  Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, smpte170m/bt470bg/smpte170m, progressive), 368x640, q=2-31, 448 kb/s, 30 fps, 30 tbr, 90k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc59.37.100 libx264
  Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 64 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
av_interleaved_write_frame(): Broken pipe00:00:09.60 bitrate=N/A speed=   1x    /s speed=N/A    
[out#0/rtsp @ 0x128f15b00] Error muxing a packet
[out#0/rtsp @ 0x128f15b00] Error writing trailer: Broken pipe
frame=  305 fps= 30 q=-1.0 Lsize=N/A time=00:00:10.10 bitrate=N/A speed=   1x    
video:560kB audio:80kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Conversion failed!
Run Code Online (Sandbox Code Playgroud)

当我运行该命令时,我在容器日志中得到以下输出:

2023/10/19 23:26:43 INF [RTSP] [conn 192.168.65.1:22506] opened
2023/10/19 23:26:43 INF [RTSP] [session f1b1b628] created by 192.168.65.1:22506
2023/10/19 23:26:43 INF [RTSP] [session f1b1b628] is publishing to path 'mystream', 2 tracks (H264, MPEG-4 Audio)
2023/10/19 23:26:50 INF [RTSP] [session f1b1b628] destroyed: torn down by 192.168.65.1:22506
2023/10/19 23:26:50 INF [RTSP] [conn 192.168.65.1:22506] closed: EOF
2023/10/19 23:26:53 INF [RTSP] [conn 192.168.65.1:22507] opened
2023/10/19 23:26:53 INF [RTSP] [session b7be9e08] created by 192.168.65.1:22507
2023/10/19 23:26:53 INF [RTSP] [session b7be9e08] is publishing to path 'mystream', 2 tracks (H264, MPEG-4 Audio)
2023/10/19 23:27:03 INF [RTSP] [conn 192.168.65.1:22507] closed: terminated
2023/10/19 23:27:03 INF [RTSP] [session b7be9e08] destroyed: session timed out
Run Code Online (Sandbox Code Playgroud)

因此,看起来能够ffmpeg连接到 RTSP 服务器,但无法实际向其发送任何内容。

谁能发现我可能出问题的地方吗?

rno*_*ris 6

使用以下内容:

docker run --rm -it --network=host -p 8554:8554

ffmpeg -re -stream_loop -1 -i fireplace.mp4 -c copy -f rtsp -rtsp_transport tcp rtsp://localhost:8554/mystream

使用以下方式查看流:

ffplay -rtsp_transport tcp rtsp://localhost:8554/mystream

解释:

由于您在 Mac 上运行此程序,因此您可能使用 Docker Desktop。Docker Desktop 文档对主机网络有这样的说法:

主机网络驱动程序仅适用于 Linux 主机,Docker Desktop for Mac、Docker Desktop for Windows 或 Docker EE for Windows Server 不支持。

由于您正在运行docker run --rm -it --network=host -p 8554:8554 bluenviron/mediamtx:latest,该--network=host选项将覆盖您在命令中提供的任何端口分配。由于此模式在 Mac 版 Docker Desktop 上不起作用,这意味着您的容器将无法访问。

要解决此问题,您需要显式转发您想要使用的端口。我能够在 Mac 上运行以下内容:

docker run --rm -it -p 8554:8554 bluenviron/mediamtx:latest<- 启动服务器

为了测试其是否有效,我使用以下命令通过 RTSP 服务器传输一系列连续的灰色帧:

ffmpeg -readrate 1 -f lavfi -i color=c=gray -vf "fps=25,format=yuv420p" -c:v libx264 -f rtsp -rtsp_transport tcp rtsp://localhost:8554/mystream

-readrate 1限制 ffmpeg 发送帧的速度过快,因为我们通过该合成视频获得的帧速率可能会导致问题。

-f lavfi -i color=c=gray连续生成灰帧,因此我们不需要依赖任何特定视频进行测试

-vf "fps=25,format=yuv420p"设置视频格式(25 FPS 和 420p 分辨率)

-c:v libx264根据其文档,将编解码器设置为 H264,这是 mediamtx 的 RTSP 流支持的编解码器之一。

-f rtsp -rtsp_transport tcp设置输出格式和传输协议。请注意,上面的命令丢失了-rtsp_transport tcp,我发现在相同的设置(macOS / docker / ffmpeg)中这是必要的。这可能是您需要添加到您自己的 ffmpeg 命令中的内容。

I was able to confirm that this stream was functional by viewing it with ffmpeg using the following command:

ffplay -rtsp_transport tcp rtsp://localhost:8554/mystream

Edit for stream capture, per request:

To capture the output of your stream back into a local file, you can use the following command:

ffmpeg -rtsp_transport tcp -i rtsp://localhost:8554/mystream -c copy fp-copy.mp4

Since your original command will infinitely loop the fireplace.mp4 file you have, this will continue to capture until your disk is full. To limit it to a specific duration, you can use the -t option on your output like so:

ffmpeg -rtsp_transport tcp -i rtsp://localhost:8554/mystream -c copy -t 60 fp-copy.mp4

This will copy the first 60 seconds from the time you start streaming. Increase it to whatever duration you would like.

You can also limit by file size instead of duration. To do that, use:

ffmpeg -rtsp_transport tcp -i rtsp://localhost:8554/mystream -c copy -fs 100M fp-copy.mp4

This will limit the output to 100MB.

Note that the first few seconds of your captured output may be black. This comes from the period where ffmpeg is establishing a connection to the RTSP stream.

If you don't want to go through the trouble of trimming out this segment with an external tool, you can modify the command to:

ffmpeg -rtsp_transport tcp -i rtsp://localhost:8554/mystream -vf "trim=start=10,setpts=PTS-STARTPTS" -af "atrim=start=10,asetpts=PTS-STARTPTS" -t 20 fp-copy.mp4

This new -vf option will trim the first 10 seconds from both audio and video. Note that this is incompatible with the -c copy option, but it seems to work fine all the same.