最近有个朋友问我,他想将国内的CCTV节目内容,通过互联网传输到北美去。因为那边移民了很多的中国人,他们过去的时候会带着他们的家人,有的家人不会英语,就很想看国内的电视节目。他问我如何做到既不用专线,只使用互联网就可以实现的。
恰好我之前做了一个类似的项目,目前运行了很久,各方面都很稳定。于是我在这方面刚好有一些可以聊的干货。
今天我们就来简单地聊聊在类似跨境视频传输方面可以采取的方法吧。
首先我们看看一般电视节目是怎么到达用户手机上或者电视上的。
视频播放示意图这是一个简单的示意图。
通常视频源采用的是HLS协议,HLS协议本身非常简单,而且适应性比较强。
以下是百度中对于HLS协议的解释:
HLS (HTTP Live Streaming)是Apple的动态码率自适应技术。主要用于PC和Apple终端的音视频服务。包括一个m3u(8)的索引文件,TS媒体分片文件和key加密串文件。
这个解释有点抽象,简单来说,就是有两个文件,一个是m3u8索引文件,这个文件中记录着每一个音视频流的TS文件名称、时长,加密等等。另一个是实际的视频流TS文件。
以下是一个简化后的M3U8文件内容
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:64
#EXTINF:6.000000,
2300/20200316/298.ts
#EXTINF:6.000000,
2300/20200316/299.ts
#EXTINF:6.000000,
2300/20200316/300.ts
#EXTINF:6.000000,
2300/20200316/301.ts
HLS协议非常简单,完全采用HTTP协议。播放器只需要根据索引m3u8文件下载相应的TS文件,然后按照顺序进行播放就可以了。
凡事都是双刃剑,HLS虽然简单,但是它会带来一个非常大的问题,那就是延迟。一般HLS协议的延迟是因为每一个TS视频文件都有一定的时间,一个索引文件中有多少个TS文件,理论上就会有多大的延迟。如此推算,上面的m3u8代表的视频流最大的延迟应该在24秒。
这种用于跨境传输,如果在实时性要求不高的情况下是完全可以的。但是如果在实时性要求比较高的场景下就不行了。
例如在体育比赛的场景中,肯定没办法满足需求(试想一个场景:足球比赛中,国内都已经看到进球了,北美的用户还没看到球员突破禁区呢。这种体验真的是...)。
对于实时性要求非常高的场景,如何才能做到跨境传输呢?
我们来计算一下,从国内到国外除去其它因素,只考虑网络延时,国内到北美那边大概的RTT(Round Trip Time即传输往返时间)时间在300毫秒左右。那就意味着无论我们如何做,只要是你用互联网来进行传输,那么延时一定会有300毫秒以上(选择其它传输的线路,例如先从国内传输到欧洲、然后在从欧洲传输到北美则是另一个话题了)。
我们如何将传输时间缩短到接近这个时间呢:
有两种方法。一种方法非常简单,不用进行复杂的开发。一种非常麻烦,但是控制权完全在自己手上。
简单的我这里就不说了,因为一切控制权都交出去了,技术什么的也就不值一提(不过后面我也会提到)。
说说需要技术含量的吧。
其实这种技术是非常成熟的技术了,想想我们的手机通话,不会因为你是给国外打电话而不通吧。这种技术叫做HARQ。
百度对于HARQ的解释是:
混合自动重传请求(Hybrid Automatic Repeat reQuest,HARQ),是一种将前向纠错编码(FEC)和自动重传请求(ARQ)相结合而形成的技术。
从定义上看HARQ会有很多不同的实现方式,事实上也是如此(嘚瑟一下,我有一个专利就是关于HARQ的,名叫《基于混合自动重传请求的数据传输方法及系统》)。
从百度定义中其实我们可以看到它的两个特性:
1:前向纠错编码(FEC)
2:自动重传请求(ARQ)
前向纠错编码非常专业,一大堆的算法,什么汉明码、BCH码、Turbo 码、以及大名鼎鼎的LDPC和极化码。太专业了,听着都头痛。其实目的很简单,就是对一大堆的数字在发送端编码,在对方那里解码。如果在传输过程中产生了错误,接收端也能根据现有的数据恢复出原来的数据。
举个例子吧:
张三和李四打电话,张三说了一个“1、2、3”,信息在张三本地编码,传送给李四。传输中出现了错误,到李四那边成了“1、2、4”。前向纠错就是通过算法,算出张三说的是“1、2、3”。
前向纠错编码一般都会对于数据进行一定的冗余,传输的带宽会比实际的裸数据多出一些来。那会多出多少呢?这个是根据实际抵抗网络抖动能力的不同而不同的,有的系统多出5%,有的系统10%,而有的系统完全是动态的,网络不好时10%,网络好时5%。这些完全由算法来决定。
简单说了说FEC,下面说说第二个部分——自动重传请求(ARQ)。
为啥要重传?这个好理解。将数据从国内传输到北美,数据需要经过N多的设备。这些设备千差万别,丢包是再正常不过的事情了。
丢了包怎么办?
通过FEC算算看,看能不能算出来。
实在算不出来了咋办?
重传呗。
下面是一张简图:
传输丢包示意图从简图中可以看到,传输10个数据包中,任何一个都有可能没到达对方。而这些没有到达对方的数据包在计算不出来的时候,都要进行自动重传。
以上这句话说起来挺简单的,但是实际实现起来有几个难点:
难点1:你怎么知道数据包是丢失了,还是它还在传输中呢?
这个两个状态状态的差别,在处理上简直是天壤之别:
如果它是在传输中,我们就不能进行重传,等等看,兴许它就传输过去了呢——这样你就少传一份数据了,可以降低网络消耗。
可它万一真的丢了,你要马上重传——这个等的越久,对方缓冲的数据就会越多。
难点2:难点1中说,要马上重传,但是如果重传数据过多,又会造成带宽消耗,引起更多数据包的丢失。
这两个难点如同悖论一样,如何解决呢?下次再详细说吧。
网友评论