MSS(Microsoft smoothing streaming)介紹

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sstr/8383f27f-7efe-4c60-832a-387274457251?redirectedfrom=MSDN

這裏是微軟的官方介紹,mss和hls出現都比較久了,應用的也非常多。


1、微軟SmoothStreamIndexing協議規定了四種消息:

(The IIS Smooth StreamIndexing Transport Protocol defines four types of messages: )

  1.Manifest Request 

  2.Manifest Response 

  3.Fragment Request 

  4.Fragment Response 

把HTTP cache proxies 的角色放進去:

    不同的client,同樣請求同一塊fragment,第二次直接從cache返回。

    自己搭建了一個SS web server,抓包看了一下消息的內容,以BigBuckBunny舉例吧。抓包軟件最開始用的wireshark,可是不知道爲什麼總是收不到本來期望能收到的包,後來改用Windows network monitor,很容易上手很好用,還會列出哪些消息是在哪些進程裏面。

1. Manifest request

在瀏覽器中輸入http://[server_name]/[virtual_addr]/bigbuckbunny.ism/manifest,client向server發送HTTP請求。

協議中要求的(manifest/fragment request):HTTP方法必須是GET,HTTP協議版本必須是HTTP/1.1

2. Manifest response

Server 將bigbuckbunny.ismc 發回給client,可以在瀏覽器中顯示出來。(用了另外的URL展示)

協議中要求的(manifest/fragment response):HTTP 狀態碼必須是200,HTTP協議版本必須是HTTP/1.1。payload中就是ismc文件的內容了。

這時如果再次請求(在瀏覽器中刷新頁面),得到的響應卻是304:

304 not modified,數據內容跟上一次比沒有變化。這個應該跟cache-control的值有關,沒研究過不深究了。這篇先不研究manifest文件的具體element和attribute,只看消息交互。

3. Fragment request

在瀏覽器中輸入:http://[server_name]/[virtual_add]/SmoothStreamingPlayer.html

server的響應:

client收到的第一個響應,會是manifest,然後才能根據manifest裏面的信息來構建fragment request。

URL裏面包含了具體的QualityLevels 和Fragments 值。client向server請求bit rate是2962000,fragments偏移是400000000的video chunk。

 

4. Fragment response

由於之前已經執行過,播放過了,所以得到的響應時304。Server說還是老數據,自己從cache裏面拿吧。

5. Continue

下一個Fragment request 請求的offset是420000000。

 

終於等到一個不是304的響應。

返回的狀態碼是200,類型是video/mp4。HTTPPayloadLine是空的,內容包含在下一個響應中:

一般在200 ok響應之後,要接着發好幾個帶有HTTPPayloadLine的包,見下圖,一對一的都是304響應。

    用Microsoft Network Monitor 抓包,協議列,請求都是PCCRTP,在wireshark中直接是HTTP。PCCRTP:Peer Content Caching and Retrieval: HTTP extension.

    有時候client會收到 412 響應,代表fragment not yet available。

 

1.  Manifest Request 

ManifestRequest =  [ "/" VirtualPath ] "/" PublishingPointName "." "ism" / VendorExtensionFileExtension "/" "Manifest" 

注意上面的式子中有一個斜槓是沒有引號的,也就是VendorExtensionFileExtension前面那個,也就是說這個斜槓不是要出現在Request中的,這個斜槓表示或者的意思。

也就是說,"."後面既可以跟ism也可以跟提供商自己的擴展名,"ism"跟VendorExtensionFileExtensions是或的關係。

看來ManifestRequest中必須包含".",就是"/" "Manifest"的前一級必須包含"."。這樣看來我自己在lighttpd上搞的目錄實際是不符合協議的。

http://ak.xbox.c4assets.com/ondemand/CH4_29_02_29_65973003001001_001_SQ.ism/Manifest

這個URL就是一個Request Manifest。

2. Manifest Response (Manifest 文件的格式)

Manifest文件是個XML文本,遵循XML標準。注:XML 標籤對大小寫敏感,XML 的屬性值須加引號。

Manifest的根元素必須是<SmoothStreamIndexingMedia>,這個元素的意思是“客戶端爲了播放節目(Presentation)所需的所有元數據”。

  這個元素有4個屬性:MajorVersion,MinorVersion,TimeScale,Duration。
  2011版新加入3個屬性:IsLive,LookaheadCount ,DVRWindowLength。這三個屬性都是直播相關的。
 

其中除了TimeScale之外都是必須的,TimeScale之所以不是必須,是因爲他有默認值————10000000(1個1,7個0)。

TimeScale的意思是每秒鐘Duration屬性的增量,Duration就是節目長度的意思。也就是每一秒,Duration加幾,TimeScale就是個這數。

可以理解爲TimeScale是劃分時間的粒度,10000000代表每秒鐘節目時長加10的7次方那麼多,反過來理解就是,每10的負7次方秒,節目長度就要加1。

默認值把視頻劃分的夠細的啊。(比hls分得更細,hls是官方推薦的10s)

