圖網長期致力于web前端開發,難免會和各種視頻、音頻打交道,除了常見的mp4、mp3等格式,其實還有m3u8、oga等等其他沒有那么常見的格式,那么你都了解了嗎?下面介紹一下html5常見的音視頻格式和解決方案。
萬能播放插件js
1.ckplayerhttp://www.ckplayer.com/
2.Sewise Player
一款專業的免費網頁HTML5視頻、流播放器,它功能強大,體積小,跨平臺,兼容性好,使用方便簡潔。確定html5與flash播放的優先級。支持跨終端播放,不僅適用PC端播放,也適配ipad、iphone、android手機、平板電腦等移動終端。 支持多系統多平臺,PC端支持Window、MacOS、Linux 等,移動端支持Android、IOS、Window Phone等。 兼容HTML5,確保98%的互聯網用戶可以看到您的視頻。 支持多瀏覽器兼容,IE6/7/8/9/10、Chrome、Firefox、Safari、Opera等。 接收來自任何地方的音視頻流 支持mp4、m3u8、oga、webm、theora、flv、f4v等視頻格式播放。 支持Flash播放m3u8文件,以及AES-128解碼播放。 支持播放地址AMF, AJAX, JOSNP類型請求。 支持PC與Mobile平臺播放器自動識別功能。 支持瀏覽器HTML5與Flash特性檢測。
3.hls
http://www.bootcdn.cn/hls.js/
僅支持hls(m3u8)地址,不支持flv,mp4,mov,f4v,3gp格式,做了跨平臺的適配, 支持PC終端,Android安卓終端,iOS蘋果終端,WP終端的正常播放。
m3u8是m3u的一種,是utf-8格式的,Apple 為了提高流播效率開發的技術,特點是將流媒體切分為若干 TS 片段(比如每10秒一段),然后通過一個擴展的 m3u 列表文件將這些 TS 片段集中起來供客戶端播放器接收。可以做多碼率的適配,根據網絡帶寬,客戶端會自動選擇一個適合自己碼率的文件進行播放,保證視頻流的流暢。
MP4是一套用于音頻、視頻信息的壓縮編碼標準,支持所有音頻和視頻以及高級內容(或它們的混合),編碼格式:H.264格式高清
MP4是遵循MPEG-4(ISO 14496-14)的官方容器格式定義的廣義文件擴展名。它可以流媒體化并支持眾多多媒體的內容(多音軌(multiple audio)、視頻流(video)、字幕(subtitlestreams)、圖片(pictures)、可變楨率(variable-framerates)、碼率(bitrates)、采樣率(samplerates)等)和高級內容(advanced content)(官方稱之為“Richmedia”(超媒體)或“BIFS”(Binary Format for Scenes/二進制格式場景),類似2D和3D圖形,動畫、用戶界面、類DVD菜單,上述這些AVI搞不定的東西。
其他相關的擴展名:
– .m4v:是.mp4文件的錯誤擴展名,由apple提出,支持視頻+音頻,m4v擴展名可以安全地更名為.mp4
– .m4a:是.mp4文件的錯誤擴展名,由apple提出,只支持音頻,m4a擴展名可以安全地更名為.mp4
– .m4p:隨iTunes發售的DRM(Digital Rights Management/數字版權保護技術)產權保護的文件,使用Apple開發的DRM sheme
– .m4e:由.sdp修改擴展名的來的文件,Envivio用其于流媒體播放。
– .m4v, -.mp4v, -.cmp, -.divx, .-xvid, .264:raw的mpeg-4視頻流(并非內含于mp4)。
– .3gp, -.3g2:手機中使用的格式,其中儲存的內容同樣在.mp4未被定義(H.263, AMR(Adaptive Multi Rate/自適應多碼率))。
OGG OGGVobis(oggVorbis)是一種音頻壓縮格式,類似于MP3等的音樂格式。Ogg是完全免費、開放和沒有專利限制的。OggVorbis文件的擴展名是”.ogg”。Ogg文件格式可以不斷地進行大小和音質的改良,而不影響舊有的編碼器或播放器。
OGV是html5中的一個名為Ogg Theora的視頻格式,起源于ogg容器格式。
webm由Google提出,是一個開放、免費的媒體文件格式。WebM標準的網絡視頻更加偏向于開源并且是基于HTML5標準的,WebM 項目旨在為對每個人都開放的網絡開發高質量、開放的視頻格式,其重點是解決視頻服務這一核心的網絡用戶體驗。
MOV(QuickTime)它是Apple公司開發的一種音頻、視頻文件格式,用于存儲常用數字媒體類型。QuickTime用于保存音頻和視頻信息,包括Apple Mac OS,MicrosoftWindows95/98/NT/2003/XP/VISTA,甚至WINDOWS7在內的所有主流電腦平臺支持。
WMV 是微軟推出的一種采用獨立編碼方式并且可以直接在網上實時觀看視頻節目的文件壓縮格式。WMV格式的主要優點包括:本地或網絡回放、可擴充的媒體類型、部件下載、可伸縮的媒體類型、流的優先級化、多語言支持、環境獨立性、豐富的流間關系以及擴展性等。
MPG/MPEG(.mpg, .mpeg)
Realmedia(.rm, .rmvb)
AVI(.avi)
Flv/swf
本文由專業的WEB前端外包公司-切圖網原創,轉載請保留版權( WEB前端開發外包www.qietu.com )切圖網始于2007年,提供高品質的前端開發服務、前端外包、切圖外包。歡迎來電咨詢!
照相機、留聲機誕生,解決了人們記錄影像、聲音的需求以來,人們就不斷地追求著在有限的條件下盡可能地提高這些記錄的品質,而從模擬時代過渡到數字時代以后,這方面的追求有一部分變成了在盡可能小的空間中提供盡可能好的內容質量,這就催生出了一系列不斷演進著的媒體壓縮技術。
不過這期課堂的主題尚未來到媒體編碼的歷史,在講音視頻圖像的壓縮算法進化之路前,我們先來了解一下這些媒體內容的載體——容器格式的進化歷程。
首先需要區分清楚的,就是容器格式與媒體編碼格式。
對于數字媒體數據來說,容器就是一個可以將多媒體數據混在一起存放的東西,就像是一個包裝箱,它可以對音視頻數據進行打包裝箱,將原來的兩塊數據整合到一起,也可以單單只存放一種類型的媒體數據。它就像電影膠片一樣,中央是一幀一幀的圖像,而兩旁則印有對應的音軌。
舉個簡單的例子,常見的MP4就是一種媒體容器格式而不是編碼格式,它里面的視頻編碼可以是現在最常見的AVC/H.264,也可以是它的前任H.263或者下一任——HEVC,音頻編碼可以是常見的AAC也可以是AC-3。
另一個生僻點的例子:最常見的圖片格式——JPEG,它其實只是一種壓縮方式,而它的存放方式其實叫做JFIF(JPEG File Interchange Format),雖然在JPEG標準中定義了一種名為JIF(JPEG Interchange Format)的容器格式,但是因為其缺乏某些關鍵要素,造成了使用的不便而被后來第三方開發出來的JFIF容器給取代了,今天我們能夠看到的JPEG文件幾乎都是裝在JFIF容器中的。
雖然今天我們能夠直接拿到的MP4文件里面裝的幾乎都是AVC+AAC的組合,但還是不能混淆了兩者的概念,容器就是個容器,它沒得靈魂。
AVI可能是和筆者年齡相仿的朋友最早接觸的一個格式。確實,它推出的時間相對較早,也是許久以前最為常見的一種容器格式。它全稱叫做音頻視頻交錯( Audio Video Interleave),顧名思義,它就是簡單地將視頻與音頻交錯在一起,幾幀視頻之后就是對應的音頻段,這樣重復,直到結束。
AVI文件的結構示意圖
它由三部分組成,頭部、主體以及位于文件尾部的索引。頭部中含有文件的元數據(metadata),比如視頻的分辨率、碼率總幀數等信息。主體部分是媒體數據的存放區,它使用了塊(chunk)的概念,將原本的視頻流和音頻流分成塊狀進行交錯放置,就是上面講的一段視頻一段音頻交錯放置,而尾部則是用來放置索引,它用來記錄每個數據塊在文件中的偏移位置。
紅框標注為對軌道的標識
講到AVI,還可以聯動一下WAV和蘋果那邊的AIFF,這些容器格式其實是同源的,來自于EA(對,就是現在那個做游戲的EA)為了讓不同公司開發出來的軟件之間進行數據交換而在1985年開發出來的IFF(Interchange File Format)格式。蘋果在IFF的基礎上開發出了AIFF,而微軟與IBM將IFF格式使用的大端序改成小端序就成了RIFF(Resource Interchange File Format),也就是AVI、WAV這兩個容器的基本原型。
AVI雖然老,但是因為它以幀為單位把數據切成塊來存放的特性,使得它幾乎支持市面上幾乎所有的音視頻編碼。而它的缺點也有很多,首先因為索引在文件尾部的關系,所以它并不適合用來流傳輸;另外在容器中也沒有時間戳,只能通過幀數和幀率信息來進行計算,在索引里面并沒有寫明時間戳—媒體位置的數據,所以要在播放AVI時進行快速跳轉還需要額外的技術手段;而媒體數據分塊存放也使得它對很多使用運動預測特性的視頻編碼的支持并不是太好,因為這些幀,比如P幀和B幀,都是通過I幀進行計算得到的,這就需要訪問當前幀以外的數據了。
用電腦播放過VCD的朋友一定還記得會在目錄里尋找那個最大的.DAT文件來播放,而DVD則是找那個最大的.VOB。其實這兩個格式都是MPEG-PS容器規范的一種,此PS非彼Photoshop,而是指Program Stream,是MPEG組織在1993年發布的一個容器標準,并且隨后寫入ISO/IEC國際標準,除了以上兩種后綴名之外,還有.mpg也用的是這個標準。
MPEG-PS標準中引入了包的概念,整個文件由一個個包組成,每個包的大小并不相等,包里面含有這個包的時間碼以及對應的音視頻數據。
MPEG-PS已經隨著時代的進步被廢棄了,它只能存放MPEG-1、MPEG-2、MPEG-4這些出自同門的視頻編碼,限制性較大。但因為VCD和DVD的廣泛流行,實際上它還是被用的相當多的。
MPEG組織不僅僅為音視頻文件的存儲制定了容器標準,還早早地順應時代潮流,為它們的傳輸準備了相應的容器。我們的數字電視和IPTV用的就是MPEG組織在1995年制定的Transport Stream,也就是TS容器,當然它也并不限于這兩個場景,在現在的低延時直播系統中,MPEG-TS仍然占據了絕對主流的地位,原因就是它的整個結構就是為了流傳輸而設計的。
從IP層到TS包內部的結構
一個TS文件中可以容納多個TS流,不同的流上面可以帶有不同的音視頻數據,這樣通過接收一個TS文件,用戶方面可以自由地在這個TS文件中的多個子TS流之間進行切換,非常適合用于傳輸電視節目。而它同時針對復雜的傳輸環境進行了針對性的優化,TS流的基礎單位是一個個大小僅為188字節的包,每個包都有自己的獨立時基,并且由于采用了固定大小,所以在傳輸過程中即使遭遇丟包也很快就可以恢復正常播放。
發展到今天,TS仍然在網絡流傳輸時代中發揮著自己重要的作用,在蘋果主導的HLS(Http Live Streaming)協議中使用的就是TS流,它比MPEG-DASH更加通用,因為后者對于MP4文件進行了一定的修改,在老平臺上面支持不太好,而HLS使用的TS仍然是規范中的,可以被大多數設備兼容。
不過也因為TS分包較多的特性,會產生一些數據冗余,所以在存儲場景中一般不會使用TS作為容器。
M2TS:專為高清時代而生
M2TS多見于Blu-ray光盤和高清錄像(AVCHD)中,它由MPEG-TS修改而來,加入了對于高清時代新的音視頻編解碼支持。
一張Blu-ray視頻光盤中的M2TS
并且由于TS文件的特性,每一個小片上都有自己的獨立時間戳,這使得文件中一部分數據即使遭到破壞也不會影響到其他部分的正常播放,而且可以從中隨意的進行切片操作。
見過ASF格式視頻的朋友我想應該不會太多,但是見過WMV和WMA這兩個微軟以前主推的媒體編碼格式的朋友肯定有很多。其實WMV和WMA就是存放在ASF容器之中的,它全稱高級系統格式(Advanced Systems Format),微軟原本計劃是用它來作為AVI容器的后繼者的,它具有諸多先進的特性,比如說它可以包含視頻除了規格以外的元數據,如導演、電影名這些,它也可以提供數字版權管理(DRM),還有非常好的流傳輸支持——僅需要加載文件的最小部分即可開始播放,這點小編感受過一次。
ASF文件開頭會用這32個字節來標識自己是個ASF文件
ASF身上的這些特性在當時還算是比較先進的,但不過這于事無補,微軟建立它那套封閉媒體格式體系的做法并沒有得到太多廠商和用戶的支持,大家仍然更喜歡用其他更為開放一點的標準,比如MP3就是一個很好的例子。ASF容器也隨著微軟媒體格式的衰亡而漸漸消失了,我們今天已經幾乎看不到WMV、WMA這兩個曾經還很常見的格式的影子了。
與ASF差不多同時代流行的就是RM和RMVB了,在那個AVC尚未開始普及,DivX和XviD應用較少的年代中,RMVB在國內的各大下載站中都占據了絕對主流的地位,很多視頻站也大多使用RM來提供“網絡視頻點播”的服務。
RM容器的內部結構
不過RM容器本身并不出彩,索引仍然位于文件尾部,不過由于數據段里面有加入時間戳,所以在流傳輸時還是可以應付用戶的跳轉操作的。因為這個容器本身與RM編碼息息相關的原因,它本身也只能容納RM編碼的視頻流,所以在RM編碼沒落之后我們就很少再看到這些昔日王者了,一個容器格式想要長存,要么在設計上有其獨到之處,要么就是要開放,在眾多平臺上面提供支持。而RM兩個理由都不占,效果又比不過新興的AVC,所以它的沒落也是必然了。
還記得十年前的土豆網嗎?彼時它還被稱為“國內的Youtube”,當時視頻網站普遍都還在用Flash寫播放器實現流視頻播放,而自然而然地,Adobe制定的Flash Video格式就成了這些視頻網站主要使用的容器格式,也就是我們熟知的FLV。
FLV格式是在Flash Player 6中引入的,當時更多的是被存放在SWF文件的內部,不過后來因為體積越來越大而直接獨立了出來,它的結構相對而言比較簡單,主要分為兩塊,位于文件頭部的元數據信息和后面的音視頻數據。不過在數據的存放上面,FLV是將數據分為多個標簽進行存儲的,每個標簽都帶有自己的時間戳,所以這就保證了流傳輸時的音畫同步。
由于FLV結構簡單但是功能足夠用,并且被Flash Player天然支持,所以在當時的視頻網站上面普遍都使用它作為容器,直到今天還有很多網站沒有放棄它,雖然其中的視頻編碼早已升級,它也有衍生出來的F4V作為后繼者,雖然后者的血統已經不是Flash家族的了。
F4V:換了血的繼任者
小編還記得土豆網在2009、2010年左右在國內率先開始使用H.264編碼,當時如果將清晰度切換到“高清”就會播放這些用H.264編碼的視頻。而用飛速土豆加速會緩存到一些.f4v擴展名的文件,乍一看還以為它就是FLV,但其實不然,F4V其實是MP4所在的ISO標準容器家族的,但也是Adobe搞出來的FLV的后繼者。關于后者的詳情,請往下看。
MOV格式的正式名字叫QuickTime File Format。看到這個QuickTime第一反應肯定是“哦,這是蘋果的東西”。確實,QuickTime File Format是由蘋果在1998年推出的,它引入了原子(atom)的概念,在QTFF格式中,atom是基本的數據單元,它可以用來容納實際的音視頻數據,也可以放置元數據和字幕等文本信息,atom中所容納的數據類型和大小在每個atom的頭部進行描述,經過一層層的嵌套之后,整個數據文件呈現了一種樹狀的結構,并且保留了強大的可擴展性。
MOV和MP4這些ISO標準容器格式的開頭都有一個ftyp用于標記格式
MOV作為蘋果QuickTime編碼的成員,在目前仍然被蘋果設備廣泛使用著,并且對于它的支持非常好。1998年推出QTFF的同時,蘋果將這個格式交給了ISO組織,后者將它標準化為國際通用容器格式,而基于這個標準衍生出來的容器,又可以叫做ISO/IEC base media file format,同時被MPEG組織采納,寫入MPEG-4 Part 12標準中。
ISO標準容器格式
ISO標準容器格式是一個規范,它代表符合這個規范的容器類型,而不是特指某個格式。它是由蘋果的QuickTime File Format發展而來的,在MPEG-4 Part 12中被最終確定并被ISO/IEC組織寫入標準。它雖然沒有具體實現,但是它定義了基于時間碼的多媒體文件的通用結構,并由此成為了MP4、3GP等格式的基礎。
3GP、MP4與ISO標準容器格式的關系
MP4肯定是現在最通用最流行的媒體容器,甚至可以說沒有之一。但其實現在的MP4和早期的并不是同一個標準,目前常見的MP4標準是在2003年完整的的MPEG-4 Part 14規范中制定的,到今天為止也經過了多次的修訂。它其實與MOV之間并沒有太大的區別,基本上就是把MOV的atom改了個名字,叫成box,然后加了一點別的佐料。
MP4的內部結構
蘋果建立iTunes Store賣數字音樂的時候選擇了AAC-LC作為他們的音頻編碼格式,而容器格式上面他們并沒有選擇與AAC-LC處于同一時代(MPEG-2)的ADTS,而是選擇了比AAC-LC大一輩的MPEG-4標準容器,也就是MP4,不過因為它只含音頻所以我們看到的擴展名就是.m4a,iTunes Store還賣一種只有視頻沒有音頻的MV,它用的也是MP4,擴展名為.m4v,本質上它們就是同一種東西。
目前很多視頻網站已經從FLV切換到MP4上面了,而且還有一種新的MPEG-DASH格式就是借助于MP4可分割的特性實現的,它將一整段視頻切成許多段小塊,方便瀏覽器進行加載,減少HTTP長連接對服務器的壓力。
這里說一句題外話,當年某站剛上HTML5播放器的時候,因為他們原來的視頻幾乎全部都用的是FLV存儲的,而HTML5標準并不支持它,所以要進行一個容器轉換,某站當時一位非常年輕的程序員寫出了一個在瀏覽器內實時將FLV文件轉成MP4并喂給瀏覽器的媒體播放器的腳本,名為flv.js,這個腳本可能給某站省下了非常大的格式轉換成本。不久之后這位程序員因為受不了某站的低薪而離職。這件事曾經引起了很多社區的熱烈討論,因為今天是程序員日所以特地寫了這么一段。
3GP:精簡小巧,手機最愛
3GP是MP4的同族兄弟,一樣是基于ISO標準容器格式,用過3GP的兄弟肯定還記得這格式最多出現的地方是哪里——以諾基亞為代表的前智能手機時代,手機錄像出來的文件大多都是3GP格式的。
3GP這個容器格式標準其實不是由以往的MPEG啊這類專注于多媒體編碼的組織搞出來的,而是3GPP,對沒錯就是制定通信行業標準的那個組織制定的。它在容器支持的格式上進行了精簡,只面向于手機可以進行的編碼,比如MPEG-4 Visual、H.263這些比較老的視頻編碼和AMR、AAC這兩種前智能手機時代使用較多的音頻編碼。
因為前智能手機時代的手機性能并不強大,一般也不需要支持很多種格式,不用像MP4那么全面,所以3GP最終成為了一種被廣泛支持的格式,不過也因為它支持的格式過于有限,最終在智能手機時代被同門大哥MP4給取代了。
MPEG-DASH
面對時下流行的流媒體,MPEG組織對MP4文件進行了魔改,由于MP4天生可以進行無損切割的特性,DASH方式將原本媒體文件中完整的文件頭的元數據信息和片段Box中的信息抽取出來單獨寫在一個文件(MPD)中,同時還包含了片段的URL等信息,播放器可以自適應選擇需要的片段進行播放,在自適應程度上面比HLS更強一些。(其實MPEG-DASH也可以用TS作為容器,但用MP4更多一些)
目前MPEG-DASH已經成為了一項國際標準,人們比較熟悉的應用平臺就是Youtube和Netflix,在這些平臺上面你會發現瀏覽器在不斷地加載一些小的視頻文件,但是視頻的播放是連續的。
說到MKV,喜歡收藏高清電影的朋友肯定不會陌生,這種容器格式大概是和高清時代一起發展起來的,但其實它在2002年底就已經完成制定了,不過推廣的很緩慢,到了高清時代和UHD時代人們才開始發現這種容器的強大,并用的越來越多,連微軟都在Windows 10的初始版本中加入了對它的支持。
MKV的內部結構
MKV全名Matroska,它身上最大的特點就是開放標準、免費使用,而且它可能是目前地球上最強大的數字媒體容器格式,一個文件中可以放音頻、視頻、字幕、字體還有章節信息等等等等,前面東西都是不限數量任你放多少都可以吃得下的,而且它是目前唯一一個支持封裝ASS字幕的格式。
值得一提的是,這玩意兒是俄羅斯組織матрёшка搞出來的,其實本身是用于盜版的,俄羅斯的網絡情況跟我們挺像的,網絡上盜版橫行,而MKV也幫助了文件的傳播,目前來看,MKV可能是眾多容器格式里面最好用的,無論是編輯元數據還是抽取軌道重新封裝都有GUI工具支持,不過可惜的是眾多視頻編輯剪輯軟件還是沒有提供對它的支持。
其實讀到最后你會發現,這些容器格式內部對于音視頻數據的處理都是大同小異的,區別點其實并不大。更多的差距在于它們對于不同編碼格式的支持程度、元數據的詳細程度以及對于是否能夠支持音視頻以外的數據。
而發展到至今,MP4仍然夠用,在互聯網時代扮演著非常重要的角色;MKV在下載黨那里被奉為圭臬;而TS格式仍然在數字電視系統中被廣泛使用。但在他們之前的格式也不是說非常弱或者不好,只不過可能是他們支持的那些格式沒落了順帶著把它們也帶沒了,真正像AVI那樣確實在技術規格上落伍的容器并不多。
而對于各種容器之間無損互轉的事情,小編這里推薦mp4box、mkvtoolnix和強大的ffmpeg這些工具。下一篇系列課堂,我們會轉向在如今多媒體領域中扮演無可替代角色的視頻編碼的變遷史,并且會看一看未來的AV1和VVC這兩種對于大眾來說還很陌生的下一代視頻編碼。
本文章主要對在瀏覽器環境中實現直播相關的技術介紹,其中包括了對音視頻的格式以及推送、播放技術的探索。分享過程中還會對目前自己已經實現的一套Web直播方案進行分析。最后還會簡單介紹現在比較熱門的WebRTC技術。
音視頻串流從廣義角度來說,就是能夠實現設備A將音視頻畫面同步傳輸給設備B進行播放,例如電視投屏、會議投屏。而今天所介紹的Web音視頻串流主要是實現允許用戶在瀏覽器環境就能完成串流。
一個完整的Web媒體串流應當具備3種角色,推流客戶端(主播側),媒體服務器(MediaServer)和拉流客戶端(觀眾側)。其中推流和拉流客戶端其實都是在網頁中進行處理的,而MediaServer位于服務端,并且要能夠完成同時接收來自不同推流客戶端的流數據,并對這些流進行區分,向拉流客戶端提供獲取對應流的渠道。
在封裝格式里的視頻可以用不同的編碼格式,編碼格式簡單的理解就是用特定的壓縮技術把視頻做些處理。不過容器其實也可以做些壓縮處理。所以視頻是可以在編碼格式、容器格式中做兩次壓縮。
常見的編碼格式有:mpeg-2、mpeg-4、h.263、h.264、RV40
音視頻封裝格式 封裝格式就是把已經編碼封裝好的視頻、音頻按照一定的規范放到一起 同一種封裝格式中可以放不同編碼的視頻,不過一種視頻容器格式一般是只支持某幾類編碼格式的視頻。我們能夠最直觀判斷封裝格式的方法就是文件后綴。 常見的容器格式有: MP4、rmvb、rm、flv、AVI、mov、WMV、mk
對于video標簽來說,瀏覽器支持視頻播放的封裝格式有:MP4、WebM和Ogg。其中我們就MP4來說,必須使用h.264編碼的視頻和aac編碼的音頻,才能被瀏覽器正確解析,否則是沒有辦法播放的。
下面列出了另外兩種封裝格式下瀏覽器能直接解碼的音視頻編碼組合:
對于video標簽來說,瀏覽器支持視頻播放的封裝格式有:MP4、WebM和Ogg。其中我們就MP4來說,必須使用h.264編碼的視頻和aac編碼的音頻,才能被瀏覽器正確解析,否則是沒有辦法播放的。
下面列出了另外兩種封裝格式下瀏覽器能直接解碼的音視頻編碼組合:
C++音視頻開發學習資料:點擊領取→音視頻開發(資料文檔+視頻教程+面試題)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
由于在媒體串流的過程中,客戶端是需要源源不斷接受來自外界傳輸的音視頻,并且需要播放已經接受到的部分,后文中把這種特殊的媒體簡寫為流媒體。
而不論是MP4還是WebM還是Ogg都是需要等待完整的數據傳遞完成后才能夠開始播放,并且不能將多個音視頻進行無縫連接播放,所以這三種格式統統無法沒流媒體利用,涼涼。
因此我們需要其他更加適合串流的媒體封裝格式,這里主要介紹下面兩種,為后文作鋪墊。
FLV格式的流中, 每一個音視頻數據都被封裝成了包含時間戳信息頭的數據包。在傳輸時,只需要當播放器拿到這些數據包解包的時候能夠根據時間戳信息把這些音視頻數據和之前到達的音視頻數據連續起來播放。
而MP4,MKV等等類似這種封裝,必須拿到完整的音視頻文件才能播放,因為里面的單個音視頻數據塊不帶有時間戳信息,播放器不能將這些沒有時間戳信息數據塊連續起來,所以就不能實時的解碼播放。
TS(Transport Stream)
就如TS(傳輸流)的命名,似乎天生就是為了流媒體而生的一種封裝格式,其特點是多個TS片段可以被播放器無縫拼接進行播放,無需等待重新載入。不過TS的實現相對FLV要復雜許多,在此不再說明,這里我們簡單知道它的特點就可以了。
RTMP(Real Time Messaging Protocol 實時信息控制協議) RTMP是 Adobe Systems 公司為 Flash 播放器和服務器之間音頻、視頻和數據傳輸開發的開放協議, 該協議在國內直播平臺中較為普及。 RTMP 是一種基于TCP進行實時流媒體通信的網絡協議,主要用來在 Flash 平臺和支持 RTMP 協議的流媒體服務器之間進行音視頻和數據通信。RTMP協議下可以用來拉流,也可以進行退流。在瀏覽器中并不支持RTMP協議,只能通過Flash插件進行處理。RTMP傳輸是所支持的媒體格式為FLV。 主播 ==> MediaServer ==> 觀眾
這種協議主要是為了讓原本只能在RTMP中進行傳輸的FLV音視頻流也能夠在HTTP下進行傳輸。主要是用于FLV能夠在瀏覽器頁面中進行播放,由于HTML的Video不直接支持Flv格式的音視頻,所以在早期需要在網頁中加入Flash插件才能夠播放。目前大量的流媒體服務器 Media Server都支持了將FLV格式流通過HTTP-FLV的形式對外界進行開放。
HLS(HTTP Living Stream) 是一個由蘋果公司提出的基于 HTTP 的流媒體網絡傳輸協議。 HLS 的工作原理是把整個流分成一個個小的基于 HTTP 的文件來下載,每次只下載一些。當媒體流正在播放時,客戶端可以選擇從許多不同的備用源中以不同的速率下載同樣的資源,允許流媒體會話適應不同的數據速率。在開始一個流媒體會話時,客戶端會下載一個包含元數據的 extended M3U (m3u8) playlist文件,用于尋找可用的媒體流。
來解釋一下這張圖,從左到右講,左下方的inputs的視頻源是什么格式都無所謂,他與server之間的通信協議也可以任意(比如RTMP),總之只要把視頻數據傳輸到服務器上即可。這個視頻在server服務器上被轉換成HLS格式的視頻(既TS和m3u8文件)文件。細拆分來看server里面的Media encoder的是一個轉碼模塊負責將視頻源中的視頻數據轉碼到目標編碼格式(H264)的視頻數據。轉碼成H264視頻數據之后,在stream segmenter模塊將視頻切片,切片的結果就是index file(m3u8)和ts文件了。圖中的Distribution其實只是一個普通的HTTP文件服務器,然后客戶端只需要訪問一級m3u8文件的路徑就會自動播放HLS視頻流了。
說說m3u8文件
m3u8的命名來源是m3u文件 + utf-8編碼而來,兩者的文件內容是完全一樣的。下文中直接稱為m3u
m3u (移動圖像專家組音頻層3統一資源定位器)
m3u實際上就是一個索引文件,其中可以記錄TS文件地址,客戶端會按照下載的順序進行連續播放。
對于一個記錄了TS的文件M3U的文件內容如下
#EXTM3U // 聲明文件為M3U,必須寫在第一行
#EXT-X-PLAYLIST-TYPE:VOD // 當前播放類型為點播
#EXT-X-TARGETDURATION:10 //每個視頻分段最大的時長(單位秒)
#EXTINF:10, //下面ts切片的播放時長
2000kbps-00001.ts //ts文件路徑
#EXTINF:10,
2000kbps-00002.ts
#ZEN-TOTAL-DURATION:20
#ZEN-AVERAGE-BANDWIDTH:2190954
#ZEN-MAXIMUM-BANDWIDTH:3536205
#EXT-X-ENDLIST // m3u結束指令
不光如此,m3u還可以記錄二級m3u的文件的地址。
下面是一個記錄了文件地址的m3u8內容
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2128000
drawingSword(1080p).m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1064000
drawingSword(720p).m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=564000
drawingSword(480p).m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=282000
drawingSword(360p).m3u8
#EXT-X-ENDLIST
bandwidth指定視頻流的比特率,PROGRAM-ID表示資源的ID,每一個#EXT-X-STREAM-INF的下一行是二級index文件的路徑,可以用相對路徑也可以用絕對路徑。例子中用的是相對路徑。這個文件中記錄了不同比特率視頻流的二級index文件路徑,客戶端可以當前環境的網絡帶寬,來決定播放哪一個視頻流。也可以在網絡帶寬變化的時候平滑切換到和帶寬匹配的視頻流。
HLS目前的不足 由于HLS需要將采集到的音視頻進行分片、客戶端也需要對接受到的分片后的音視頻進行合并處理,因此相對來時會存在比較大的延遲,大概會達到 10s左右。
HLS在瀏覽器中的兼容情況
事實上,HLS 在 PC 端僅支持safari瀏覽器,而其他大部分PC瀏覽器使用HTML5 video標簽由于無法解析TS所以不能直接播放(需要通過hls.js)。移動端不論是安卓還是IOS統統都原生支持HLS。這點主要是由于HLS是由Apple公司推廣的,蘋果自家的瀏覽器上都是支持的,而安卓也進行了跟進。所以如果想要在PC瀏覽器上使用到HLS,仍然需要使用其他技術手段才能實現。
各協議總結:
Web音視頻串流實踐方案(WebSocket + RTMP)
這里簡單介紹一種在網頁中進行音視頻串流的方案: 把RTMP推流的工作放到中間服務層(此次以Node為例)去,而拉流通過流媒體服務器開放的HTTP-FLV,并在播放前使用Flv.js將轉換后的流數據喂給Video去解析播放。
FFmpeg:一款處理音視頻非常有效的工具, 這款工具提供以命令行的方式去對視頻進行轉碼、轉封裝格式、增加水印等等功能其中還包括了RTMP推流的功能。同時FFmpeg也為Node提供了一些控制的Bridge,在后文中,我會在中間層使用Node來控制FFmpeg進行音視頻的推流。
STEP1:推流客戶端 => Node中間處理層
這里有包括兩種推流的音視頻源,一種是實時錄制自己的攝像頭進行推流。另外一種是使用本地的視頻文件進行發送。這里我們分開來講
對于推流客戶端推送實時錄制的音視頻數據時,其核心操作就用過瀏覽器來調用攝像頭數據,并通過MediaStreamRecorder.js去捕獲音視頻二進制數據(Blob)注意此處每個時間片返回一個blob,獲得當前時間片的Blob后通過WebSocket將blob數據傳遞給Node中間層。
而對于推流客戶端推送視頻格式的文件時,需要做的就是將視頻文件按照每段時間的視頻量進行分片。例如對于一個100s的視頻,如果按照每段blob需要發送4s的數據量,那就需要分為25段blob,這些可以通過前端去進行分片,分片發送的中間Node層。后面的操作就和攝像頭推流一致了。
STEP2:Node中間處理層 => 流媒體服務器
在Blob數據抵達Node中間層后會被轉化為Buffer,在Node層我們需要做的這些分段的視頻格式轉化為ts格式的片段,再將ts片段(這里就利用到了TS能夠無縫拼接進行播放的特性,能夠讓ffmpeg推送持續的流媒體)通過ffmpeg將持續不斷接受到的TS格式的流媒體轉化為Flv流并通過RTMP推流到流媒體服務器上。
C++音視頻開發學習資料:點擊領取→音視頻開發(資料文檔+視頻教程+面試題)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
流媒體服務器是在Node.js環境下通過node-media-server第三方包進行搭建。Node-media-server許多不同協議的推流和拉流的方法。其中它支持外界通過RTMP的方式進行推流拉流(端口1935),也支持將RTMP流轉換為HTTP-FLV協議的流對外開放(端口8000)。通過Node-media-server建立一個流媒體服務步驟也很簡單,只需要如下代碼:
const NodeMediaServer = require('node-media-server');
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
allow_origin: '*'
}
};
const nms = new NodeMediaServer(config)
nms.run();
在Node-media-server中,提供了通過使用不用的URL路徑來對流進行區分。這里貼上一個官方提供的URL格式
rtmp://hostname:port/appname/stream
http://hostname:port/appname/stream.flv
例如對于音視頻流A,它的URL是這樣的: rtmp://47.110.88.142:1935/live/root_14465 可以看出對于這個流,appName這里被命名為了live, 而stream被命名為了root_14465。對應的,如果想通過HTTP-FLV進行拉這條流,可以通過下面這條URL: http://47.110.88.142:8000/live/root_14465.flv 在完成流媒體服務器的搭建后,不同用戶會生成對應不同的推流URL,只要為觀眾發放正確對應的拉流URL就會播放正確的流數據。實現了并行串流的目的。 本地演示:
通過Http-flv進行傳輸,瀏覽器的video標簽通過http獲取到flv流后,使用Flv.js【后文中介紹】進行轉換封包格式后為MP4后便能夠持續播放。
在實現過程中,我們用到了flv.js, 這是B站開源的一款媒體流轉碼插件,該插件能夠利用Js將接受到的HTTP-FLV實時轉碼為Video能夠接受的MP4格式。
得益于瀏覽器提供了Media Source Extensions API(MSE),使得flv.js能夠通過JavaScript來對流數據格式進行轉換,并分片為
這里我們貼一段flv.js的簡單的使用代碼
<script src="flv.min.js"></script>
<video id="videoElement"></video>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://example.com/flv/video.flv'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
MSE目前在PC端瀏覽器上支持較好,但是一些較低版本的移動端流覽器就不是那么理想了如圖:
由于Flv.js是基于MSE制作的,所以一些低版本移動端流覽器中是無法正常播放的,因此在考慮兼容性的情況下需要慎用。 關于WebRTC和音視頻會議 我們不難發現市場已經出現了一種新興的平臺 - Web視頻會議,用戶直接通過PC瀏覽器即可加入音視頻會議。
我們知道移動端的瀏覽器由于種類繁多并不能較好的適配,因此不被推薦直接在移動端瀏覽器中使用web視頻會議。
那讓我們從音視頻串流的角度來考慮,視頻會議就是讓傳統的單向直播變化為了雙向直播,即每個參與者即需要推流,也需要拉流。例如下圖,3位參會者,服務器就需要接受3條推流和6條拉流,顯然這樣對流媒體服務器的壓力過于龐大,并且還有不可忽視的延時問題。
大部分主流瀏覽器為開發者開放了可以開箱即用WebRTC - API,可以通過執行API就能呼叫指定的Peer并建立連接。但需要注意使用WebRTC技術雖然音視頻數據不經過服務端傳輸,但是仍然需要服務端去交換一些連接的必要信息。我們在開頭所說的兩款Web音視頻會議產品就是通過WebRTC實現的。
WebRTC更適合用來做Web視頻會議的原因就是它能夠實現瀏覽器和瀏覽器之間進行音視頻的傳輸
這其中的傳輸過程如圖。這里面的PeerN指的是連接的瀏覽器客戶端,在多個Peer連接之前,每個Peer需要和信令服務器(Signaling Server)進行連接,這里面提到的信令服務器需要由開發者自行搭建。 可以看到Peer與 信令服務器的連接是雙向的,這是因為連接的各方需要通過信令服務器交換一些關鍵信息,這些信息都會以信令的信息發送和接受。 Peer之間主要需要交換下面3種類型的信息
其中需要重點關注第二點,因為需要交換各個Peer之間的IP來進行Peer之間的連接,所以要保證Peer之間是要能夠正確訪問到對方ip的,如果所有的Peer都是在同一個局域網下沒有問題,但是如果參會的Peer來自不通的局域網,那么他們交換的IP是無法訪問到的。 所以在這里還需要增加一個借助另一種服務器(稱為STUN server)實現NAT/Firewall穿越。主要做的工作就是將用戶交換IP的過程中需要把根據局域網IP生成一個公網IP,這樣就實現了公網環境的傳輸。
我們在文章中了解了Web傳統的音視頻串流、初窺了新興的WebRTC技術,這兩項技術能力其實也對應著兩種不同的應用場景。前者輔以CDN更符合面向觀眾的直播場景,后者適合中小型的音視頻會議的場景,短期來看WebRTC無法代替傳統音視頻串流。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。