上节分享了打印AVPacket中的时间戳信息,这节准备分享一下利用rtmp协议将视频和音频数据推流到nginx服务器上并利用vlc来进行拉流播放视频,达到直播的效果。

由于AVPacket包数据中的解码时间戳dts、显示时间戳pts是使用输入流来进行配置的,上节分享的是利用av_read_frame()函数读取数据,由于第一个参数是输入流的帧,所以配置的dts和pts就是输入流的配置,要想用输出流的pts、dts配置,可以利用ffmpeg中的int64_t av_rescale_q_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd); 函数来进行转化,该函数的原理是:

可以假设原来的dts为x,利用c来作为度量的值为y,这样就可以列出两个方程式

x/b=a ,x/c=y ,所以a*b=c*y,及最后的y=a*b/c;转化的代码如下,

     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_PASS_MINMAX));pkt.dts = av_rescale_q_rnd(pkt.dts, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));pkt.duration = av_rescale_q_rnd(pkt.duration, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));pkt.pos = -1;

最后再利用ffmpeg的av_usleep()函数来进行延时即可实现推流。

但是利用固定延时这种方式来进行推流的话,播放出来的画面会有卡顿的现象,可以通过改变视频解码的时间和发送的时间一致来解决,这里题主修改了多次av_usleep()函数的参数,发现只要解码时间和发送时间不同步就会导致视频卡顿,具体代码如下。

     //视频帧推送速度if (ictx->streams[pkt.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){//时间基数AVRational tb = ictx->streams[pkt.stream_index]->time_base;//已经过去的时间long long now = av_gettime() - startTime;long long dts = 0;dts = pkt.dts * (1000 * 1000 * r2d(tb));cout << dts << " " << now  <<flush<<endl;if(dts>now)av_usleep(dts-now);}

最后利用vlc播放器就可以实现直播推流了。设置方式如下

最后的效果

通过读取本地的视频推流实现直播。下面是源码分享。

extern "C"
{
#include "libavformat/avformat.h"
#include "libavutil/time.h"
}#include <iostream>
using namespace std;
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"avcodec.lib")
int XError(int errNum)
{char buf[1024] = { 0 };av_strerror(errNum, buf, sizeof(buf));std::cout << buf << endl;getchar();return -1;
}
static double r2d(AVRational r)
{return r.num == 0 || r.den == 0 ? 0. : (double)r.num / (double)r.den;
}
int main(int argc, char *argv[])
{char *inUrl = "test.flv";char *outUrl = "rtmp://192.168.198.128/live";//初始化所有封装和解封装   flv mp4 mov mp3av_register_all();//初始化网络库avformat_network_init();//1 打开文件,解封装//输入封装上下文AVFormatContext *ictx = NULL;//打开文件,解封文件头int re=avformat_open_input(&ictx,inUrl,NULL,NULL);if (re != 0){return XError(re);}std::cout << "open file" << inUrl << "Success" << endl;//获取音视频流信息,h264 flvre=avformat_find_stream_info(ictx,0);if (re != 0){return XError(re);}av_dump_format(ictx,0,inUrl,0);///输出流//创建输出流上下文AVFormatContext *octx = NULL;re=avformat_alloc_output_context2(&octx,0,"flv",outUrl);if (!octx){return XError(re);}std::cout << "octx create success!" << endl;//配置输出流//遍历输入的AVStreamfor (int i = 0;i < ictx->nb_streams;i++){//创建输出流AVStream *out= avformat_new_stream(octx,ictx->streams[i]->codec->codec);if (!out){return XError(0);}//复制配置信息,用于MP4//re=avcodec_copy_context(out->codec, ictx->streams[i]->codec);re = avcodec_parameters_copy(out->codecpar, ictx->streams[i]->codecpar);out->codec->codec_tag = 0;}av_dump_format(octx, 0, outUrl, 1);////rtmp推流//打开iore=avio_open(&octx->pb,outUrl,AVIO_FLAG_WRITE);if (!octx->pb){return XError(re);}//写入头信息re=avformat_write_header(octx,0);if (re < 0){return XError(re);}cout << "avformat_writr_header" << re << endl;//推流每一帧数据AVPacket pkt;long long startTime = av_gettime();for (;;){re=av_read_frame(ictx,&pkt);if (re != 0){break;}//cout << pkt.pts <<" "<<flush;//计算转化pts dtsAVRational 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_PASS_MINMAX));pkt.dts = av_rescale_q_rnd(pkt.dts, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));pkt.duration = av_rescale_q_rnd(pkt.duration, itime, otime, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));pkt.pos = -1;//视频帧推送速度if (ictx->streams[pkt.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){//时间基数AVRational tb = ictx->streams[pkt.stream_index]->time_base;//已经过去的时间long long now = av_gettime() - startTime;long long dts = 0;dts = pkt.dts * (1000 * 1000 * r2d(tb));cout << dts << " " << now  <<flush<<endl;if(dts>now)av_usleep(dts-now);}re=av_interleaved_write_frame(octx,&pkt);//av_usleep(10*1000);if (re < 0){return XError(re);}//清除空间//av_packet_unref(&pkt);}std::cout << "file to rtmp test" << endl;getchar();return 0;
}