另外兩個屬性,描述版本用的:MajorVersion必須等於2,MajorVersion必須等於0,這沒啥好說的,規定。

這個元素屬性挺少的,到這兒就說完了。下邊說說這個元素的內容:

內容=[ ProtectionElement S?] 1* StreamIndexElement  注: *元素 表示0或多個元素,1*元素 表示1或多個元素,2*3元素 表示2或3個元素。

上面是協議裏寫的,翻譯成漢語就是,由一個可選的<Protection>元素和若干個<StreamIndex>元素組成。接下來的任務就是看看這倆元素分別是啥了。

先看<StreamIndex>元素。

<StreamIndex>元素的意思“客戶端爲了播放Stream所需的所有元數據”,跟前邊<SmoothStreamIndexingMedia>比,把節目(Presentation)換成了Stream。

其實一個節目一般可以分爲兩個Stream,即視頻流和音頻流。以後就管Stream叫“流”了,漢語方便。

這 個元素有以下這12個屬 性:Type,Subtype,TimeScale,Name,Chunks,QualityLevels,Url,MaxWidth,MaxHeight,DisplayWidth,DisplayHeight,VendorExtension。

其 中Type是必須的,並且,如果這個<StreamIndex>元素中沒有插入<QualityLevel>元素,那麼這3個元 素也是必須的:NumberOfFragments, NumberOfTracks,Url。當然,常見的場景是<StreamIndex>元素中都插入 了<QualityLevel>元素。

下邊來看看這12個屬性都什麼意思:

Type:流的類型,可以是video, audio, or text。text有點特殊和不常見,今天先不說。

MaxWidth, MaxHeight, DisplayWidth, DisplayHeight:這4個屬性就是字面意思。注意只有當Type屬性的值爲video時,這4個屬性纔可以出現。

Subtype:當Type屬性的值爲text時,這個屬性必須出現。這個屬性稍微複雜並不常用,今天先不說。

Name :流的名稱,沒啥好說的。

Chunks :流中Fragment的個數,Fragment就是分片。

QualityLevels :流中Track的個數,目前理解是,一個碼率就叫一個Track(對於視頻)。協議裏說Track元素的名字就是QualityLevel。

Url:客戶端用以產生FragmentRequest的格式,這個屬性的值必須是UrlPattern:

UrlPattern = QualityLevels("{bitrate}" / "{Bitrate}"  ["," "{CustomAttributes}"] )"/"Fragments(TrackName "=" "{start time}" / "{start_time}" )

TimeScale:這個流中的TimeScale,跟前面的TimeScale具有相同的意義。

VendorExtension:內容提供商自己開發擴展用。

下邊說說這個元素的內容:

StreamContent = 1*(TrackElement S?) *(StreamFragment S?) 

翻譯成漢語就是,此元素的內容是一到多個Track元素(<QualityLevel>)與0到多個StreamFragment元素(<c>)組成的。下面正好開始看這兩個元素。

<QualityLevel>元素(Track元素)的意思是“客戶端爲了播放Track所需的所有元數據”,跟前邊比,把stream換成了track。

這 個元素有以下這些屬 性:Index,Bitrate,MaxWidth,MaxHeight,CodecPrivateData,SamplingRate,Channels,BitsPerSample,PacketSize,AudioTag,NALUnitLengthField

這些屬性都是啥意思今天先不說。

這個元素的內容如下:

TrackContent = CustomAttributes?

這個內容協議裏描述的沒太看明白,而且也不咋重要,今天先不說。

<c>元素(StreamFragment元素)的意思是“分片(Fragments)元數據的集合”。這個元素很重要,今天好好說說。

這個元素有3個屬性:n,d,t。其中d和t至少要出現一個。

n:分片在流中的序號,隨時間遞增。非必須屬性。

d:(FragmentDuration)分片的持續時間。由包含這個分片的流的TimeScale屬性的值顯示的或隱含的指明。如果d屬性沒有出現,那麼他的隱含值要由客戶端按如下規則計算:

   用本<c>元素的t屬性的值減去後面那個<c>元素的t屬性的值。翻譯成漢語就是,當前分片的開始時間減去後面分片的開時間。

如果一個分片沒有後續分片,那麼他的d屬性隱含值爲0.(注:這裏協議原文貌似寫的有問題,我覺着只有按我這麼理解才能解釋通)

t:(FragmentTime)分片(開始)時間(點)。由包含這個分片的流的TimeScale屬性的值顯示的或隱含的指明。如果t屬性沒有出現,那麼他的隱含值要由客戶端按如下規則計算:

   用本<c>元素前面那個<c>元素的d的值加上t的值。

   如果一個分片前面沒有其他分片,那麼他的t屬性隱含值爲0.

   

下邊是個例子:

     <c t = "0" d = "19680000" />  

      <c t = "19680000" d="19680000" /> 

      <c t = "39360000" d="19680000" /> 

爲了支持直播,新版協議給視頻分片加了兩個新的box(type=uiid):tfxdBox(本分片的t和d封裝在裏面),tfrfBox(下一個或幾個分片的t和d封裝在裏面)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章