流媒体传输 - HLS 协议

news/2024/4/25 9:10:41/文章来源:https://blog.csdn.net/irainsa/article/details/128097704

HLS 全称是 HTTP Live Streaming,是一个由 Apple 公司提出的基于 HTTP 的媒体流传输协议,用于实时音视频流的传输。目前 HLS 协议被广泛的应用于视频点播和直播领域。

概述

原理介绍

通过将整条流切割成一个小的可以通过 HTTP 下载的媒体文件,然后提供一个配套的媒体列表文件,提供给客户端,让客户端顺序地拉取这些媒体文件播放,来实现看上去是在播放一条流的效果。由于传输层协议只需要标准的 HTTP 协议,HLS 可以方便的透过防火墙或者代理服务器,而且可以很方便的利用 CDN 进行分发加速,并且客户端实现起来也很方便.

整体架构

HLS 的架构分为三部分:Server,CDN,Client 。即服务器、分发组件和客户端。

下面是 HLS 整体架构图:

                                                              HLS 整体架构图

服务器用于接收媒体输入流,对它们进行编码,封装成适合于分发的格式,然后准备进行分发。

分发组件为标准的 Web 服务器。它们用于接收客户端请求,传递处理过的媒体,把资源和客户端联系起来。

客户端软件决定请求何种合适的媒体,下载这些资源,然后把它们重新组装成用户可以观看的连续流。

HLS 协议分析

HLS Playlist

其实,HLS 协议的主要内容是关于 M3U8 这个文本协议的,其实生成与解析都非常简单。为了更加直接地说明这一点,我下面举两个简单的例子:

【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~

  

简单的 Media Playlist

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:2680
#EXTINF:7.975,
https://priv.example.com/fileSequence2680.ts
#EXTINF:7.941,
https://priv.example.com/fileSequence2681.ts
#EXTINF:7.975,
https://priv.example.com/fileSequence2682.ts

包含多种比特率的 Master Playlist

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1280000
http://example.com/low.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000
http://example.com/mid.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000
http://example.com/hi.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS="mp4a.40.5"
http://example.com/audio-only.m3u8
  • HLS 通过 URI(RFC3986) 指向的一个 Playlist 来表示一个媒体流

  • 一个 Playlist 可以是一个 Media Playlist 或者 Master Playlist, 使用 UTF-8 编码的文本文件,包含一些 URI 跟描述性的 tags

  • 一个 Media Playlist 包含一个 Media Segments 列表,当顺序播放时,能播放整个完整的流

  • 要想播放这个 Playlist, 客户端需要首先下载他,然后播放里面的每一个 Media Segment

  • 更加复杂的情况是,Playlist 是一个 Master Playlist, 包含一个 Variant Stream 集合,通常每个 Variant Stream 里面是同一个流的多个不同版本 (如:分辨率,码率不同)

  • 一个 Playlist 文件必须通过 URI(.m3u8 或 m3u) 或者 HTTP Content-Type 来识别 (application/vnd.apple.mpegurlaudio/mpegurl)

  • 换行符可以用 \n 或者 \r\n

  • # 开头的是 tag 或者注释,以 #EXT 开头的是 tag, 其余的为注释,在解析时应该忽略

  • Playlist 里面的 URI 可以用绝对地址或者相对地址,如果使用相对地址,那么是相对于 Playlist 文件的地址

HLS Media Segments

  • 每一个 Media Segment 通过一个 URI 指定,可能包含一个 byte range

  • 每一个 Media Segmentduration 通过 EXTINF tag 指定

  • 每一个 Media Segment 有一个唯一的整数 Media Segment Number

  • 有些媒体格式需要一个 format-specific sequence 来初始化一个 parser, 在 Media Segmentparse 之前。这个字段叫做 Media Initialization Section, 通过 EXT-X-MAP tag 来指定。支持的 Media Segment 格式

