ffmpeg获取网络摄像头视频流

一、ffmpeg 简介

 FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。

源码链接:http://ffmpeg.org/download.html#get-sources

编译参数介绍:https://www.jianshu.com/p/137be4377cef

二、简单应用

  1. 申请内存空间存储媒体流的格式信息,后面很多操作都需要使用到它:AVFormatContext* format_ctx = avformat_alloc_context();  
  2. 加载socket库以及网络加密协议相关的库,为后续使用网络相关提供支持:avformat_network_init(); 
  3. 设置设置获取网络摄像头视频流参数:

        AVDictionary* options = NULL;

        av_dict_set(&options, “buffer_size”, “425984”, 0); //设置缓存大小,1080p可将值调大

        av_dict_set(&options, “rtsp_transport”, “udp”, 0); //以udp方式打开,如果以tcp方式打开将udp替换为tcp

        av_dict_set(&options, “stimeout”, “2000000”, 0); //设置超时断开连接时间,单位微秒

        av_dict_set(&options, “max_delay”, “5000”, 0); //设置最大时延

        /* –preset的参数主要调节编码速度和质量的平衡, 有ultrafast、superfast、veryfast、

        faster、fast、medium、slow、slower、veryslow、placebo这10个选项,从快到慢。*/

        av_dict_set(&options, “preset”, “ultrafast”, 0);

        /* –tune的参数主要配合视频类型和视觉优化的参数,或特别的情况。

        如果视频的内容符合其中一个可用的调整值又或者有其中需要,则可以使用此选项,否则建议不使用.

        zerolatency:零延迟,用在需要非常低的延迟的情况下,比如电视电话会议的编码。*/

        av_dict_set(&options, “tune”, “zerolatency”, 0);

    还有许多参数可以设置,具体我们可以查看 ffmpeg 源码,比如 avformat_open_input 是结构体 AVFormatContext 提供的 API,在 libavformat/options_table.h 中定义了 AVFormatContext 所有支持的 options 选项

  4. 读取文件头,获取封装格式相关信息:avformat_open_input(&format_ctx, “rtsp://admin:gti123456@192.168.1.58:554/onvif1″; 不同厂家不同的设备会有相应的url;
  5. 解码一段数据,获取流相关信息:avformat_find_stream_info(format_ctx, NULL);

  6. 从获取到的视频流信息里面找到图像流和音频流的对应下标:

        for (int i = 0; i < format_ctx->nb_streams; i++) {

            if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)

                video_stream_index = i;

            else if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)

                audio_stream_index = i;

        }

  7. 找到视频H264:

        AVCodecParameters *pCodecpar = format_ctx->streams[video_stream_index]->codecpar;

        AVCodec *pCodec = avcodec_find_decoder(pCodecpar->codec_id); 

  8. 独立的解码上下文(最新的ffmpeg去掉了codec,统一使用codecpar。我们可以使用avcodec_parameters_to_context进行替换):

    AVCodecContext *vc =vcodec_alloc_context3(pCodec);

    avcodec_parameters_to_context(vc, format_ctx->streams[video_stream_index]->codecpar);

  9. 初始化一个视音频编解码器的AVCodecContext:avcodec_open2(vc, pCodec, NULL);

  10.  申请每一帧视频流的空间:pFrameDec = av_frame_alloc();

  11. 从视频流里面读取当前的一个数据包:av_init_packet(&packet); av_read_frame(format_ctx, &packet);

  12. 视频解码:avcodec_decode_video2(vc, pFrameDec, &frameFinished, &packet);

 

 

    原文作者:JR-su
    原文地址: https://blog.csdn.net/weixin_39273426/article/details/104535753
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