热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

gosrs流媒体服务器_SRS流媒体服务器之RTMP协议分析(2)

0.引言阅读本文前,可以先阅读前面文章,能够帮助你更好理解本篇文章。文章列表如下:SRS流媒体框架分析(1)SRS流媒体之RTMP推流框架分析(2)SR

0.引言

阅读本文前,可以先阅读前面文章,能够帮助你更好理解本篇文章。文章列表如下:

SRS流媒体框架分析(1)

SRS流媒体之RTMP推流框架分析(2)

SRS流媒体之RTMP拉流框架分析(3)

SRS流媒体服务器之RTMP协议分析(1)

简述SRS流媒体服务器相关技术

流媒体推拉流实战之RTMP协议分析(BAT面试官推荐)

流媒体服务器架构与应用分析

手把手搭建流媒体服务器详细步骤

手把手搭建FFmpeg的Windows环境

超详细手把手搭建在ubuntu系统的FFmpeg环境

HTTP实战之Wireshark抓包分析

上篇文章主要是通过推流分析来讲解RTMP协议传输的过程,本篇文章通过拉流来讲解RTMP协议传输的过程。由于要使用WireShark抓包来分析,这时候推流就不能在win上使用ffmpeg(如果这样使用,在拉流时,会影响WireShark抓包),而是在ubuntu上使用ffmpeg推流。

讲解本篇文章前,补充下上篇文章的内容,关于推流客户端和SRS流媒体服务器的函数对应关系。

ffmpeg推流客户端 SRS流媒体服务器

gen_connect()--------发送--------------------------->SrsRtmpServer::connect_app(SrsRequest* req)

handle_invoke_result

gen_release_stream 和gen_fcpublish_stream----------发送------->SrsFMLStartPacket

handle_invoke_result

gen_create_stream-------------------发送------------------->SrsCreateStreamPacket

handle_invoke_result

1.拉流抓包分析

无论是拉流还是推流,交互协议都是固定流程,要是深入研究,需要按照spec去分析。

在ubuntu上使用ffmpeg推流命令:

ffmpeg -re -i source.200kbps.768x320.flv -vcodec copy -acodec copy -f flv -y rtmp://xxx.xxx.xxx.xxx/live/livestream

推流界面如下:

13e4536272e97b5e08c9acbf145a28c2.png

在win上使用ffmpeg去拉流,输入命令:

ffplay rtmp://xxx.xxx.xxx.xxx/live/livestream -loglevel 56

拉流界面如下:

734870a29545c53b9be856693597137d.png
89703b43fb9818c27065a4de56bdbb1c.png

WireShark抓包分析,

客户端拉流时与推流,大部分情况类似(如应答,设置窗口等),有些不一样。

aed7d5ffae93d85e9fc258d8924ccc59.png

拉流客户端给SRS流媒体服务器发送:window Acknowledgement Size 2500000|createStream()|_checkbw。拉流端ffmpeg源码如下:

其中gen_release_stream(s, rt)和gen_fcpublish_stream(s, rt)主要是在推流时用作输出使用,发送给SRS流媒体服务器,而gen_window_ack_size(s, rt)主要是在拉流时用作输入使用,拉流客户端发送给SRS流媒体服务器。

