欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

搞音視頻開發(fā)好些年,分享過許多博客文章,比如:前幾年發(fā)布的《FFmpeg Tips》系列,《Android 音頻開發(fā)》系列,《直播疑難雜癥排查》系列等等。最近想把多年來開發(fā)和優(yōu)化播放器的經(jīng)驗(yàn)也分享出來,同時也考慮把自己業(yè)余時間開發(fā)的基于 ffmpeg 的播放器內(nèi)核開源出來,希望能幫助到音視頻領(lǐng)域的初學(xué)者。第一期文章要推出的內(nèi)容主要涉及到播放器比較核心的幾個技術(shù)點(diǎn),大概的目錄如下:

創(chuàng)新互聯(lián)公司專注于景洪網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供景洪營銷型網(wǎng)站建設(shè),景洪網(wǎng)站制作、景洪網(wǎng)頁設(shè)計(jì)、景洪網(wǎng)站官網(wǎng)定制、小程序定制開發(fā)服務(wù),打造景洪網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供景洪網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

  1. 播放器技術(shù)分享(1): 架構(gòu)設(shè)計(jì)

  2. 播放器技術(shù)分享(2):緩沖區(qū)管理

  3. 播放器技術(shù)分享(3):音畫同步

  4. 播放器技術(shù)分享(4):首開時間

  5. 播放器技術(shù)分享(5):延時優(yōu)化

本篇是系列文章的第一篇,主要聊一聊播放器的架構(gòu)設(shè)計(jì)。

1 概述


首先,我們了解一下播放器的定義是什么 ?

“播放器,是指能播放以數(shù)字信號形式存儲的視頻或音頻文件的軟件,也指具有播放視頻或音頻文件功能的電子器件產(chǎn)品。”  —— 《百度百科》


我的解讀如下:“播放器,是指能讀取、解析、渲染存儲在本地或者服務(wù)器上的音視頻文件的軟件,或者電子產(chǎn)品。”

歸納起來,它主要有如下 3 個方面的功能特性:

  1. 讀取(IO):“獲取” 內(nèi)容  -> 從 “本地” or “服務(wù)器” 上獲取

  2. 解析(Parser):“理解” 內(nèi)容  -> 參考 “格式&協(xié)議” 來 “理解” 內(nèi)容

  3. 渲染(Render):“展示” 內(nèi)容  -> 通過揚(yáng)聲器/屏幕來 “展示” 內(nèi)容

把這 3 個方面的功能串起來,就構(gòu)成了整個播放器的數(shù)據(jù)流,如圖所示:播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

IO:負(fù)責(zé)數(shù)據(jù)的讀取。從數(shù)據(jù)源讀取數(shù)據(jù)有多種標(biāo)準(zhǔn)協(xié)議,比如常見的有:File,HTTP(s),RTMP,RTSP 等

Parser & Demuxer:負(fù)責(zé)數(shù)據(jù)的解析。音視頻數(shù)據(jù)的封裝格式,都有著各種業(yè)界標(biāo)準(zhǔn),只需要參考這些行業(yè)標(biāo)準(zhǔn)文檔,即可解析各種封裝格式,比如常見的格式:mp4,flv,m3u8,avi 等

Decoder:其實(shí)也屬于數(shù)據(jù)解析的一種,只不過更多的是負(fù)責(zé)對壓縮的音視頻數(shù)據(jù)進(jìn)行解碼,拿到原始的 YUV 和 PCM 數(shù)據(jù),常見的視頻壓縮格式如:H.264、MPEG4、VP8/VP9,音頻壓縮格式如 G.711、AAC、Speex 等

Render:負(fù)責(zé)視頻數(shù)據(jù)的繪制和渲染,是一個平臺相關(guān)的特性,不同的平臺有不同的渲染 API 和方法,比如:Windows 的 DDraw/DirectSound,Android 的 SurfaceView/AudioTrack,跨平臺的如:OpenGL 和 ALSA 等

下面我們逐一剖析一下播放器整個數(shù)據(jù)流的每一個模塊的輸入和輸出,并一起設(shè)計(jì)一下每一個模塊的接口 API。

2 模塊設(shè)計(jì)


2.1 IO 模塊

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

IO 模塊的輸入:數(shù)據(jù)源的地址(URL),這個 URL 可以是一個本地的文件路徑,也可以是一個網(wǎng)絡(luò)的流地址。

IO 模塊的輸出:二進(jìn)制的數(shù)據(jù),即通過 IO 協(xié)議讀取的音視頻二進(jìn)制數(shù)據(jù)。

