37.FFmpeg+OpenCV直播推流(FFmpeg api实现推流)

简介:

今天我们来ffmpeg api编程实现推流并测试效果
项目源码

开发环境

Visual Studio 2015 + FFmpeg-3.2 + nginx服务器

开发过程
1.环境准备

首先在FFmpeg官网下载ffmpeg dev 和share sdk
ffmpeg下载类型.png
下载解压之后,打开文件夹目录,拷贝dev中的include和lib目录,shared中的bin目录,然后创建一个项目目录,将这三个目录拷贝进去,方便我们编写代码时配置相对路径。其中bin存放的都是dll动态库文件,include存放的是头文件,lib存放的是每一个dll对应的lib文件
QQ图片20181125115923.png
然后创建src目录用于我们的项目根目录,我们将会使用Visual Studio在这个目录下创建控制台项目来编写推流代码。

项目创建完成之后,需要对AS做一些配置:

a.右键项目名打开属性,在配置属性的常规选项中的输出目录配置一个目录用于存放我们编译后的文件,这里直接设置为上边创建的bin目录
QQ图片20181125120741.png

b.然后同样在配置属性下找到调试,设置工作目录为bin
QQ图片20181125120901.png
然后在编译时就会去这里找动态库文件

c.下一步在C/C++选项中找到常规,设置头文件目录
QQ图片20181125121143.png

d.在链接器下配置lib目录位置
QQ图片20181125121255.png

这样一来,VS的工作环境就搭建好了

2.代码编写

接下来正式开始写代码,我们这次的推流以本地文件为源进行推,推流的过程大概是这么几步

1.ffmpeg初始化

av_register_all注册所有封装器和解封装器以及协议,这个方法在前边文章已经提到过

avformat_network_init初始化网络相关的东西,推流必须用到这个

av_register_all();
avformat_network_init();
2.读取源文件

avformat_open_input打开一个流读取流的文件头信息,如果没有文件头则无法读取到正确的信息

avformat_find_stream_info 针对一些不包含头信息的源(MPEG)很有效,调用防止无法读取到文件的正确信息

avformat_open_input(&ictx, input, 0, &opts);
avformat_find_stream_info(ictx, 0);
3.推流的准备工作

源文件信息我们已经读取到了,接下来开始准备推流,推流之前我们需要构造出几个对象:
AVFormatContext:输出格式上下文
AVStream:输出流,有几条stream就构造几个

avcodec_parameters_copy的作用是将输入流也就是源文件的parameter信息拷贝到输出流的参数中

avformat_alloc_output_context2(&octx, 0, "flv", output)
avformat_new_stream(octx, ictx->streams[i]->codec->codec)
avcodec_parameters_copy(out->codecpar, ictx->streams[i]->codecpar)
4.开始推流

avio_open会初始化出一个AVIOContext对象,我们可以把他看作一个普通的io流对象,只不过区别在于它是向流媒体服务器写入数据的

avformat_write_header是初始化推流的头信息

av_read_frame是在一个循环中进行的,不断的读取源得到AVPacket,然后由av_interleaved_write_frame负责开始推

avio_open(&octx->pb, output, AVIO_FLAG_WRITE);
avformat_write_header(octx, 0);
av_read_frame(ictx, &pkt)
av_interleaved_write_frame(octx, &pkt);

推流的过程很简单,不过其中涉及到一点比较重要的东西就是推流中的速度控制,我们可以设置一个时间基准,通过对比packet的pts和时间基准的大小来决定推送的速度,从而实现正常效果的推送,关键代码如下

//推流每一帧数据
    AVPacket pkt;
    long long startTime = av_gettime();
    for (;;) {
        result = av_read_frame(ictx, &pkt);
        if (result != 0) {
            break;
        }
        //计算转换时间戳pts dts
        AVRational itime = ictx->streams[pkt.stream_index]->time_base;
        AVRational otime = octx->streams[pkt.stream_index]->time_base;
        pkt.pts = av_rescale_q_rnd(pkt.pts, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_NEAR_INF));
        pkt.dts = av_rescale_q_rnd(pkt.pts, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_NEAR_INF));
        pkt.duration = av_rescale_q_rnd(pkt.duration, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_NEAR_INF));
        pkt.pos = -1;
        
        //视频帧推送速度
        if (ictx->streams[pkt.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            //获取视频的时间戳
            AVRational rational = ictx->streams[pkt.stream_index]->time_base;
            //从开始解码到现在过去的时间,可以作为推流进行的时间,用当前帧的pts做对比,进行同步
            long long now = av_gettime() - startTime;
            long long dts = 0;
            //单位微秒
            dts = pkt.dts*r2d(rational)*1000*1000;

            //说明推送太快,等一等
            if (dts > now) {
                av_usleep(dts - now);
                cout << "等待"<< dts - now<< endl;
            }
            else {
                cout << "无需等待" << dts - now << endl;
            }
        }

        result = av_interleaved_write_frame(octx, &pkt);
    
        if (result < 0) {
            return XError(result);
        }

        //av_packet_unref(&pkt);
    }
总结

本篇文章简单讲述了ffmpeg实现推流的过程,推流服务器使用的是nginx,所以在开始推之前要确保nginx服务器已经开始,并且正确配置服务器的ip地址,推流之后我们可以通过vlc播放器测试推流效果。本文代码比较简要,具体可查看源码项目源码

