将帧从网络摄像头(RTSP)保存到mp4文件 [英] Saving frames from a network camera (RTSP) to a mp4 file

查看:1585
本文介绍了将帧从网络摄像头(RTSP)保存到mp4文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对如何将视频流保存到mp4文件感到困惑。我使用ffmpeg。让我解释一下问题:


  1. 我使用avformat_open_input(),avformat_find_stream_info()连接到网络摄像机, ,av_read_play()和我获得的帧与av_read_frame()。

  2. 每次我得到一个帧av_read_frame(),我存储相应的AVPacket在循环缓冲区。
  3. 在我的应用程序的某些点上,选择了这个循环缓冲区的范围。我发现一个用来从一个关键帧开始的关键帧。

  4. 一旦我有一个从关键帧开始的AVPacket的列表,我写头,帧和尾,如下面的代码所述。

问题是,如果我尝试使用VLC,Windows Media Player或其他视频观看它, 。



我也意识到这些包的pts是不连续的,而dts是连续的。我知道B帧,但这是我的情况下的一个问题吗?

  //准备输出
AVFormatContext * oc = avformat_alloc_context();
oc-> oformat = av_guess_format(NULL,video.mp4,NULL);

//必须写头,包和尾
avio_open2(& oc-> pb,video.mp4,AVIO_FLAG_WRITE,NULL,NULL);

//写标题
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);

//对于每个帧...
... av_write_frame(oc,circular [k]); ...

//写预告片并关闭文件
av_write_trailer(oc);
avcodec_close(stream-> codec);
avio_close(oc-> pb);
avformat_free_context(oc);非常感谢,

解决方案

首先:当你使用相机时,最好是通过TCP over TCP(TCP作为传输协议)。
要启用此功能:

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

第二个:
在数据包开始传输后,等待第一个关键帧并开始写入到这一刻的文件。


I am quite confused about how to save a video stream into a mp4 file. I am using 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().
  2. Each time I get a frame with av_read_frame(), I store the corresponding AVPacket in a circular buffer.
  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.

The problem is that the resulting mp4 video has artifacts if I try to watch it using VLC, Windows Media Player, or another one.

I have also realized that the pts of that packets are not continuous, while dts are continuous. I know about B frames, but is this a problem in my case?

// 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). 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.

这篇关于将帧从网络摄像头(RTSP)保存到mp4文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