How to convert MP4 frame rate like 14.939948fps to 15fps

Viewed 328

Description

I pushed a USB camera stream by ffmpeg to a RTMP stream server which is called SRS.

The SRS had saved a MP4 file for me. The frame rate is not a common value in VLC - it's 14.939948. I've checked it out - It seems to be the 'ntsc' format.

Meanwhile, I had received the stream by OpenCV and saved it as another MP4 file.They're not synchronized.

I have tried to convert the frame rate by ffmpeg but was still not synchronized. The only way to make it is to put it in Adobe Premiere and modify the frame rate. Here is the ffmpeg commands I executed:

ffmpeg -i 1639444871684_copy.mp4 -filter:v fps=15 out.mp4

Aside from the stream server, how can I convert the frame rate to normal and keep synchronized at the same time?

3 Answers

Note: For live streaming, you should never depends on the FPS, because RTMP/FLV always use fixed TBN 1k, so there is always introduce some deviation, when publish stream as RTMP or record to other format like TS/MP4.

Note: For WebRTC, the fps is variant, please read Would WebRTC use a constant frame rate to capture video frame or about the Variable Frame Rate (VFR)

It's not a problem of SRS or FPS, you can also replay it by FFmpeg.

  1. Use FFmpeg to transcode doc/source.flv from 25fps to 15fps, then publish to SRS by RTMP(15fps).
  2. Use FFmpeg to record the RTMP(15fps) as output.mp4(15fps).
  3. Use VLC to play the output.mp4(15fps), it show the fps IS NOT 15fps.

First, please start SRS by bellow config, note that DVR disabled:

# ./objs/srs -c test.conf
listen              1935;
daemon              off;
srs_log_tank        console;

vhost __defaultVhost__ {
}

Run FFmpeg to transcode and publish to SRS, change the fps to 15:

cd srs/trunk
ffmpeg -re -i doc/source.flv -c:v libx264 -r 15 -c:a copy \
  -f flv rtmp://localhost/live/livestream

Record the RTMP stream(in 15fps) to output.mp4, note tat the fps is, in FFmpeg logs, it's 15fps:

ffmpeg -f flv -i rtmp://localhost/live/livestream -c copy -y output.mp4

Use VLC to play the output.mp4 which is 15fps, open the Window -> Media Information, you will find out that the fps is changing around 14.8fps, not 15fps!

It's because the TBN of RTMP/FLV, is fixed 1000(1k tbn, each frame is about 66.66666666666667ms), so the deviation is introduced when publish MP4 to RTMP stream. It's not caused by DVR, it's caused by RTMP/FLV TBN.

Note: However, for SRS, using fixed TBN 1k is not a good choice, because it's not friendly for MP4 duration, I reopen the issue srs#2790.

Ultimately, the framerate/fps is not a fixed stuff, it's just a number that give some tips about the stream. Instead, the player always use the DTS/PTS to decide when and how to render the picture.

Answer myself. Here is my method: Read by OpenCV and write frames to a new file at 15FPS. They're going to be synchronized.

with -r

ffmpeg -i 1639444871684_copy.mp4 -r 15 out.mp4
Related