static int handle_invoke_result(URLContext *s, RTMPPacket *pkt){ RTMPContext *rt &#61; s->priv_data; char *tracked_method &#61; NULL; int ret &#61; 0; if ((ret &#61; find_tracked_method(s, pkt, 10, &tracked_method)) <0) return ret; if (!tracked_method) { /* Ignore this reply when the current method is not tracked. */ return ret; } if (!strcmp(tracked_method, "connect")) { if (!rt->is_input) { if ((ret &#61; gen_release_stream(s, rt)) <0) goto fail; if ((ret &#61; gen_fcpublish_stream(s, rt)) <0) goto fail; } else { if ((ret &#61; gen_window_ack_size(s, rt)) <0) goto fail; } if ((ret &#61; gen_create_stream(s, rt)) <0) goto fail; if (rt->is_input) { /* Send the FCSubscribe command when the name of live * stream is defined by the user or if it&#39;s a live stream. */ if (rt->subscribe) { if ((ret &#61; gen_fcsubscribe_stream(s, rt, rt->subscribe)) <0) goto fail; } else if (rt->live &#61;&#61; -1) { if ((ret &#61; gen_fcsubscribe_stream(s, rt, rt->playpath)) <0) goto fail; } } } else if (!strcmp(tracked_method, "createStream")) { double stream_id; if (read_number_result(pkt, &stream_id)) { av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()"); } else { rt->stream_id &#61; stream_id; } if (!rt->is_input) { if ((ret &#61; gen_publish(s, rt)) <0) goto fail; } else { if (rt->live !&#61; -1) { if ((ret &#61; gen_get_stream_length(s, rt)) <0) goto fail; } if ((ret &#61; gen_play(s, rt)) <0) goto fail; if ((ret &#61; gen_buffer_time(s, rt)) <0) goto fail; } } else if (!strcmp(tracked_method, "getStreamLength")) { if (read_number_result(pkt, &rt->duration)) { av_log(s, AV_LOG_WARNING, "Unexpected reply on getStreamLength()"); } }fail: av_free(tracked_method); return ret;}

注意:根据实际情况的抓包分析&#xff0c;WireShark有时候会漏掉一些包。只能当做参考使用。

确定服务器发送过来的字节&#xff0c;拉流客户端需要回应服务器ACK。源码如下:

static int handle_window_ack_size(URLContext *s, RTMPPacket *pkt){ RTMPContext *rt &#61; s->priv_data; if (pkt->size <4) { av_log(s, AV_LOG_ERROR, "Too short window acknowledgement size packet (%d)", pkt->size); return AVERROR_INVALIDDATA; } rt->receive_report_size &#61; AV_RB32(pkt->data); if (rt->receive_report_size <&#61; 0) { av_log(s, AV_LOG_ERROR, "Incorrect window acknowledgement size %d", rt->receive_report_size); return AVERROR_INVALIDDATA; } av_log(s, AV_LOG_DEBUG, "Window acknowledgement size &#61; %d", rt->receive_report_size); // Send an Acknowledgement packet after receiving half the maximum // size, to make sure the peer can keep on sending without waiting // for acknowledgements. rt->receive_report_size >>&#61; 1; return 0;}

2.重点要分析的内容

(1)metadata只发一次&#xff0c;流媒体会缓存metadata。

(2)SRS流媒体服务器会cache缓存I帧。

(3)协议转换&#xff0c;如rtmp->hls&#xff0c;rtmp->http-flv&#xff0c;这个是需要深入研究。

(4)超时退出

(5)码率统计

3.总结

本篇文章主要是对上篇文章补充及对拉流抓包分析。需要结合前面文章仔细查看。迎关注&#xff0c;转发&#xff0c;点赞&#xff0c;收藏&#xff0c;分享&#xff0c;评论区讨论。

后期关于项目的知识&#xff0c;会在微信公众号上更新&#xff0c;如果想要学习项目&#xff0c;可以关注微信公众号“记录世界 from antonio”

2470483de572c191e8cbb9d9d16ee3d5.png



推荐阅读
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • C语言常量与变量的深入理解及其影响
    本文深入讲解了C语言中常量与变量的概念及其深入实质,强调了对常量和变量的理解对于学习指针等后续内容的重要性。详细介绍了常量的分类和特点,以及变量的定义和分类。同时指出了常量和变量在程序中的作用及其对内存空间的影响,类似于const关键字的只读属性。此外,还提及了常量和变量在实际应用中可能出现的问题,如段错误和野指针。 ... [详细]
  • 手把手教你使用GraphPad Prism和Excel绘制回归分析结果的森林图
    本文介绍了使用GraphPad Prism和Excel绘制回归分析结果的森林图的方法。通过展示森林图,可以更加直观地将回归分析结果可视化。GraphPad Prism是一款专门为医学专业人士设计的绘图软件,同时也兼顾统计分析的功能,操作便捷,可以帮助科研人员轻松绘制出高质量的专业图形。文章以一篇发表在JACC杂志上的研究为例,利用其中的多因素回归分析结果来绘制森林图。通过本文的指导,读者可以学会如何使用GraphPad Prism和Excel绘制回归分析结果的森林图。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
author-avatar
mobiledu2502862217
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有