HLS TAGS

  • Basic Tags: 用在Media Playlist和Master Playlist里面
    • EXTM3U: 必须在文件的第一行,标识是一个 Extended M3U Playlist 文件

    • EXT-X-VERSION: 表示 Playlist 兼容的版本

  • Media Segment Tags: 只能出现在Media Playlist里面
    • EXTINF: 用于指定 Media Segmentduration

    • EXT-X-BYTERANGE: 用于指定 URIsub-range

    • EXT-X-DISCONTINUITY: 表示不连续

    • EXT-X-KEY: 表示 Media Segment 已加密,该值用于解密

    • EXT-X-MAP: 用于指定 Media Initialization Section

    • EXT-X-PROGRAM-DATE-TIME: 和 Media Segment 的第一个 sample 一起来确定时间戳

    • EXT-X-DATERANGE: 将一个时间范围和一组属性键值对结合到一起

  • Media Playlist tags: 只能出现在Media Playlist里面
    • EXT-X-TARGETDURATION: 用于指定最大的 Media Segment duration

    • EXT-X-MEDIA-SEQUENCE: 用于指定第一个 Media SegmentMedia Sequence Number

    • EXT-X-DISCONTINUITY-SEQUENCE: 用于不同 Variant Stream 之间同步

    • EXT-X-ENDLIST: 表示结束

    • EXT-X-PLAYLIST-TYPE: 可选,指定整个 Playlist 的类型

    • EXT-X-I-FRAMES-ONLY: 表示每个 Media Segment 描述一个单一的 I-frame

  • Master Playlist tags: 只能出现在Master Playlist中
    • EXT-X-MEDIA: 用于关联同一个内容的多个 Media Playlist 的多种 renditions

    • EXT-X-STREAM-INF: 用于指定一个 Variant Stream

    • EXT-X-I-FRAME-STREAM-INF: 用于指定一个 Media Playlist 包含媒体的 I-frames

    • EXT-X-SESSION-DATA: 存放一些 session 数据

    • EXT-X-SESSION-KEY: 用于解密

  • Media or Master Playlist Tags: 可以出现在Media Playlist或者Master Playlist中,但是如果同时出现在同一个Master Playlist和Media Playlist中时,必须为相同值
    • EXT-X-INDEPENDENT-SEGMENTS: 表示每个 Media Segment 可以独立解码

    • EXT-X-START: 标识一个优选的点来播放这个 Playlist

HLS 播放

播放未加密 HLS

我们通过 VLC 播放器播放苹果官方提供的一个例子:http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8,并使用 Wirshark 对其中交互进行抓包。

