整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          WSL的WebRTC開發(fā)環(huán)境(四)

          WebRTC(Web Real-Time Communication,網(wǎng)頁即時通信),是一個支持網(wǎng)頁瀏覽器進行實時語音對話或視頻對話的技術,目的是無插件實現(xiàn)web端的實時通信的能力。WebRTC提供了視頻會議的核心技術,包括音視頻的采集、編解碼、網(wǎng)絡傳輸、展示等功能,并且還支持跨平臺,包括linux、windows、mac、android等。


          WebRTC

          2010 年 Google 以 6820 萬美元收購 VoIP 軟件開發(fā)商 Global IP Solutions 的 GIPS 引擎,在經(jīng)過收購之后沒多久,Google 將該引擎改名為“WebRTC”,并宣布向開發(fā)者們開源了源代碼。

          2012 年,Google 將 WebRTC 集成到 Chrome 瀏覽器中。隨后, Mozilla、Opera、Ericsson 等 PC 瀏覽器以及手機瀏覽器均開始支持 WebRTC 技術。

          2017 年,蘋果在 WWDC17 上正式宣布其瀏覽器內(nèi)核 WebKit 也正式支持 WebRTC。

          基于 Chromium 的新版 Edge 現(xiàn)在可在預覽版中使用。新版本的 Edge 提供了 WebRTC 開發(fā)者常用的許多功能,如支持數(shù)據(jù)通道、RTCPeerConnection 中的 Strem、VP9 編解碼器和 MediaStream Recording。

          在 Discord、Google Hangouts 和 Facebook Messenger 等一些國內(nèi)的多媒體網(wǎng)絡應用中,也都需要 WebRTC 才能實現(xiàn)。

          但是,WebRTC 的發(fā)展還面臨著諸多的挑戰(zhàn):

          瀏覽器面臨的主要挑戰(zhàn)是完成 WebRTC 1.0 API 的實現(xiàn),以及消除實現(xiàn)差異。WebRTC API 在其歷史中經(jīng)歷了三次主要迭代,需要實現(xiàn)互操作性、改進測試覆蓋率等方面的標準。W3C 在實現(xiàn)這一目標方面一直在穩(wěn)步前進,但還未成熟。

          前實時音視頻通信領域,也并不只有 WebRTC 一種可供選擇的技術,專有的自研協(xié)議和 WebRTC 的互操作性通常使用網(wǎng)關實現(xiàn)。

          WebRTC協(xié)議介紹:https://www.cnblogs.com/SingleCat/p/11315349.html

          基于Webrtc、Kurento的一種低延遲架構(gòu)實現(xiàn):https://www.jianshu.com/p/ac307371def4

          WebRTC的開源實現(xiàn):

          1、Jitsi Videobridge

          Jitsi是一個SFU開源框架,由Atlassian維護,被集成到HipChat中。

          Jitsi是一個處理XMPP信號流的SFU,適用于SIP/XMPP視頻通話,會議,聊天,桌面共享,文件傳輸。如果你不需要SFU或者使用其他信號協(xié)議,最好還是使用其他項目。但由于Jitsi項目的簡單明了,很多外包供應商很喜歡使用Jitsi,將它集成到自己的項目案例當中。

          Github項目地址:https://github.com/jitsi/jitsi

          2、Kurento

          Kurento 是一個 WebRTC 流媒體服務器以及一些客戶端API,可以實現(xiàn)webrtc mcu、sfu等功能。2016年被Twilio收購,Kurento目前推進到6.13版本。nubomedia 開源框架是基于kurento開發(fā)的官方paas 平臺,提高了穩(wěn)定性,但是并不推薦學習使用。它可以實現(xiàn)的功能包括

          • 網(wǎng)絡流媒體協(xié)議,包括HTTP、RTP和WebRTC
          • 群組通信(group communications,包括MCU和SFU功能),支持媒體流的轉(zhuǎn)碼、錄制、廣播、路由、混流。
          • 高級媒體處理特性,包括:機器視覺、視頻索引、增強現(xiàn)實、語音分析。
          • Media storage that supports writing operations for WebM and MP4 and playing in all formats supported by GStreamer.
          • Automatic media transcoding between any of the codecs supported by GStreamer, including VP8, H.264, H.263, AMR, OPUS, Speex, G.711, and more.


          Kurento服務器實現(xiàn)的功能

          官網(wǎng)地址:http://www.kurento.org

          2019年12月發(fā)布的最新的6.13版本的文檔:https://doc-kurento.readthedocs.io/en/6.13.0/project/relnotes/v6_13_0.html

          由于Kurento開源服務只有Ubuntu的版本,所以在WSL的UBUNTU上安裝Kurento服務器是再適合不過了。建議安裝Kurento的6.11版本,因為最新的版本并不支持kms-datachannelexample等組件,無法運行顯示字幕等實例,如果只是學習WebRTC,可以無視。

          6.11版本的文檔https://doc-kurento.readthedocs.io/en/6.11.0/user/about.html

          WSL上的安裝:

          1、 在Ubuntu子系統(tǒng)內(nèi)確認安裝GnuPG

          sudo apt-get update && sudo apt-get install --no-install-recommends --yes \
          gnupg


          在Ubuntu子系統(tǒng)內(nèi)確認安裝GnuPG

          2、 在16.04的Ubuntu子系統(tǒng),執(zhí)行:

               DISTRO="xenial"  # KMS for Ubuntu 16.04 (Xenial)
              DISTRO="bionic"  # KMS for Ubuntu 18.04 (Bionic)
           

          在18.04的Ubuntu子系統(tǒng),執(zhí)行

          DISTRO="bionic"  # KMS for Ubuntu 18.04 (Bionic)

          3、下面兩條指令指令增加Kurento倉庫到系統(tǒng)配置中:

          sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 5AFA7A83
                 sudo tee "/etc/apt/sources.list.d/kurento.list" >/dev/null <<EOF
          # Kurento Media Server - Release packages
          deb [arch=amd64] http://ubuntu.openvidu.io/6.13.0 $DISTRO kms6
          EOF


          增加Kurento倉庫到系統(tǒng)配置

          4、 安裝Kurento服務KMS

          sudo apt-get update && sudo apt-get install --yes kurento-media-server

          安裝過程中下載較慢,特別是下載GStream組件的時候,如果下載速度降到很低,可以中斷重新下載,具備斷點重傳。

          5、安裝完成后,可以用下面的指令啟動服務,或者停止服務

          sudo service kurento-media-server start
          sudo service kurento-media-server stop


          啟動KMS服務

          KMS會在Ubuntu子系統(tǒng)本地生成一個端口在8888的服務,可以通過/etc/kurento/kurento.conf.json進行KMS的詳細配置。


          KMS服務的配置

          6、可以在/var/log /kurento-media-server/下查看KMS的日志信息


          KMS的日志信息

          7、如果需要在遠程服務器上部署KMS服務,則需要繼續(xù)安裝STUN或者TURN服務器,來穿透NAT墻。可以參照該網(wǎng)文來安裝Docker設置,https://blog.csdn.net/XRRRICK/article/details/85010829

          8、之后可以繼續(xù)下載Kurento的示例代碼來安裝運行,有SpringBoot、NodeJS等版本的程序供選擇。我這里用SpringBoot就是Java的例程:Kurento Java Tutorial - Hello World

          (1) 運行以下命令來下載Java實例代碼、設置6.11分支,打包運行SpringBoot項目:

          git clone https://github.com/Kurento/kurento-tutorial-java.git
          cd kurento-tutorial-java/kurento-hello-world
          git checkout 6.11.0
          mvn -U clean spring-boot:run -Dkms.url=ws://localhost:8888/kurento


          啟動Hello World的SpringBoot項目

          這里的-Dkms.url=ws://localhost:8888/kurento是本地KMS服務提供的路徑,如果端口沒有什么變化,可以省略不寫。

          (2) 如果啟動沒有什么錯誤的話,就可以在WebRTC兼容的瀏覽器(Chrome、Edge、360瀏覽器等)輸入以下地址(注意是https協(xié)議):https://localhost:8443/,這個Helloworld實例是將本地攝像頭采集到的音視頻流發(fā)送到KMS服務器后,又回送到瀏覽器,左邊的Video組件是顯示本地的視頻,右邊的Video組件是顯示回送的視頻。

          可以看到界面:

          Helloworld示例

          在界面的console里你可以看到整個瀏覽器客戶端與應用服務器(SpringBoot創(chuàng)建的8433端口的Web服務)的消息協(xié)商過程。

          如果在Chrome瀏覽器中,可以在瀏覽器的另一個標簽里打開:chrome://webrtc-internals/,可以看到Google瀏覽器提供的對WebRTC數(shù)據(jù)的統(tǒng)計。


          Chrome瀏覽器里的WebRTC統(tǒng)計信息


          有興趣的同學可以摘取其中的靜態(tài)JS文件和庫文件,組合到自己的應用里。

          • 示例中的WebRTC Media Player可以修改為遠程流媒體播放。
          • 示例中的WebRTC recording可以修改為流媒體錄像
          • 示例中的WebRTC One-To-Many broadcast可以修改為一對多的直播
          • 示例中的WebRTC Many-To-Many video call (Group Call) 可以修改為多對多的視頻會議系統(tǒng)

          可以在我的網(wǎng)站rtc目錄下訪問這個helloworld示例,rtc/hello.html

          PyQt5中,可以使用PyQtWebEngine模塊快速定制專屬瀏覽器,缺省的PyQt5包中并不包含這個模塊,請使用命令:

          pip install PyQtWebEngine

          安裝這個模塊。

          QWebEngineView

          QWebEngineView類提供了一個用于查看和編輯Web文檔部件,web view是Qt WebEngine網(wǎng)頁瀏覽模塊的主要部件的組件。可以在各種應用程序中使用它來實時顯示Internet上的Web內(nèi)容。

          和其他Qt部件一樣,必須show()函數(shù)才可以顯示W(wǎng)eb視圖,簡單的示例代碼如下:

          webView = QWebEegineView(self)
          view.load(QUrl('http://qt-project.org/'))
          view.show()

          QWebEegineView 常用函數(shù):

          • load(self, url): 加載指定的url并顯示。
          • setHtml(self, html, baseUrl): 將網(wǎng)頁視圖的內(nèi)容設置為指定的HTML內(nèi)容。
          • history(self): 返回指向?qū)Ш骄W(wǎng)頁視圖歷史的對象。
          • icon(self): 獲得與當前查看的頁面關聯(lián)的圖標。
          • iconUrl(self): 獲得此屬性保存與當前查看的頁面關聯(lián)的圖標的URL。
          • page(self): 返回指向基礎網(wǎng)頁的對象。
          • pageAction(self, action):返回指向QAction的對象,該對象封裝了指定的Web操作action。
          • selectedText(self):獲得當前選定的文本。。
          • setPage(self, page): 使page成為Web視圖的新網(wǎng)頁。
          • setUrl(self, url): 設置當前查看的網(wǎng)頁的URL。
          • setZoomFactor(self, factor): 設置視圖的縮放因子,有效值是從范圍內(nèi)的0.25到5.0。默認因子是1.0。
          • settings(self): 返回指向視圖或頁面特定設置對象。
          • title(self): 獲得HTML<title>元素定義的頁面標題。
          • triggerPageAction(self, action, checked):觸發(fā)指定的action。如果這是可檢查的操作,則假定為指定的checked狀態(tài)。
          • url(self):獲得當前查看的網(wǎng)頁的URL。
          • zoomFactor(self): 返回視圖的縮放因子。
          • back(self): 用于通過導航鏈接構(gòu)建的文檔列表中的上一個文檔。如果沒有以前的文檔,則不執(zhí)行任何操作。
          • forward(self): 用于通過導航鏈接構(gòu)建的文檔列表中的下一個文檔。如果沒有下一個文檔,則不執(zhí)行任何操作。
          • reload(self): 重新加載當前文檔。
          • stop(self): 停止加載文檔。

          QWebEegineView 常用信號:

          • iconChanged(self, icon): 當與視圖關聯(lián)的圖標(“收藏夾”)更改時,將發(fā)出此信號。新圖標由icon指定。
          • iconUrlChanged(self, url): 當與視圖關聯(lián)的圖標(“圖標”)的URL更改時,將發(fā)出此信號。新URL由url指定。
          • loadFinished(self, ok): 頁面加載完成后發(fā)出此信號。ok將指示加載成功還是發(fā)生錯誤。
          • loadProgress(self, progress): 每當Web視圖中的某個元素完成加載(例如嵌入式圖像或腳本)時,都會發(fā)出此信號。因此,它跟蹤加載Web視圖的總體進度。當前值由progress提供,范圍為0到100,這是QProgressBar的默認范圍。
          • loadStarted(self): 當頁面開始新的加載時,將發(fā)出此信號。
          • renderProcessTerminted(self, terminationStatus,exitCode): 當渲染過程以非零退出狀態(tài)終止時,將發(fā)出此信號。terminationStatus是進程的終止狀態(tài),而exitCode是進程終止的狀態(tài)代碼。
          • selectionChanged(self): 選擇更改時,將發(fā)出此信號。
          • titleChanaged(self, title): 每當視圖標題更改時,都會發(fā)出此信號。
          • urlChanged(self, url): 視圖的URL更改時,將發(fā)出此信號。

          簡單的瀏覽器

          代碼演示如何定制一個簡單的瀏覽器,備注(QWebEngine 模塊的內(nèi)核使用的Chorme, 測試程序在win10下運行正常,在Ubutun下需要加開關 --no-sandbox)。完整代碼如下:

          資源文件:resource.qrc

          <RCC>
          <qresource>
              <file>images/back.png</file>
              <file>images/next.png</file>
              <file>images/close.png</file>
              <file>images/reload.png</file>
          </qresource>
          </RCC>

          代碼文件:

          import sys
          from PyQt5.QtCore import Qt, QUrl, QSize
          from PyQt5.QtGui import QIcon
          from PyQt5.QtWidgets import (QApplication, QMainWindow, QLineEdit,
                                       QMenuBar, QToolBar, QMenu, QAction)
          from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
           
          import resource_rc
           
          default_url = 'https://www.toutiao.com/i6856673250190033415/'
           
          class WebEngineView(QWebEngineView):
              windowList = []
           
          class DemoBrowser(QMainWindow):
              def __init__(self, parent=None):
                  super(DemoBrowser, self).__init__(parent)   
                  
                   # 設置窗口標題
                  self.setWindowTitle('實戰(zhàn)Qt for Python: QWeEngineView演示')      
                  # 設置窗口大小
                  self.resize(640, 480)
                  
                  webSettings = QWebEngineSettings.globalSettings()
                  webSettings.setAttribute(QWebEngineSettings.JavascriptEnabled, True)
                  webSettings.setAttribute(QWebEngineSettings.PluginsEnabled, True)
                  webSettings.setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, True)
                  
                  self.browser = QWebEngineView(self)
                  self.setCentralWidget(self.browser)
                
                  self.initBar()
                  
                  self.browser.load(QUrl(default_url))
              
              def initBar(self):
                  #菜單條
                  menuBar = self.menuBar() 
                  menuFile = menuBar.addMenu('文件(&F)')
                  
                  actionExit = QAction('退出(&X)', self)
                  actionExit.triggered.connect(QApplication.instance().quit)
                  menuFile.addAction(actionExit)  
                  
                  #瀏覽器工具條
                  navBar = QToolBar('Navigation')
                  navBar.setIconSize(QSize(16, 16))
                  self.addToolBar(navBar)
                  
                  self.editUrl = QLineEdit()
                  #地址欄能響應回車按鍵信號
                  self.editUrl.returnPressed.connect(self.navigateToUrl)
                  
                  navBar.addAction(QAction(QIcon(':/images/back.png'), 'Back', self, triggered=self.browser.back))
                  navBar.addAction(QAction(QIcon(':/images/next.png'), 'Forward', self, triggered=self.browser.forward))
                  navBar.addAction(QAction(QIcon(':/images/close.png'), 'Stop', self, triggered=self.browser.stop))
                  navBar.addAction(QAction(QIcon(':/images/reload.png'), 'Reload', self, triggered=self.browser.reload))
                  navBar.addSeparator()
                  navBar.addWidget(self.editUrl)
                  
                  #瀏覽器相應url地址的變化
                  self.browser.urlChanged.connect(self.renewUrl)
                  
              def navigateToUrl(self):
                  url = QUrl(self.editUrl.text())
                  if url.scheme() == '':
                      url.setScheme('http')
                  self.browser.setUrl(url)
                  
              def renewUrl(self, url):
                  # 將當前網(wǎng)頁的鏈接更新到地址欄
                  self.editUrl.setText(url.toString())
                  self.editUrl.setCursorPosition(0)
                  
                    
          if __name__ == '__main__':
              app = QApplication(sys.argv)
              window = DemoBrowser()
              window.show()
              sys.exit(app.exec())   

          運行效果如下圖:

          使用QWebEngineView實現(xiàn)一個簡單的瀏覽器

          本文知識點

          • QWebEngine模塊不包含在PyQt5缺省包中,需要單獨安裝。
          • QWebEngine模塊使用Chrome內(nèi)核。
          • 如何構(gòu)建一個簡單的瀏覽器。

          前一篇: 實戰(zhàn)PyQt5: 132-一個輕量級的地圖應用


          請多多關注,評論,收藏,點贊,和轉(zhuǎn)發(fā)。

          文主要以 HackerScreenSaver 新功能的開發(fā)經(jīng)歷介紹 webBrowser中網(wǎng)頁如何調(diào)用.NET方法的過程。

          1. 背景

          之前開源了一款名為 HackerScreenSaver 的 Windows 屏保程序。該程序具有模擬黑客炫酷界面的特點,用戶可以將自定義的網(wǎng)頁作為鎖屏界面。不久前,有網(wǎng)友提出一個有趣的需求:能否在退出屏保時需要輸入密碼?雖然我不太清楚他的用意,但這個其實可以安排,不過需要變通一下。

          2. 新功能設計

          之前做這個程序的時候我就發(fā)現(xiàn),屏幕保護程序需要自己處理退出,如果屏保程序設計得不夠合理,可能會導致用戶在無法正常退出屏保時遇到困擾。所以在設計之初,我添加了 MouseKeyHook 用來監(jiān)聽全局的鍵鼠事件。

          那么設計新的功能來實現(xiàn)網(wǎng)友的需求也很簡單,當然不是直接的設計什么密碼輸入,然后判斷退出的功能。這里只需將屏保退出的功能提供給網(wǎng)頁控制就可以了。


          新增設置


          3. 網(wǎng)頁與 .NET 交互

          之前介紹到為了程序簡易軟件采用了 webBrowser,那么為了讓網(wǎng)頁可以決定什么時候退出屏保,就需要讓 webBrowser 中的網(wǎng)頁可以調(diào)用 .NET 的方法。

          在網(wǎng)頁中,我們需要在屏保退出的邏輯部分添加一段 JavaScript 代碼,用于調(diào)用 .NET 方法。這段代碼的核心是 window.external 對象,它允許 JavaScript 訪問 .NET 對象。我們在用戶輸入正確密碼或者游戲勝利等條件下執(zhí)行下面的 JavaScript 代碼即可:

          window.external.ExecuteExitSrc();

          對于 .NET 代碼,可以創(chuàng)建一個和單獨的類以供 web 調(diào)用:

          • [ComVisible(true)]public class JavaScriptInteraction{ public void ExecuteExitSrc() { Application.Exit(); }}

            需要注意的是,我們需要在該類上添加一個 [ComVisible(true)] 特性。這個特性使得該類的公共成員可以被 COM 組件訪問,從而實現(xiàn) JavaScript 與 .NET 方法之間的互操作,否則你會收到下面的錯誤信息:

            System.ArgumentException:“ObjectForScripting 的類必須對 COM 可見。請確認該對象是公共的,或考慮向您的類添加 ComVisible 特性。”

            最后,需要在 webBrowser 控件的 ObjectForScripting 屬性中設置一個 .NET 對象,這個對象將用于被 JavaScript 調(diào)用:

            webB.ObjectForScripting = new JavaScriptInteraction();

            4. 新的屏保

            為了演示新功能的使用,在 html 目錄中,提供了一個演示用的 exit.html 直接提供了網(wǎng)頁退出屏保的演示按鈕。

            新的功能提供了更多的可玩性,用戶可以根據(jù)自己的喜好設計各種有意思的屏保,這樣也是滿足了輸入密碼退出這個功能的實現(xiàn)基礎。當然我們可以有許多有意思的功能可以自行設計,比如:

            1.解謎屏保:設計一個帶有簡單謎題的屏保,用戶需要在網(wǎng)頁上回答正確才能退出屏保。謎題可以是數(shù)學題、邏輯題或者常識題等,每次屏保激活時,可以隨機從題庫中抽取一道題目。既然是題庫,甚至可以利用屏保學習各種知識,比如英語單詞,各種考試題等等。2.拼圖屏保:制作一個拼圖游戲,用戶需要在網(wǎng)頁上完成拼圖才能退出屏保。可以使用用戶自己的照片作為拼圖素材,或者從網(wǎng)上隨機抓取圖片。拼圖難度可以根據(jù)用戶的喜好進行調(diào)整。3.計時屏保:設置一個倒計時屏保,用戶需要在網(wǎng)頁上等待一段時間(例如,1分鐘)后才能退出屏保。在等待期間,可以展示一些有趣的事物,如名言警句、美麗的圖片或者實時新聞等。

            通過這些有趣的屏保設計方案,用戶在退出屏保時可以享受到更多互動和趣味性。此外,這些方案還可以根據(jù)用戶的喜好和需求進行定制和擴展,為用戶帶來更豐富的屏保體驗。

            同時,我還在更新中提供了一個經(jīng)典的 2048 小游戲,要求玩家在贏得游戲后才能退出屏保。


            2048


            這個游戲改的邏輯其實是沒有改好的,也懶得調(diào)整了,更新一下游戲介紹也是可以的。


            游戲介紹



            提交信息


            5. 背后的哲學

            當玩家在游戲中努力拼搏,最終贏得游戲時,他們可能會發(fā)現(xiàn),游戲并沒有因此結(jié)束,屏保依然繼續(xù)運行。這時,他們可能會意識到,即使付出了努力,結(jié)果也不一定如人意。而當玩家選擇投降并重新開始游戲10次后,他們將發(fā)現(xiàn)這個看似無用的操作竟然讓屏保退出,讓電腦恢復正常使用。

            也許只有努力過才會發(fā)現(xiàn),游戲還是投降躺平舒服些,只需要重開十次,就會被比你努力湊齊 2048 贏得游戲來退出屏保更快。人生有時就是這樣,在現(xiàn)實生活中,我們往往會面臨兩種選擇:努力拼搏還是躺平投降。有時候,努力拼搏的結(jié)果并不一定能讓我們達到預期的目標,反而可能讓我們陷入更深困境,帶來更多的困擾。而在某些情況下,選擇躺平投降,反而能讓我們以更輕松的心態(tài)面對問題,從而找到解決問題的更快方法。當然,該拼搏的時候,還是需要努力一把,萬一就成功了呢?

            6. 最后

            本文向大家介紹了如何在 webBrowser 中的網(wǎng)頁調(diào)用 .NET 方法,以及如何在屏保程序中加入游戲元素。通過這些技巧,我們可以為用戶帶來更有趣的屏保體驗。希望本文能對大家有所幫助,最后項目地址是:https://github.com/sangyuxiaowu/HackerScreenSaver?wt.mc_id=DT-MVP-5005195 感興趣的話,可以下載體驗一下。


          主站蜘蛛池模板: 色噜噜狠狠一区二区三区| 美女AV一区二区三区| 精品国产一区二区三区www| 精品深夜AV无码一区二区老年| 亚洲国产精品一区二区久久| 久久亚洲国产精品一区二区| 亚洲国产精品一区二区成人片国内 | 国产伦理一区二区| 精品久久一区二区| 亚欧在线精品免费观看一区| 亚洲熟妇成人精品一区| 日本精品高清一区二区2021| 色一情一乱一伦一区二区三区日本 | 国产精品免费视频一区| 日本视频一区二区三区| 中文字幕在线视频一区| 午夜天堂一区人妻| 亚洲一区二区三区写真| 波多野结衣av高清一区二区三区| 亚洲国产成人久久一区久久| 亚洲乱码日产一区三区| 亚洲熟妇av一区二区三区下载| 日韩成人无码一区二区三区 | 久久久无码一区二区三区| 亚洲国产欧美日韩精品一区二区三区 | 亚洲熟女综合色一区二区三区| 色天使亚洲综合一区二区| 一区二区三区免费高清视频| 竹菊影视欧美日韩一区二区三区四区五区| 国产伦理一区二区三区| 精品国产香蕉伊思人在线在线亚洲一区二区| 国模极品一区二区三区| 精品国产一区二区22| 青青青国产精品一区二区| 成人精品一区二区不卡视频| 国产情侣一区二区三区| 91大神在线精品视频一区| 国产成人av一区二区三区在线| 熟妇人妻系列av无码一区二区| 亚洲一区在线免费观看| 美女AV一区二区三区|