c++ - 将来自网络摄像机 (RTSP) 的帧保存到 mp4 文件

标签 c++ ffmpeg rtsp libav

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

  • 我使用 avformat_open_input()、avformat_find_stream_info()、av_read_play() 通过 RTSP(H.264 流)连接到网络摄像机,并使用 av_read_frame() 获取帧。
  • 每次我使用 av_read_frame() 获得一个帧时,我都会将相应的 AVPacket 存储在一个循环缓冲区中。
  • 在我的应用程序的某些点中,选择了此循环缓冲区的范围。我找到了一个用来开始的关键帧。
  • 一旦我有一个从关键帧开始的 AVPacket 列表,我就会编写标题、帧和尾部,如下面的代码中所述。

  • 问题是,如果我尝试使用 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);
    

    太感谢了,

    最佳答案

    第一:当您使用相机时,最好通过 RTP over TCP(TCP 作为传输协议(protocol))工作。
    要启用此功能:

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

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

    关于c++ - 将来自网络摄像机 (RTSP) 的帧保存到 mp4 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20522950/

    相关文章:

    c++ - 如何否定 boost::lambda:bind?

    c++ - 在C++中从文件中查找平均工资

    c++ - 比较变量类型

    ffmpeg - 通过添加自动暂停来同步音频和视频的关键时间

    android - 使用 ffmpeg-android 连接视频文件

    ffmpeg - 将 rtsp 流转换为 bmp 图像

    c++ - 在条件中使用 boost::tribool 时是编译器错误还是我的错误?

    ffmpeg - 找不到流 0 的编解码器参数

    qt - 在 Windows 上的 QML 中播放 RTSP 视频

    ffmpeg - 将 RTP 数据转换为 RTSP