相关文章
|
1月前
|
并行计算 PyTorch TensorFlow
Ubuntu安装笔记(一):安装显卡驱动、cuda/cudnn、Anaconda、Pytorch、Tensorflow、Opencv、Visdom、FFMPEG、卸载一些不必要的预装软件
这篇文章是关于如何在Ubuntu操作系统上安装显卡驱动、CUDA、CUDNN、Anaconda、PyTorch、TensorFlow、OpenCV、FFMPEG以及卸载不必要的预装软件的详细指南。
3271 3
|
1月前
|
应用服务中间件 Linux nginx
FFmpeg学习笔记(一):实现rtsp推流rtmp以及ffplay完成拉流操作
这篇博客介绍了如何使用FFmpeg实现RTSP推流到RTMP服务器,并使用ffplay进行拉流操作,包括在Windows和Linux系统下的命令示例,以及如何通过HTML页面显示视频流。
392 0
|
1月前
|
缓存 并行计算 Ubuntu
Jetson 学习笔记(十一):jetson agx xavier 源码编译ffmpeg(3.4.1)和opencv(3.4.0)
本文是关于在Jetson AGX Xavier上编译FFmpeg(3.4.1)和OpenCV(3.4.0)的详细教程,包括编译需求、步骤、测试和可能遇到的问题及其解决方案。还提供了Jetson AGX Xavier编译CUDA版本的OpenCV 4.5.0的相关信息。
61 4
Jetson 学习笔记(十一):jetson agx xavier 源码编译ffmpeg(3.4.1)和opencv(3.4.0)
|
1月前
|
Ubuntu 应用服务中间件 nginx
Ubuntu安装笔记(三):ffmpeg(3.2.16)源码编译opencv(3.4.0)
本文是关于Ubuntu系统中使用ffmpeg 3.2.16源码编译OpenCV 3.4.0的安装笔记,包括安装ffmpeg、编译OpenCV、卸载OpenCV以及常见报错处理。
140 2
Ubuntu安装笔记(三):ffmpeg(3.2.16)源码编译opencv(3.4.0)
|
1月前
|
缓存 监控 计算机视觉
视频监控笔记(三):opencv结合ffmpeg获取rtsp摄像头相关信息
本文介绍了如何使用OpenCV结合FFmpeg获取RTSP摄像头信息,包括网络架构、视频监控系统组成、以及如何读取和显示网络摄像头视频流。
41 1
|
1月前
|
网络协议 应用服务中间件 nginx
FFmpeg错误笔记(一):nginx-rtmp-module推流出现 Server error: Already publishing
这篇文章讨论了在使用nginx-rtmp-module进行RTMP推流时遇到的“Server error: Already publishing”错误,分析了错误原因,并提供了详细的解决办法,包括修改nginx配置文件和终止异常的TCP连接。
124 0
FFmpeg错误笔记(一):nginx-rtmp-module推流出现 Server error: Already publishing
|
1月前
FFmpeg学习笔记(二):多线程rtsp推流和ffplay拉流操作,并储存为多路avi格式的视频
这篇博客主要介绍了如何使用FFmpeg进行多线程RTSP推流和ffplay拉流操作,以及如何将视频流保存为多路AVI格式的视频文件。
167 0
|
3月前
|
编解码 Java Android开发
FFmpeg开发笔记(四十五)使用SRT Streamer开启APP直播推流
​SRT Streamer是一个安卓手机端的开源SRT协议直播推流框架,可用于RTMP直播和SRT直播。SRT Streamer支持的视频编码包括H264、H265等等,支持的音频编码包括AAC、OPUS等等,可谓功能强大的APP直播框架。另一款APP直播框架RTMP Streamer支持RTMP直播和RTSP直播,不支持SRT协议的直播。而本文讲述的SRT Streamer支持RTMP直播和SRT直播,不支持RTSP协议的直播。有关RTMP Streamer的说明参见之前的文章《使用RTMP Streamer开启APP直播推流》,下面介绍如何使用SRT Streamer开启手机直播。
73 4
FFmpeg开发笔记(四十五)使用SRT Streamer开启APP直播推流
|
4月前
|
视频直播 Windows
FFmpeg开发笔记(四十一)结合OBS与MediaMTX实现SRT直播推流
《FFmpeg开发实战》书中介绍了直播中的RTSP、RTMP和SRT协议,SRT提供更低延迟和稳定性。FFmpeg从4.0版起支持SRT,OBS Studio和MediaMTX等工具也已支持。在Windows环境下,通过集成libsrt的FFmpeg,可以建立SRT直播系统。MediaMTX日志显示SRT服务监听8890端口,OBS Studio设置SRT推流至"publish:live"。ffplay和VLC通过"read:live"拉流成功,验证了SRT推拉流功能。更多详情见《FFmpeg开发实战:从零基础到短视频上线》。
165 2
FFmpeg开发笔记(四十一)结合OBS与MediaMTX实现SRT直播推流
|
4月前
|
Web App开发 缓存 编解码
FFmpeg开发笔记(三十八)APP如何访问SRS推流的RTMP直播地址
《FFmpeg开发实战》书中介绍了轻量级流媒体服务器MediaMTX,适合测试RTSP/RTMP协议,但不适用于复杂直播场景。SRS是一款强大的开源流媒体服务器,支持多种协议,起初为RTMP,现扩展至HLS、SRT等。在FFmpeg 6.1之前,推送给SRS的HEVC流不受支持。要播放RTMP流,Android应用可使用ExoPlayer,需在`build.gradle`导入ExoPlayer及RTMP扩展,并根据URL类型创建MediaSource。若SRS播放黑屏,需在配置文件中开启`gop_cache`以缓存关键帧。
146 2
FFmpeg开发笔记(三十八)APP如何访问SRS推流的RTMP直播地址