简体   繁体   English

将帧从网络摄像机(RTSP)保存到mp4文件

[英]Saving frames from a network camera (RTSP) to a mp4 file

I am quite confused about how to save a video stream into a mp4 file. 我对如何将视频流保存到mp4文件中感到非常困惑。 I am using ffmpeg. 我正在使用ffmpeg。 Let me explain the problem: 让我解释一下这个问题:

  1. I connect to a network camera via RTSP (H.264 stream) with avformat_open_input(), avformat_find_stream_info(), av_read_play(), and I get frames with av_read_frame(). 我使用avformat_open_input(),avformat_find_stream_info(),av_read_play()通过RTSP(H.264流)连接到网络摄像机,并使用av_read_frame()获得帧。
  2. Each time I get a frame with av_read_frame(), I store the corresponding AVPacket in a circular buffer. 每次使用av_read_frame()获取一帧时,我都会将相应的AVPacket存储在循环缓冲区中。
  3. In some points in my application, a range of this circular buffer is selected. 在我的应用程序中的某些地方,选择了此循环缓冲区的范围。 I find a key frame used to start from. 我找到了一个关键的起点。
  4. Once I have a list of AVPacket's starting from a key frame, I write header, frames, and tail, as I described below in the code. 有了从关键帧开始的AVPacket列表后,就可以编写标题,帧和尾部,如下面在代码中所述。

The problem is that the resulting mp4 video has artifacts if I try to watch it using VLC, Windows Media Player, or another one. 问题是,如果我尝试使用VLC,Windows Media Player或其他播放器观看最终的mp4视频,则该视频会带有伪影。

I have also realized that the pts of that packets are not continuous, while dts are continuous. 我还意识到,这些数据包的pt是不连续的,而dts是连续的。 I know about B frames, but is this a problem in my case? 我知道B帧,但是这对我来说是个问题吗?

// Prepare the output
AVFormatContext* oc = avformat_alloc_context();
oc->oformat = av_guess_format(NULL, "video.mp4", NULL);

// Must write header, packets, and trailing
avio_open2(&oc->pb, "video.mp4", AVIO_FLAG_WRITE, NULL, NULL);

// Write header
AVStream* stream = avformat_new_stream(oc, (AVCodec*) context->streams[video_stream_index]->codec->codec);
avcodec_copy_context(stream->codec, context->streams[video_stream_index]->codec);
stream->sample_aspect_ratio = context->streams[video_stream_index]->codec->sample_aspect_ratio;
avformat_write_header(oc, NULL);

// FOR EACH FRAME...
... av_write_frame(oc, circular[k]); ...

// Write trailer and close the file
av_write_trailer(oc);
avcodec_close(stream->codec);
avio_close(oc->pb);
avformat_free_context(oc);

Thank you so much, 非常感谢,

First: when you work with the camera, it is better to work through an RTP over TCP (TCP as transport protocol). 第一:使用相机时,最好通过TCP上的RTP(TCP作为传输协议)进行操作。 To enable this feature: 要启用此功能:

AVDictionary *ifmtdict;
av_dict_set(&ifmtdict, "rtsp_transport", "tcp", 0);
...
avformat_open_input (..., &ifmtdict);

Second: After the packets start coming, wait for the first keyframe and start to write to the file from this moment. 第二:数据包开始发送之后,请等待第一个关键帧并从此刻开始写入文件。

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

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