視頻數(shù)據(jù)源的 URL 示例如下:

file:///c:/WINDOWS/clock.avi

rtmp://live.hkstv.hk.lxDNS.com/live/hks

http://www.w3school.com.cn/i/movie.mp4

http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8

綜上,播放器 IO 模塊的接口設(shè)計(jì)如下所示:

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

Open/Close 方法主要是用于打開/關(guān)閉視頻流,播放器內(nèi)核可以通過 URL 的頭(Schemes)知道需要采用哪一種 IO 協(xié)議來拉流(如:FILE/RTMP/HTTP),然后通過繼承本接口的子類去完成實(shí)際的協(xié)議解析和數(shù)據(jù)讀取。

IO 模塊讀取數(shù)據(jù),則定義了 2 個方法,Read 方法用于順序讀取數(shù)據(jù),ReadAt 用于從指定的 Offset 偏移的位置讀取數(shù)據(jù),后者主要用于文件或者視頻點(diǎn)播,為播放器提供 Seek 能力。

對于網(wǎng)絡(luò)流,可能出現(xiàn)斷線的情況,因此獨(dú)立出一個 Reconnect 接口,用于提供重連的能力。

2.2 解析模塊

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

從 IO 模塊讀到的音視頻二進(jìn)制數(shù)據(jù),其實(shí)都是用如 mp4、flv、avi 等格式封裝起來的,如果想分離出音頻包和視頻包,則需要通過一個 Parser & Demuxer 模塊進(jìn)行解析。

解析模塊的輸入:由 IO 模塊讀取出來的 bytes 二進(jìn)制數(shù)據(jù)

解析模塊的輸出:音視頻的媒體信息,未解碼的音頻數(shù)據(jù)包,未解碼的視頻數(shù)據(jù)包

音視頻的媒體信息主要包括如下內(nèi)容:

  • 視頻時長、碼率、幀率等?    

  • 音頻的格式:編碼算法,采樣率,通道數(shù)等?    

  • 視頻的格式:編碼算法,寬高,長寬比等

綜上,解析模塊的接口設(shè)計(jì)如下圖所示:

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

創(chuàng)建好解析對象后,通過 Parse 函數(shù)輸入音視頻數(shù)據(jù)解析出基本的音視頻媒體信息,通過 Read 函數(shù)讀取分離的音視頻數(shù)據(jù)包,然后分別送入音頻和視頻×××,通過 Get 方法獲取各種音視頻參數(shù)信息。

2.3 解碼模塊

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

解析模塊分離好音頻和視頻包以后,就可以分配送入到音頻×××和視頻×××了

解碼模塊的輸入:未解壓的音頻/視頻包

解碼模塊的輸出:解壓好的音頻/圖像的原始數(shù)據(jù),即 PCM 和 YUV

由于音視頻的解碼,往往不是每送入×××一幀數(shù)據(jù)就一定能輸出一幀數(shù)據(jù),而是經(jīng)常需要緩存幾幀參考幀才能拿到輸出,所以編碼器的接口設(shè)計(jì)常常采用一種 “生產(chǎn)者-消費(fèi)者” 模型,通過一個公共的 buffer 隊(duì)列來串聯(lián) “生產(chǎn)者-消費(fèi)者”,如下圖所述(截取自 Android MediaCodec 編解碼庫的設(shè)計(jì)):

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

綜上,解碼模塊的接口設(shè)計(jì)如下所示:

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

解析模塊輸出的媒體信息,包含有該使用什么類型的音頻/視頻×××,可利用該信息完成×××的初始化。剩下的過程,就是通過 Queue 和 Dequeue 不斷跟×××交互,送入未解碼的數(shù)據(jù),拿到解碼后的數(shù)據(jù)了。

2.4 渲染模塊

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)


×××輸出原始的圖像和音頻數(shù)據(jù)后,下一步就是送入到渲染模塊進(jìn)行圖像的渲染和音頻的播放了。

一般視頻數(shù)據(jù)渲染是輸出到顯卡展示在窗口上,音頻數(shù)據(jù)則是送入聲卡利用揚(yáng)聲器播放出來。雖然不同平臺的窗口繪制和揚(yáng)聲器播放的系統(tǒng)層 API 都不太一樣,但是接口層面的流程也都差不多,如圖所示:

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

對于視頻渲染而言,流程則是:Init 初始化 -> SetView 設(shè)置窗口對象 -> SetParam 設(shè)置渲染參數(shù) -> Render 執(zhí)行渲染/繪制

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

