Save RTMP Stream to MP4 Without Re-encoding Using FFmpeg

Capturing an RTMP camera stream and saving it directly to an MP4 file without re-encoding is an efficient way to record video while consuming minimal CPU and maintaining original visual quality. By utilizing FFmpeg’s stream copy functionality, you simply repackage (remux) the incoming H.264 video and AAC audio packets from the RTMP container into an MP4 container. This guide provides the exact FFmpeg commands needed to capture your stream, handle network drops, and prevent file corruption.

The Basic Command

To capture the live RTMP stream and save it to an MP4 file without re-encoding, run:

ffmpeg -i "rtmp://camera_ip_address/live/stream_key" -c copy output.mp4
  • -i "rtmp://...": Specifies the source URL of the RTMP stream.
  • -c copy: Instructs FFmpeg to bypass the decoding and encoding pipeline entirely, copying the audio and video streams directly into the target container.
  • output.mp4: Defines the name and format of the output file.

To stop the recording gracefully, press q or Ctrl + C in your terminal. This ensures FFmpeg writes the proper metadata header (the moov atom) so the MP4 file remains playable.

Preventing Corrupted Files on Unexpected Disconnects

Standard MP4 files place the index metadata at the end of the recording. If the camera disconnects or FFmpeg is abruptly terminated, the file may become unreadable. To make the file resilient against crashes, use fragmented MP4 flags:

ffmpeg -i "rtmp://camera_ip_address/live/stream_key" -c copy -movflags frag_keyframe+empty_moov output.mp4

This ensures the video can be played up to the exact second the connection dropped.

Optimizing for Web Playback

If you are stopping recordings normally and want the MP4 to be immediately streamable over the web without buffering the entire file first, relocate the index to the beginning of the file using faststart:

ffmpeg -i "rtmp://camera_ip_address/live/stream_key" -c copy -movflags +faststart output.mp4

Splitting Continuous Streams into Segments

For 24/7 camera monitoring, recording to a single giant file is risky and impractical. You can automatically split the recording into timed chunks (for example, 15-minute segments) without re-encoding:

ffmpeg -i "rtmp://camera_ip_address/live/stream_key" -c copy -f segment -segment_time 900 -reset_timestamps 1 -strftime 1 "capture_%Y-%m-%d_%H-%M-%S.mp4"
  • -f segment: Enables FFmpeg's segmenter muxer.
  • -segment_time 900: Sets the segment duration to 900 seconds (15 minutes).
  • -reset_timestamps 1: Resets timestamps at the beginning of each segment for smooth playback.
  • -strftime 1: Formats the output filename using standard date and time stamps.