<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          音視頻通信為什么要選擇WebRTC?

          共 6596字,需瀏覽 14分鐘

           ·

          2022-02-09 17:34

          在網(wǎng)上經(jīng)常看到有人說:“在線教育直播是用WebRTC做的”,“音視頻會議是用WebRTC做的”......;“聲網(wǎng)、騰訊、阿里......都使用的WebRTC”。但你有沒有好奇,這些一線大廠為什么都要使用WebRTC呢?換句話說,WebRTC到底好在哪里呢?

          這個(gè)問題,對于長期做音視頻實(shí)時(shí)通信的老手來說是不言而喻的;但對于新手,則是急切想知道,而又很難得到答案的問題。那么本文我將采用對比法,向你詳細(xì)闡述一下WebRTC到底好在哪里。

          這次我們對比的指標(biāo)包括:性能、易用性、可維護(hù)性、流行性、代碼風(fēng)格等多個(gè)方面。不過,要做這樣的對比并非易事兒,首先要解決的難點(diǎn)是,目前市面上沒有一款與WebRTC接近或有相似功能的開源庫。這真成了無米之炊了!

          好在這點(diǎn)困難并難不倒我們,既然沒有與之可比較的開源庫,那我們就自己“造”一個(gè),用自研系統(tǒng)與WebRTC作比較。評估一下自研系統(tǒng)與基于WebRTC開發(fā)的音視頻客戶端,哪個(gè)成本更低、質(zhì)量更好。通過這樣的對比,相信能讓你更加了解WebRTC,知道其到底有多優(yōu)秀了。

          自研系統(tǒng)直播客戶端架構(gòu)

          首先我們先來了解一下自研直播客戶端的架構(gòu),其如(圖1)所示。這是一個(gè)最簡單的音視頻直播客戶端架構(gòu),通過這張架構(gòu)圖,你大體可以知道自研系統(tǒng)都要實(shí)現(xiàn)那些模塊了。

          (圖1)

          由(圖1)你可以知道,一個(gè)最簡單的直播客戶端至少應(yīng)該包括:音視頻采集模塊、音視頻編碼模塊、網(wǎng)絡(luò)傳輸模塊、音視頻解碼模塊和音視頻渲染模塊五大部分。

          • 音視頻采集模塊:該模塊調(diào)用系統(tǒng)的API,從麥克風(fēng)和攝像讀取設(shè)備采集到的音視頻數(shù)據(jù)。音頻采集的是PCM數(shù)據(jù),視頻采集的是YUV數(shù)據(jù)。
          • 音視頻編碼模塊:它負(fù)責(zé)將音視頻設(shè)備上采集的原始數(shù)據(jù)(PCM、YUV)進(jìn)行壓縮編碼。網(wǎng)
          • 絡(luò)傳輸模塊:該模塊負(fù)責(zé)將編碼后的數(shù)據(jù)生成RTP包,并通過網(wǎng)絡(luò)傳輸給對端;同時(shí),接收對端的RTP數(shù)據(jù)。
          • 音視頻解碼模塊:它將網(wǎng)絡(luò)模塊接收到的壓縮數(shù)據(jù)進(jìn)行解碼,還原回原始數(shù)據(jù)(PCM、YUV)。
          • 音視頻渲染渲染:拿到解碼后的數(shù)據(jù)后,該模塊將音頻輸出到揚(yáng)聲器,將視頻渲染到顯示器。

          通過前面的介紹,相信你一定覺得,自研一個(gè)直播客戶端好像也不是特別難的事兒。但實(shí)際上,上面介紹的音視頻直播客戶端架構(gòu)是極簡化的,甚至都不能稱之為直播客戶端架構(gòu),而只能稱它為示意圖。因?yàn)橐獙⑺優(yōu)檎鎸?shí)的、可商用的架構(gòu)還需要做不少的細(xì)化工作。

          拆分音視頻模塊

          接下來,咱們就對上面的直播客戶端架構(gòu)圖進(jìn)行逐步細(xì)化,細(xì)化的第一步就是拆分音視頻模塊。因?yàn)樵趯?shí)際開發(fā)中,音頻與視頻的處理是完全獨(dú)立的,它們有各自的處理方式。如音頻有獨(dú)立的采集設(shè)備(聲卡),獨(dú)立的播放設(shè)備(揚(yáng)聲器)、訪問音頻設(shè)備的系統(tǒng)API等,另外,音頻還有多種音頻編解碼器,如Opus、AAC、iLBC等;同樣,視頻也有自己獨(dú)立的采集設(shè)備(攝像頭)、渲染設(shè)備(顯示器)、各種視頻編碼器,如H264、VP8等。細(xì)化后的直播客戶端架構(gòu)如(圖2)所示。

          (圖2)

          從(圖2)中你可以看到,細(xì)化后的架構(gòu)中,音頻的采集模塊與視頻的采集模塊是分開的,而音頻編解碼模塊與視頻的編解碼模塊也都是分開的。也就是說,音頻是一條處理流程,視頻是另外一條處理流程,它們之間并不相交。在音視頻處理中,我們一般稱每一路音頻或每一路視頻為一條軌。

          除此之外,你還可以知道,自研音視頻直播客戶端要實(shí)現(xiàn)的模塊遠(yuǎn)不止5個(gè),至少應(yīng)該包括:音頻采集模塊、視頻采集模塊、音頻編碼/音頻解碼模塊、視頻編碼/視頻解碼模塊、網(wǎng)絡(luò)傳輸模塊、音頻播放模塊以及視頻渲染7個(gè)模塊。

          跨平臺

          實(shí)現(xiàn)音視頻直播客戶端除了要實(shí)現(xiàn)上面介紹的7個(gè)模塊外,還要考慮跨平臺的問題,只有在各個(gè)平臺上都能實(shí)現(xiàn)音視頻的互聯(lián)互通,才能稱得上是一個(gè)合格的音視頻直播客戶端。所以它至少應(yīng)該實(shí)現(xiàn)Windows端、Mac端、Android端以及iOS四個(gè)終端,當(dāng)然如果還能夠支持Linux端和瀏覽器則是再好不過的了。

          你要知道的是,如果不借助WebRTC,想在瀏覽器上實(shí)現(xiàn)音視頻實(shí)時(shí)互通,難度是非常大的,這是自研系統(tǒng)的一大缺陷。除了與瀏覽器互通外,其它幾個(gè)終端實(shí)現(xiàn)互通倒是相對較容易的事兒。

          增加跨平臺后,音視頻直播客戶端的架構(gòu)要較之前復(fù)雜得多了,其如(圖3)所示。從這張圖中你可以看到,要實(shí)現(xiàn)跨平臺,難度最大、首當(dāng)其沖的,是訪問硬件設(shè)備的模塊,如音頻采集模塊、音頻播放模塊、視頻采集模塊以及視頻播放模塊等,它們在架構(gòu)中的變化是最大的。

          (圖3)

          以音頻采集為例,在不同的平臺上,采集音頻數(shù)據(jù)時(shí)使用的API是完全不一樣的。PC端使用的是CoreAudio系列的API;巧合的是,Mac端用于采集音頻的系統(tǒng)API也稱為CoreAudio,不過具體的函數(shù)名肯定是不同的;在Android端,它為采集音視頻提供的API稱之為AudioRecord;iOS端,使用AudioUnit來采集音頻數(shù)據(jù);而Linux端,則使用PulseAudio采集音頻數(shù)據(jù)。

          總之,每個(gè)終端都有各自采集音視頻數(shù)據(jù)的API。由于不同的系統(tǒng),其API設(shè)計(jì)的架構(gòu)也不同,所以在使用這些API時(shí),調(diào)用的方式和使用的邏輯也千差萬別。因此,在開發(fā)這部分模塊時(shí),其工作量是巨大的。

          插件化管理

          對于音視頻直播客戶端來說,我們不但希望它可以處理音頻數(shù)據(jù)、視頻數(shù)據(jù),而且還希望它可以分享屏幕、播放多媒體文件、共享白板......此外,既使是處理音視頻,我們也希望它可以支持多種編解碼格式,如音頻除了可以支持Opus、AAC外,還可以支持G.711/G.722、iLBC、speex等;視頻除了可能支持H264外,還可以支持H265、VP8、VP9、AV1等,這樣它才能應(yīng)用的更廣泛。

          實(shí)際上,這些音視頻編解碼器都有各自的優(yōu)缺點(diǎn),也有各自適用的范圍。比如G.711/G.722主要用于電話系統(tǒng),音視頻直播客戶端要想與電話系統(tǒng)對接,就要支持這種編解碼格式;Opus主要用于實(shí)時(shí)通話;AAC主要應(yīng)用于音樂類的應(yīng)用,如鋼琴教學(xué)等。所以,我們希望直播客戶端能夠支持盡可能多的編解碼器,這樣的直播客戶端才足夠強(qiáng)大。

          如何才能做到這一點(diǎn)呢?最好的設(shè)計(jì)方案就是實(shí)現(xiàn)插件化管理。當(dāng)你需要支持某個(gè)功能時(shí),直接編寫一個(gè)插件放上去即可;當(dāng)不需要的時(shí)候,可以隨時(shí)將插件拿下來,這樣的設(shè)計(jì)方案靈活、安全、可靠。

          (圖4)

          為了讓直播客戶端支持插件化管理,我對之前的架構(gòu)圖又做了調(diào)整。如(圖4)所示。從中你可以看到,為了支持插件化管理,我將原來架構(gòu)圖中的音視頻編解碼器換成音視頻編解碼插件管理器,而各種音視頻編解碼器(Opus、AAC、iLBC......)都可以作為一個(gè)插件注冊到其中。當(dāng)你想使用某種類型的編碼器時(shí),可以通過參數(shù)進(jìn)行控制,這樣從音視頻采集模塊采集到的數(shù)據(jù)就會被送往對應(yīng)的編碼器進(jìn)行編碼;當(dāng)接收接收到RTP格式的音視頻數(shù)據(jù)時(shí),又可以根據(jù)RTP頭中的Payload Type來區(qū)分,將數(shù)據(jù)交由對應(yīng)的解碼器進(jìn)行解碼。經(jīng)這樣處理后,咱們的音視頻直播客戶端的功能就更強(qiáng)大了,應(yīng)用范圍也更廣了。

          這里我以音頻編解碼器為例,簡要的向你介紹一下直播客戶端增加插件管理前后的區(qū)別。客戶端在增加插件管理之前,它只能使用一種音頻編解碼器,如Opus。因此,在一場直播活動中,所有參與直播的終端都只能使用同一種音頻的編解碼器(Opus)。這樣看起來貌似也不會產(chǎn)生什么問題,是吧?不過,假如此時(shí),我們想將一路電話語音接入到這場直播中(電話語音使用的編解碼器為G.711/G.722),它就無能為力了;而有了插件管理情況就不同了,各終端可以根據(jù)接收到的音頻數(shù)據(jù)類型調(diào)用不同的音頻解碼器進(jìn)行解碼,從而實(shí)現(xiàn)不同編解碼器在同一場直播中互通的場景,這就是插件化管理給我們帶來的好處。

          服務(wù)質(zhì)量

          除了上面我介紹的幾點(diǎn)外,要實(shí)現(xiàn)一個(gè)功能強(qiáng)大的、性能優(yōu)越的、應(yīng)用廣泛的音視頻直播客戶端還有很多的工作要做,尤其將服務(wù)質(zhì)量是大家特別關(guān)心的。如果直播客戶端不能提供好的服務(wù)質(zhì)量,那它就失去了商業(yè)價(jià)值。

          實(shí)時(shí)通信中的服務(wù)質(zhì)量指的是什么呢?它主要包括三個(gè)方面,一是通信時(shí)延小;二是同等網(wǎng)路條件下視頻更清晰、流暢;三是同等網(wǎng)絡(luò)條件下語音失真小。如何才能保障通信時(shí)延小、視頻清晰、語音不失真呢?

          這里的關(guān)鍵是網(wǎng)絡(luò)。如果直播客戶端可以保障用戶有一條非常好的網(wǎng)絡(luò)線路,在這條線路上傳輸?shù)臅r(shí)延最小、不丟包、不亂序,那我們的音視頻服務(wù)質(zhì)量自然就上去了,對吧!

          但我們都知道,網(wǎng)絡(luò)的問題是最難解決的。出現(xiàn)丟包、抖動、亂序更是家常便飯。有的同學(xué)可以會說 TCP 不是已經(jīng)解決了丟包、亂序這些問題嗎?確實(shí)是,但它是以犧牲時(shí)延為代價(jià)的。當(dāng)我們的網(wǎng)絡(luò)比較優(yōu)質(zhì)時(shí),TCP/UDP都可以用于實(shí)時(shí)傳輸,但大多數(shù)情況下,我們首選UDP,原因是在弱網(wǎng)環(huán)境下使用TCP會產(chǎn)生極大的延時(shí)。

          要想弄清楚TCP為什么在弱網(wǎng)環(huán)境下會產(chǎn)生極大的延時(shí),就要介紹一點(diǎn)TCP的機(jī)制的了。TCP為了保證不丟包,不亂序,采用了發(fā)送、確認(rèn)、丟包、重傳的機(jī)制。正常情況下,數(shù)據(jù)從一端傳輸?shù)搅硪欢耸菦]有任何問題的,但當(dāng)出現(xiàn)丟包時(shí)就會有較大的麻煩。如圖所示。

          (圖5)

          圖中顯示了多次丟包時(shí)的延遲情況:從客戶端向服務(wù)端發(fā)送數(shù)據(jù)包,服務(wù)端需要返回ACK消息進(jìn)行確認(rèn); 客戶端收到確認(rèn)消息后, 才能繼續(xù)發(fā)送后面的數(shù)據(jù)(有滑窗時(shí)也是類似的)。每次客戶端發(fā)完數(shù)據(jù)后,都會啟動一個(gè)定時(shí)器,定時(shí)器的最短超時(shí)時(shí)間是200ms。如果因某種原因,在200毫秒客戶端沒有收到返回的ACK包,客戶端會重發(fā)上一個(gè)包。由于TCP有退避機(jī)制,以防止頻繁發(fā)送丟失的包,因此會將重發(fā)包的超時(shí)時(shí)間延長到400ms。如果重發(fā)包依然沒有收到確認(rèn)消息,則下一次重發(fā)的超時(shí)時(shí)間會延長到800ms。我們可以看到,連續(xù)幾次丟包后,就會產(chǎn)生非常大的延遲,這就是TCP在弱網(wǎng)環(huán)境下不能使用的根本原因。

          根據(jù)實(shí)時(shí)通信指標(biāo),超過 500ms 就不能稱為實(shí)時(shí)通信了,因此在弱網(wǎng)情況下,絕對不能使用TCP協(xié)議。實(shí)時(shí)通信的指標(biāo)如(圖6)所示。

          (圖6)

          通過(圖6)中的表格可以看到,如果端到端延遲在200ms以內(nèi),說明整個(gè)通話是優(yōu)質(zhì)的,通話效果就像大家在同一個(gè)房間里聊天一樣;300ms以內(nèi),大多數(shù)人很滿意,400ms以內(nèi),有小部分人可以感覺到延遲,但互動基本不受影響;500ms以上時(shí),延遲會明顯影響互動,大部分人都不滿意。所以最關(guān)鍵的一點(diǎn)是500ms,只有延遲低于500ms,才可以說是合格的實(shí)時(shí)互動系統(tǒng)。

          通過上面的描述我們可以知道,如果我們想在自己的直播客戶端中實(shí)現(xiàn)好的服務(wù)質(zhì)量,任務(wù)還是非常艱巨的。當(dāng)然,除了上面要實(shí)現(xiàn)的功能外,還有其它很多需要處理的細(xì)節(jié)。

          其它

          音視頻不同步問題。音視頻數(shù)據(jù)經(jīng)網(wǎng)絡(luò)傳輸后,由于網(wǎng)絡(luò)抖動和延遲等問題,很可能造成音視頻不同步。因此,你在實(shí)現(xiàn)音視頻直播客戶端時(shí),需要增加音視頻同步模塊以保障音視頻的同步。

          回音問題。回音問題指的是,自己與其它人進(jìn)行實(shí)時(shí)互動時(shí),可以聽到自己的回聲。在實(shí)時(shí)音視頻通信中,不光有回音問題,還有噪音、聲音過小等問題,我們將它們統(tǒng)稱為3A問題。這些問題都是非常棘手的。目前開源的項(xiàng)目中,只有WebRTC和Speex有開源的回音消除算法,而且WebRTC的回音消除算法還是目前世界上最頂級的。

          音視頻的實(shí)時(shí)性問題。要進(jìn)行實(shí)時(shí)通信,網(wǎng)絡(luò)質(zhì)量尤為關(guān)鍵。但你應(yīng)該也清楚,網(wǎng)絡(luò)的物理層是很難保障網(wǎng)絡(luò)服務(wù)質(zhì)量的,必須在軟件層加以控制才行。雖然大家常用的TCP協(xié)議有一套完整的保障網(wǎng)絡(luò)質(zhì)量的方案,但它在實(shí)時(shí)性方面表現(xiàn)不佳。換句話說,TCP是以犧牲實(shí)時(shí)性來保障網(wǎng)絡(luò)服務(wù)質(zhì)量的,而實(shí)時(shí)性又是音視頻實(shí)時(shí)通信的命脈,這就導(dǎo)致TCP協(xié)議不能作為音視頻實(shí)時(shí)傳輸?shù)淖罴堰x擇了。因此,為了保證實(shí)時(shí)性,一般情況下實(shí)時(shí)直播應(yīng)該首選UDP協(xié)議。但這樣一來,我們就必須自己編寫網(wǎng)絡(luò)控制算法以保證網(wǎng)絡(luò)質(zhì)量了。

          此外,還有網(wǎng)絡(luò)擁塞、丟包、延時(shí)、抖動、混音......不勝枚舉。可以說,要實(shí)現(xiàn)一個(gè)實(shí)時(shí)的音視頻直播客戶端有許許多多的問題要解決,這里我就不一一列舉了。總之,通過上面的描述,我想你已經(jīng)清楚要自己研發(fā)一套音視頻直播客戶端到底有多難了。

          WebRTC客戶端架構(gòu)

          實(shí)際上,在直播客戶端架構(gòu)一節(jié)我講的所有功能,WebRTC都已經(jīng)實(shí)現(xiàn)了。下面讓我們看一下WebRTC架構(gòu)圖吧,如(圖)所示。

          (圖7)

          從WebRTC架構(gòu)圖中你可以了解到,它大體上可以分成四層:即接口層、Session層、核心引擎層和設(shè)備層。下面我就向你簡要的介紹一下每一層的作用。

          接口層包括兩部分,一是Web層接口;二是Native層接口。也就是說,你既可以使用瀏覽器開發(fā)音視頻直播客戶端,也可以使用Native(C++、Android、OC等)開發(fā)音視頻直播客戶端。

          Session層的主要作用是控制業(yè)務(wù)邏輯,如媒體協(xié)商、收集Candidate等,這些操作都是在Session層處理的;

          核心引擎層包括的內(nèi)容就比較多了。從大的方面說,它包括音頻引擎、視頻引擎和網(wǎng)絡(luò)傳輸層。音頻引擎層包括NetEQ、音頻編解碼器(如OPUS、iLBC)、3A等。視頻引擎包括JitterBuffer、視頻編解碼器(VP8/VP9/H264)等。網(wǎng)絡(luò)傳輸層包括SRTP、網(wǎng)絡(luò)I/O多路復(fù)用、P2P等。以上這些內(nèi)容中,本書重點(diǎn)介紹了網(wǎng)絡(luò)相關(guān)的內(nèi)容,它們分布在第三章音視頻實(shí)時(shí)通信的本質(zhì)、第六章WebRTC中的ICE實(shí)現(xiàn)、第九章RTP/RTCP協(xié)議詳解、第十章WebRTC擁塞控制等幾個(gè)章節(jié)中,由于篇幅的原因,其它內(nèi)容我會陸續(xù)發(fā)布在我的個(gè)人主站avdancedu.com上。

          設(shè)備層主要與硬件打交道,它涉及的內(nèi)容包括:在各終端設(shè)備上進(jìn)行音頻的采集與播放、視頻的采集以及網(wǎng)絡(luò)層等。這部分內(nèi)容會在本書的最后一章 \textbf{WebRTC源碼分析}中做詳細(xì)介紹。

          從上面的描述中你可以看到,在WebRTC架構(gòu)的四層中,最復(fù)雜、最核心的是第三層,即引擎層,因此,這里我再對引擎層內(nèi)部的關(guān)系做下簡要介紹。引擎層包括三部分內(nèi)容,分別是:音頻引擎、視頻引擎以及網(wǎng)絡(luò)傳輸。其中音視引擎和視頻引擎是相對比較獨(dú)立的。不過,它們都需要與網(wǎng)絡(luò)傳輸層(transport)打交道。也就是說,它們都需要將自己產(chǎn)生的數(shù)據(jù)通過網(wǎng)絡(luò)傳輸層發(fā)送出去;同時(shí),也需要通過網(wǎng)絡(luò)傳輸層接收其它端發(fā)過來的數(shù)據(jù)。此外,音頻引擎與視頻引擎由于要進(jìn)行音視頻同步的原因,所以它們之間也存在著關(guān)聯(lián)關(guān)系。

          (圖8)

          最后,我們再次以音頻為例(如圖8所示),來看一下WebRTC中的數(shù)據(jù)流是如何流轉(zhuǎn)的吧。當(dāng)WebRTC作為發(fā)送端時(shí),它通過音頻設(shè)備采集到音頻數(shù)據(jù)后,先要進(jìn)行3A處理,處理后的數(shù)據(jù)交由音頻編碼器編碼,編碼后由網(wǎng)絡(luò)傳輸層將數(shù)據(jù)發(fā)送出去;另一方面,當(dāng)網(wǎng)絡(luò)傳輸層收到數(shù)據(jù)后,它要判斷數(shù)據(jù)的類型是什么,如果是音頻,它會將數(shù)據(jù)交給音頻引擎模塊處理,數(shù)據(jù)首先被放入到NetEQ模塊做平滑處理及音頻補(bǔ)償處理,之后進(jìn)行音頻解碼,最終將解碼后的數(shù)據(jù)通過揚(yáng)聲器播放出來。視頻的處理流程與音頻的處理流程是類似的,這里我就不再贅述了。

          小結(jié)

          通過上面對自研音視頻客戶端架構(gòu)的描述以及WebRTC客戶端架構(gòu)的描述,相信在你心中,對WebRTC的優(yōu)勢已經(jīng)非常清楚了。下面我再從性能、跨平臺、音視頻服務(wù)質(zhì)量、穩(wěn)定性等幾個(gè)方面對兩者做一下總結(jié)。如(圖9)所示:

          (圖9)

          (圖9)告訴我們,WebRTC在實(shí)時(shí)音視頻直播方面的優(yōu)勢是不言而喻的,又有Google的強(qiáng)大支持,這就是為什么大家都選擇WebRTC的真正原因了。


          我的視頻課

          WebRTC實(shí)時(shí)互動直播技術(shù)入門與實(shí)戰(zhàn) 5G時(shí)代必備技能 (戳鏈接直達(dá)課程)

          百萬級高并發(fā)WebRTC流媒體服務(wù)器設(shè)計(jì)與開發(fā) (戳鏈接直達(dá)課程)

          編程必備基礎(chǔ)-音視頻小白系統(tǒng)入門課 (戳鏈接直達(dá)課程)

          OpenCV入門到進(jìn)階:實(shí)戰(zhàn)三大典型項(xiàng)目 (戳鏈接直達(dá)課程)

          經(jīng)典再升級-FFmpeg音視頻核心技術(shù)全面精講+實(shí)戰(zhàn) (戳鏈接直達(dá)課程)


          我的新書

          ★本書深入淺出地對WebRTC技術(shù)進(jìn)行了系統(tǒng)講解,既有原理又有實(shí)戰(zhàn),從WebRTC是如何實(shí)現(xiàn)實(shí)時(shí)音視頻通信的,到如何應(yīng)用WebRTC庫實(shí)現(xiàn)音視頻通信,再到WebRTC源碼的剖析,逐步展開講解。此外,對WebRTC的傳輸系統(tǒng)進(jìn)行了重點(diǎn)分析,相信讀者通過本書可以一窺WebRTC傳輸?shù)膴W秘。

          瀏覽 36
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  999欧美精选 | 夜夜夜久久久 | 亚洲精品成人无码AV在线 | 日本成人中文字幕 | 天天色狠狠伊人 |