GET /iphone/samples/bipbop/gear1/prog_index.m3u8 HTTP/1.1
Host: devimages.apple.com
Accept: */*
Accept-Language: zh_CN
User-Agent: VLC/3.0.8 LibVLC/3.0.8
Range: bytes=0-
​HTTP/1.1 206 Partial ContentAccept-Ranges: bytesContent-Type: audio/x-mpegurlETag: "50117c8233644c19b5ab49551b72507f:1239907352"Last-Modified: Thu, 16 Apr 2009 18:42:32 GMTServer: AkamaiNetStorageDate: Sun, 22 Nov 2020 15:01:49 GMTContent-Range: bytes 0-7018/7019Content-Length: 7019X-Cache: TCP_MEM_HIT from a184-26-91-45.deploy.akamaitechnologies.com (AkamaiGHost/10.2.0.2-31441410) (-)Connection: keep-alive
​#EXTM3U#EXT-X-TARGETDURATION:10#EXT-X-MEDIA-SEQUENCE:0#EXTINF:10, no descfileSequence0.ts#EXTINF:10, no descfileSequence1.ts#EXTINF:10, no descfileSequence2.ts#EXTINF:10, no desc......#EXTINF:1, no descfileSequence180.ts#EXT-X-ENDLIST

我们可以看到返回的 M3U8 里面他有一个一个 ts 视频片段,这个一个一个视频片段就是我们需要的播放的视频片段。

#EXTINF` 表示每个 `ts` 切片视频文件的时长。 `#EXT-X-TARGETDURATION` 指定当前视频流中的切片文件的最大时长,也就是说这些 `ts` 切片的时长不能大于 `#EXT-X-TARGETDURATION` 的值。 `#EXT-X-MEDIA-SEQUENCE` 第一个 `ts` 分片的序列号 `#EXT-X-ENDLIST` 这个表示视频结束,有这个标志同时也说明当前的流是一个非直播流。 `#EXT-X-PLAYLIST-TYPE:VOD` 的意思是当前的视频流并不是一个直播流,而是点播流,换句话说就是该视频的全部的 `ts` 文件已经被生成好了 `#EXT-X-ALLOW-CACHE` 是否允许 `cache

播放加密 HLS

HLS 协议总结

优点

  • 客户端支持简单,只需要支持 HTTP 请求即可,HTTP 协议无状态,只需要按顺序下载媒体片段即可。

  • 使用 HTTP 协议网络兼容性好,HTTP 数据包也可以方便地通过防火墙或者代理服务器,CDN 支持良好。

  • Apple 的全系列产品支持,不需要安装任何插件就可以原生支持播放 HLS, 目前 Android 也加入了对 HLS 的支持。

  • 自带多码率自适应机制。

缺点

  • 相比 RTMP 这类长连接协议,延时较高,难以用到互动直播场景。

  • 对于点播服务来说,由于 TS 切片通常较小,海量碎片在文件分发,一致性缓存,存储等方面都有较大挑战。

改进

  • 由于客户端每次请求 TSM3U8 有可能一个新的连接请求,无法有效的标识客户端,一旦出现问题,基本无法有效的定位问题。

  • 一般工业级的服务器都会对传统的 HLS 做一些改进,常见优化是对每个 M3U8 文件增加 Session 来标识一条 HLS 连接。

  • 不管通过哪种方式,最终我们都能通过一个唯一的 id 来标识一条流,这样在排查问题时就可以根据这个 id 来定位播放过程中的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_38860.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spirng 痛苦源码学习(二)——手写spring大致总框架(一)

文章目录前言一、总体步骤如下1、spring 文件夹2、myProject 文件夹二、主要coding1、配置文件2、容器3、一些spring中的重要的注解4、项目中的使用5.重要的bean定义信息6、postProcessor重要,前置通知和后置主要项目的截图前言 本文主要基于spring的注解的方式完成…

Python的10个编程技巧,你不一定都知道

文末有Python资料下载 1. 原地交换两个数字 Python 提供了一个直观的在一行代码中赋值与交换(变量值)的方法,请参见下面的示例: 赋值的右侧形成了一个新的元组,左侧立即解析(unpack)那个&…

leetcode-每日一题-1758-生成交替二进制字符串的最少操作数(简单,数学思想)

这道题标记为简单题是正常的,因为当你想到0或者1开头的时候就已经结束了看看我的分析 那么知道这个信息之后就很简单了,加上我们的位运算符号^作为标记即可,大家看看代码实现 1758. 生成交替二进制字符串的最少操作数 难度简单88收藏分享切换…

Mysql基础知识篇(二)

1.UNION 与 UNION ALL 的区别? 如果使用 UNION,会在表链接后筛选掉重复的记录行如果使用 UNION ALL,不会合并重复的记录行从效率上说,UNION ALL 要比 UNION 快很多,如果合并没有刻意要删除重复行,那么就使…

Java基于springboot+vue的摄影作品展示交流系统 计算机毕业设计

随着时代的发展,人们的精神世界也在不断的丰富,尤其是在当下电子设备发展迅速的背景下,人们通过数码相机或者手机随后就可以拍下每一个美丽的瞬间,但是人们更希望将这些摄影作品传到网上和更多的人进行分享,同时也希望…

电脑键盘功能基础知识,快速入门,抓住这份详细教程

在互联网生活发达的今天,电脑已经成为了学习工作的必备工具。而用来操作电脑的关键,就是我们经常使用的键盘和鼠标。最近有不少的小伙伴来私信小编,希望小编做一个电脑键盘功能基础知识介绍的详细教程。这不,小编应大家要求&#…

用匠心创造可期未来!与广州流辰信息科技一起携手创佳绩!

当今社会世界经济一体化趋势逐渐明朗化,竞争也愈发激烈,同时,这也是一个机遇与挑战并存的开放社会。在机遇面前,作为企业,要紧紧抓住机遇,顺势而为,创造辉煌佳绩;在挑战面前&#xf…

嵌入式 C语言/C++ 常见笔试、面试题 难疑点汇总(经典100道)

#pragma comment。将一个注释记录放置到对象文件或可执行文件中。 #pragma pack。用来改变编译器的字节对齐方式。 #pragma code_seg。它能够设置程序中的函数在obj文件中所在的代码段。如果未指定参数,函数将放置在默认代码段.text中 #pragma once。保证所在文件只…

MySQL软件常见操作

1登录MySQL 登录,如果你配置了环境变量就可以winr,在运行框输入cmd,输入登录命令 第一种:直接输入密码 mysql -uroot -p(你的密码没有有括号) 第二种不直接输入密码 mysql -uroot -p 前面两种都是localhost登录 下面是完整版 m…

slam定位学习笔记(七)-g2o学习

主要学习的是这篇文章,但大佬并没有在文章里面仔细的讲g2o,所以我在网上找了这几篇介绍g2o的文章,讲的十分详细,对入门十分友好:文章一、文章二、文章三,这三篇都是一个作者写的,主要是针对编程…

MATLAB数据导入

MATLAB数据导入 在编写一个程序时,经常需要从外部读入数据。MATLAB使用多种格式打开数据。本章将要介绍MATLAB中数据的导入。 MATLAB中导入数据的方式有两种,分别是在命令行通过代码把数据导进去和通过MATLAB的数据导入向导导入数据。本节将为大家介绍第…

广播实现强制下线功能

实现强制下线功能 强制下线应该是一个比较常用的功能,比如QQ在比的地方被登陆了,就会强制比被挤下线.强制下线的功能还是比较简单的,只需要在界面上弹出一个框,告知用户无法再进行任何操作即可.只能点击确定然后跳转至登录界面.强制下线功能需要关闭所有的Activity,然后返回到…

微服务框架 SpringCloud微服务架构 4 Ribbon 4.3 饥饿加载

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构4 Ribbon4.3 饥饿加载4.3.1 饥饿加载4.3.2 总结4 Ribbon 4.3 饥饿加载 4…

【毕业设计】深度学习车辆颜色识别检测系统 - python opencv YOLOv5

文章目录1 前言2 实现效果3 CNN卷积神经网络4 Yolov55 数据集处理及模型训练6 最后1 前言 🔥 Hi,大家好,这里是丹成学长的毕设系列文章! 🔥 对毕设有任何疑问都可以问学长哦! 这两年开始,各个学校对毕设…

ATJ2157ATJ2127音乐按文件名拼音排序---标案是按内码进行排序

音乐按文件名拼音进行排序参考网站ATJ2157&ATJ2127 排序是按照内码(汉字为GBK即GBK936)排序的按拼音排序unicode与拼音的对比表(U2P.DAT),需要打包到固件中U2P.DAT数据结构U2P.DAT生成代码是使用DEV-C生成其他说明U2P.DAT与ATJ2127平台代码参考网站 各种字符对…

activiti-api

activiti-api目录概述需求:设计思路实现思路分析1.VariableEvent2.EmptyResult3.BPMNElement4.BPMNError5.ConnectorAbstractSecurityManager参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&…

Mac下安装Hadoop

1、引言 如果想在Mac下安装Hadoop而且让Hadoop能正常运行,那安装之前需要先安装java,在Mac环境下安装Hadoop。 2、配置ssh环境 在Mac下如果想使用Hadoop,必须要配置ssh环境, 如果不执行这一步,后面启动hadoop时会出现…

PyCharm+PyQT5之三界面与逻辑的分离

之二的例程已经实现了界面与逻辑的分离,所建立的 Dialog Mainwindow 或者 widgets 等,界面改变其主调程序(暂且这样叫)更改,或者不需要大规模更改, 主调函数的程序是这样的 import sys import FistUI from PyQt5.QtWidgets import QApplication, QMainWindow,QDialog if __nam…

解决 Android WebView 多进程导致App崩溃

应用场景 应用内有两个位置用到WebView加载页面,具体处理逻辑不能通用。分别扩展了WebView了。应用内独立页面使用Fragment来展示,(采用单Activity架构)。应用提供切换语言功能。 问题猜想 一、WebView内核bug 具体路径: 进入app–>设…

cmake使用

1. cmake概述及例子 CMake快速入门 cmake、qmake、cl之间关系 1.1 各种cmake cmake根据CMakeLists.txt生成makefile,make根据makefile行编译。 1.1.1 最简cmake:生成可执行程序(一个文件) #CMakeLists.txt cmake_minimum_req…