音视频开发系列(4):完成rtmp推流vlc拉流相关推荐

  1. 【音视频开发系列】盘点音视频直播RTSP/RTMP推流一定会遇到的各种坑,教你快速解决

    聊聊RTSP/RTMP推流那些坑 1.推流架构分析 2.推流缓存队列的设计 3.FFmpeg函数阻塞问题分析 [音视频开发系列]盘点音视频直播一定会遇到的各种坑,教你快速解决 更多精彩内容包括:C/C ...

  2. 【音视频开发系列】一学就会,快速掌握音视频开发的第一个开源项目FFmpeg

    快速掌握音视频开发的第一个开源项目:FFmpeg 1.为什么要学FFmpeg 2.FFmpeg面向对象思想分析 3.FFmpeg各种组件剖析 视频讲解如下,点击观看: [音视频开发系列]一学就会,快速 ...

  3. 【音视频开发系列】srs-webrtc-janus开源流媒体服务器分析

    全球最牛开源流媒体服务器源码分析 1.如何学习流媒体服务器 2.全球最牛流媒体服务器架构分析 3.我们能从全球最牛流媒体服务器得到什么 [音视频开发系列]srs-webrtc-janus流媒体服务器分 ...

  4. SRS流媒体服务器——RTMP推流、拉流创建连接

    SRS流媒体服务器--RTMP推流.拉流创建连接 目录 识别客户端,然后获取或者创建SrsLiveSource 启动推流 启动拉流 SRS安装部署相关内容: SRS流媒体服务器--单机环境搭建和源码目 ...

  5. 音视频开发系列(16)技术解码 | SRT和RIST协议综述

    概要 近些年来,互联网行业出现了几波和音视频相关的热潮:VR.短视频.直播等.除了VR因技术成熟度问题,还在蓄势待发,短视频和直播持续热度不减,以各种方式进入新的行业应用领域.视频直播方向,RTMP仍 ...

  6. 音视频开发系列-H264编码原理

    H264简介 来自百度百科的介绍: H.264是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式. H.264是ITU-T以H.26x系列为名称命名的 ...

  7. 音视频开发系列--H264编解码总结

    一.概述 H264,通常也被称之为H264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC) 对摄像头采集的每一帧视频需要进行编码,由于视频中存在空间和时间的冗余,需要 ...

  8. 音视频开发系列(15):视频与音频同步

    上次分享了将视频与音频同时推流到服务上的代码封装,然后上节分享在测试后会发现音视频不同步,这边说一下原因: 从帧率及采样率,即可知道视频/音频播放速度.声卡和显卡均是以一帧数据来作为播放单位,如果单纯 ...

  9. 音视频开发系列(34) OpenGL ES 绘制平面图形

    我们前两篇介绍了OpenGL ES 基本概念和GLSL及Shader的渲染流程,这篇我们开始实战,通过GLSurfaceView加载着色器,来绘制三角形.正方形和直线这些平面图形.在实践过程中遇到的问 ...

最新文章

  1. HDU1811 Rank of Tetris 拓扑排序+并查集 OR 差分约束最短路+并查集
  2. python学习:函数传参数
  3. centos 6.0 启动失败提示。
  4. JSP GridView --使用自定义标签实现ASP.NET的控件
  5. Dynamics2011中Attachment的区别
  6. 应用程序通用开发框架
  7. ASP.NET使用AJAX应注意IIS有没有.ashx扩展
  8. 坦克大战 Java版
  9. 负数的开方到底等于多少?
  10. 『转』图解硬件特性!
  11. 计算机图形学 opengl版本 第三版------胡事民 第四章 图形学中的向量工具
  12. CartoonGAN照片动漫化
  13. 【开源】在线教育系统.net源码-PC端-手机端
  14. 国际国内cms系统开源网址大综合
  15. 三思而行 --jsp基础篇
  16. 4.3.2 Calculating and Applying VaR
  17. Axure RP 10 10.0.0.3818 中文版 专业的快速原型设计工具
  18. MySQL必知必会!!!看这一篇就足够了!!!
  19. 前端实现高效的海报系统
  20. win10系统使用蓝牙鼠标时自动断开连接?

热门文章

  1. 【2022年电赛】有人开摆,有人跑路,有人5秒不识数
  2. 【无标题】2022年压力管道巡检维护试题及在线模拟考试
  3. 激光slam 第六次作业
  4. 让数据库应用开发不再裸奔——Test-Driven Database Development译者序
  5. Nacos注册中心集群搭建和AP/CP模式切换
  6. python七夕快乐_七夕送小姐姐!女生勿扰,只适合男孩子的python爬虫!
  7. 乔戈里直呼:这就是计算机科班出身!
  8. dsn mssql php,mssql_fetch_assoc
  9. 智慧特色小镇,如何科学规划建设?
  10. 喜报频传,钛灵信息科技成为安徽省科学家企业家协会会员单位!