對于音頻播放而言,流程則是:Init 初始化 -> SetParam 設(shè)置播放參數(shù) -> Render 執(zhí)行播放操作

2.5 把模塊串起來

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

如圖所示,把各個模塊這樣串起來后,就是播放器的整個數(shù)據(jù)流走向了,但這是一個單線程的結(jié)構(gòu),從 IO 讀到數(shù)據(jù)后,立馬送入解析 -> 解碼 -> 渲染,這樣的單線程結(jié)構(gòu)的播放器設(shè)計(jì),會存在如下幾個問題:

  1. 音視頻分離后 -> 解碼 -> 播放,中間無法插入邏輯進(jìn)行音畫同步

  2. 無數(shù)據(jù)緩沖區(qū),一旦網(wǎng)絡(luò)/解碼抖動 -> 導(dǎo)致頻繁的卡頓

  3. 單線程運(yùn)行,沒有充分利用 CPU 多核

要想解決單線程結(jié)構(gòu)的問題,可以以數(shù)據(jù)的 “生產(chǎn)者 - 消費(fèi)者” 為邊界,添加數(shù)據(jù)緩沖區(qū),將單線程模型,改造為多線程模型(IO 線程、解碼線程、渲染線程),如圖所示:播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

改造為多線程模型后,其優(yōu)勢如下:

  1. 幀隊(duì)列(Packet Queue):可抵抗網(wǎng)絡(luò)抖動

  2. 顯示隊(duì)列(Frame Queue):可抵抗解碼/渲染的抖動

  3. 渲染線程:添加 AV Sync 邏輯,可支持音畫同步的處理

  4. 并行工作,高效,充分利用多核 CPU

注:我們將在下一篇文章專門來聊一聊這 2 個新增的緩沖區(qū)該如何設(shè)計(jì)和管理。

3 播放器 SDK 接口設(shè)計(jì)


前面詳細(xì)介紹了播放器內(nèi)涵的關(guān)鍵架構(gòu)設(shè)計(jì)和數(shù)據(jù)流,如果期望以該播放器內(nèi)核作為 SDK 給 APP 提供底層能力的話,還需要設(shè)計(jì)一套易用的 API 接口,這套 API 接口,其實(shí)可抽象為如下 5 大部分:

  1. 創(chuàng)建/銷毀播放器

  2. 配置參數(shù)(如:窗口句柄、視頻 URL、循環(huán)播放等)

  3. 發(fā)送命令(如:初始化,開始播放,暫停播放,拖動,停止等)

  4. 音視頻數(shù)據(jù)回調(diào)(如:解碼后的音視頻數(shù)據(jù)回調(diào))

  5. 消息/狀態(tài)消息回調(diào)(如:緩沖開始/結(jié)束、播放完成等)

綜上,播放器常見接口列表如下:

  1. Create/Release/Reset

  2. SetDataSource/SetOptions/SetView/SetVolume

  3. Prepare/Start/Pause/Stop/SeekTo

  4. SetXXXListener/OnXXXCallback


4 播放器的狀態(tài)模型


總體來說,播放器其實(shí)是一個狀態(tài)機(jī),被創(chuàng)建出來了以后,會根據(jù)應(yīng)用層發(fā)送給它的命令以及自身產(chǎn)生的事件在各個狀態(tài)之間切換,可以用如下這張圖來展示:

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

播放器一共有 9 種狀態(tài),其中,Idle 是創(chuàng)建后/重置后的到達(dá)的初始狀態(tài),End 和 Error 分別是主動銷毀播放器和發(fā)生錯誤后進(jìn)入的最終狀態(tài)(通過 reset 重置后可恢復(fù) Idle 狀態(tài))

其他的狀態(tài)切換和達(dá)到方式,圖中已經(jīng)標(biāo)注得比較清楚了,這里就不再贅述了。

5 總結(jié)


播放器的架構(gòu)設(shè)計(jì),就分享到這里了,有些內(nèi)容沒有展開講,但比較關(guān)鍵的點(diǎn)應(yīng)該都基本闡述清楚了,如有疑問的小伙伴歡迎來信 lujun.hust@gmail.com 交流。另外,也歡迎大家關(guān)注我的新浪微博 @盧_俊 或者 微信公眾號 @Jhuster 獲取最新的文章和資訊。

播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

網(wǎng)站標(biāo)題:播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)
網(wǎng)站網(wǎng)址:http://chinadenli.net/article30/gogoso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站外貿(mào)網(wǎng)站建設(shè)面包屑導(dǎo)航定制開發(fā)營銷型網(wǎng)站建設(shè)定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)