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

时间:2013-12-11 15:21:33

标签: c++ ffmpeg rtsp libav

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

  1. 我通过RTSP(H.264流)使用avformat_open_input(),avformat_find_stream_info(),av_read_play()连接到网络摄像机,并且我获得了带有av_read_frame()的帧。
  2. 每次使用av_read_frame()获取帧时,我都会将相应的AVPacket存储在循环缓冲区中。
  3. 在我的应用程序的某些点上,选择了一个范围的循环缓冲区。我找到了一个用来开始的关键帧。
  4. 一旦我从一个关键帧开始有一个AVPacket列表,我就会编写标题,帧和尾部,正如我在下面的代码中所描述的那样。
  5. 问题是,如果我尝试使用VLC,Windows Media Player或其他视频来观看,那么产生的mp4视频会出现伪影。

    我也意识到该数据包的pts不是连续的,而dts是连续的。我知道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);
    

    非常感谢你,

1 个答案:

答案 0 :(得分:-1)

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

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

第二: 数据包开始后,等待第一个关键帧并从此刻开始写入文件。