導(dǎo)語(yǔ)
至于手機(jī)投屏的實(shí)現(xiàn)方法可謂五花八門(mén),今天小袁就說(shuō)下以開(kāi)發(fā)人員的角度來(lái)說(shuō)下當(dāng)今手機(jī)的主流投屏方法。目前這種將終端信號(hào)經(jīng)由WiFi傳輸?shù)诫娨?、電視盒的技術(shù)有三種:DLNA、AirPlay、Miracast、Google Cast。
手機(jī)投屏智能電視的幾種方法
DLNA
專業(yè)術(shù)語(yǔ):DLNA的全稱是DIGITAL LIVING NETWORK ALLIANCE(數(shù)字生活網(wǎng)絡(luò)聯(lián)盟)。
DLNA(Digital Living Network Alliance) 由索尼、英特爾、微軟等發(fā)起成立、旨在解決個(gè)人PC,消費(fèi)電器,移動(dòng)設(shè)備在內(nèi)的無(wú)線網(wǎng)絡(luò)和有線網(wǎng)絡(luò)的互聯(lián)互通。
DLNA 2003年誕生是為了能夠把當(dāng)時(shí)相互獨(dú)立的電視機(jī)及其相關(guān)設(shè)備(功放、音響、DVD/藍(lán)光播放機(jī))、PC及其相關(guān)設(shè)備(數(shù)碼相機(jī)、音樂(lè)播放器)和移動(dòng)電話在家庭中有機(jī)地整合起來(lái),使得多媒體內(nèi)容能夠在各個(gè)設(shè)備上便捷地播放。
通俗術(shù)語(yǔ):
DLNA(數(shù)字生活網(wǎng)絡(luò)聯(lián)盟) 就是大佬們一起搞事情 商討“我們要將物聯(lián)網(wǎng)設(shè)備連接起來(lái),怎么搞啊?” 搞著搞著 就搞出了這套設(shè)備的工業(yè)標(biāo)準(zhǔn)。 然后讓其他設(shè)備具備 DLNA 這種工業(yè)標(biāo)準(zhǔn),這樣這些設(shè)備就可以互聯(lián)互通了。
UPnp協(xié)議
DLNA 標(biāo)準(zhǔn)包括多項(xiàng)協(xié)議及標(biāo)準(zhǔn),其中最重要的部分是 UPnP 協(xié)議
UPnP是由“通用即插即用論壇”(UPnP Forum)推廣的一套網(wǎng)絡(luò)協(xié)議,它的目標(biāo)是實(shí)現(xiàn)設(shè)備間網(wǎng)絡(luò)互聯(lián)。
UPnP協(xié)議定義了設(shè)備之間,設(shè)備和控制點(diǎn),控制點(diǎn)之間通信的協(xié)議
完整的UPnP協(xié)議棧由設(shè)備尋址、設(shè)備發(fā)現(xiàn)、設(shè)備描述、設(shè)備控制、事件通知以及基于Html的描述等幾部分構(gòu)成
看到這個(gè)圖有沒(méi)有想到 OSI 七層模型?
我從下至上來(lái)介紹一下:
ip網(wǎng)絡(luò)協(xié)議 大哥哥
IP:就是ip網(wǎng)絡(luò)協(xié)議。
為什么需要它?
因?yàn)橛玫骄W(wǎng)絡(luò)層數(shù)據(jù)的傳輸,IP層用于數(shù)據(jù)的發(fā)送與接收。
想象一下兩個(gè)設(shè)備互聯(lián),其實(shí)就是在網(wǎng)絡(luò)互聯(lián),所以需要網(wǎng)絡(luò)層協(xié)議。
TCP-UDP
這里包含了UDP和TCP兩塊協(xié)議。
這里圖應(yīng)該這樣表示:
UDP協(xié)議跟IP協(xié)議組合成:UDP/IP協(xié)議
而 HHTPMU 和 HTPU 這兩個(gè)協(xié)議是基于 UDP/IP 協(xié)議之上的。
TCP協(xié)議跟IP協(xié)議組合成:TCP/IP 協(xié)議
HTTP 則是基于 TCP/IP 協(xié)議上。
TCP/IP 協(xié)議大家應(yīng)該都了解,但為何出現(xiàn)一個(gè) UDP/IP 呢?
使用UDP,可以通過(guò)多點(diǎn)傳送(Multicast)向 LAN 上所有支持UPnP的設(shè)備發(fā)送新設(shè)備接入的通知。這里流媒體 也會(huì)使用 UDP 來(lái)傳輸,因?yàn)樗俣瓤臁?/p>
HHTPMU 和 HHTPU 是什么?
它是構(gòu)建在 TCP/IP 協(xié)議之上的是 HTTP 協(xié)議及其變種,所有 UPnP 消息都被封裝在 HTTP 協(xié)議及其變種中。HTTP 協(xié)議的變種是 HTTPU 和 HTTPMU,這些協(xié)議的格式沿襲了 HTTP 協(xié)議,只不過(guò)與 HTTP 不同的是他們通過(guò) UDP 而非 TCP 來(lái)承載的,并且可用于組播進(jìn)行通信。
可見(jiàn) 它之所以存在就是替換 TCP 為 UDP。
接下來(lái)就是 設(shè)備發(fā)現(xiàn) | 設(shè)備控制 | 設(shè)備事件 協(xié)議了:
1、設(shè)備發(fā)現(xiàn) SSDP 協(xié)議
簡(jiǎn)單服務(wù)發(fā)現(xiàn)協(xié)議(Simple Service Discovery Protocol:SSDP)
具體包括控制點(diǎn)如何發(fā)現(xiàn)網(wǎng)絡(luò)上有哪些服務(wù),以及這些服務(wù)的資訊,還有控制點(diǎn)本身宣告他提供哪些服務(wù)。
2、控制設(shè)備 SOAP 協(xié)議
簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議(Simple Object Access Protocol:SOAP)
它定義如何使用 XML 與 HTTP 來(lái)執(zhí)行遠(yuǎn)程過(guò)程調(diào)用。包括控制點(diǎn)如何發(fā)送命令消息給設(shè)備,設(shè)備收到命令消息后如何發(fā)送響應(yīng)消息給控制點(diǎn)。
3、設(shè)備事件 GENA 協(xié)議
通用事件通知架構(gòu)(Generic Event Notification Architecture:GENA)
定義在控制點(diǎn)想要監(jiān)聽(tīng)設(shè)備的某個(gè)服務(wù)狀態(tài)變量的狀況時(shí),控制點(diǎn)如何傳送訂閱信息并如何接收這些信息。
體系定義
這一層僅僅是一個(gè)抽象的、公用的設(shè)備模型。就是一個(gè)規(guī)范 定義,所有的 UPnP 設(shè)備都必須使用這層。
UPnP論壇
UPnP 論壇的各個(gè)專業(yè)委員會(huì)的設(shè)備定義層,在這個(gè)論壇中,不同電器設(shè)備由不同的專業(yè)委員會(huì)定義,例如:電視委員會(huì)只負(fù)責(zé)定義網(wǎng)絡(luò)電視設(shè)備部分,空調(diào)器委員會(huì)只負(fù)責(zé)定義網(wǎng)絡(luò)空調(diào)設(shè)備部分,依此類推。
UPnP設(shè)備制造廠商定義
也就是應(yīng)用層,由 UPnP 設(shè)備制造廠商定義的部分。
Miracast
Miracast是由Wi-Fi聯(lián)盟于2012年所制定,以Wi-Fi直連為基礎(chǔ)的無(wú)線顯示標(biāo)準(zhǔn)。支持此標(biāo)準(zhǔn)的設(shè)備可通過(guò)無(wú)線方式分享視頻畫(huà)面,例如手機(jī)可通過(guò)Miracast將影片或照片直接在電視或其他裝置播放而無(wú)需受到連接線纜長(zhǎng)度的影響。與DLNA不同的是,Miracast 也有類似于AirPlay 的鏡像功能,可以將手機(jī)中屏幕內(nèi)容直接投放到高清電視屏幕里,這樣你也可以通過(guò)電視屏幕來(lái)玩游戲了。Android4.2版本以后系統(tǒng)標(biāo)配此功能(在設(shè)置或顯示菜單中可以找到,應(yīng)用名稱諸如:Wlan display、Wifi display、Miracast、Allshare cast、Mirroring screen、無(wú)線顯示等,只是各手機(jī)廠家命名不同而已)??梢詫⑹謾C(jī)屏幕通過(guò)無(wú)線顯示接收器將畫(huà)面無(wú)線傳輸?shù)狡渌^大屏幕上,如客廳電視,會(huì)議室投影儀。畫(huà)面?zhèn)鬏斞訒r(shí)150ms以下,幾乎同時(shí)。點(diǎn)擊此功能,但沒(méi)有任何反應(yīng),因?yàn)榇隧?xiàng)功能需要配件支持。
AirPlay
AirPlay 是蘋(píng)果開(kāi)發(fā)的一種無(wú)線技術(shù),可以通過(guò)WiFi將iPhone 、iPad、iPodtouch 等iOS 設(shè)備上的包括圖片、音頻、視頻通過(guò)無(wú)線的方式傳輸?shù)街С諥irPlay 設(shè)備。售價(jià)99美元的Apple TV就具備這樣的功能,現(xiàn)在一些傳統(tǒng)的家庭影院和HIFI如馬蘭士和天龍的新品功放和網(wǎng)絡(luò)播放器已經(jīng)支持AirPlay功能。
AirPlay具備與DLNA所沒(méi)有的鏡像功能,這一功能叫AirPlay鏡像,可將iPhone 或iPad 上的畫(huà)面無(wú)線傳輸?shù)诫娨暽?,也就是說(shuō)你設(shè)備顯示的是什么,電視屏幕顯示就就是什么,而不僅限于圖片和視頻。你可以拿著iPad 來(lái)當(dāng)做方向盤(pán),然后看著大屏玩游戲。
另外AirPlay鏡像最牛地方是它可以實(shí)現(xiàn)雙屏游戲,讓你的游戲有更多的交互。比如,電視里顯示的是游戲畫(huà)面,而iPad上顯示的是比賽的路線圖。
Google Cast
因?yàn)閲?guó)內(nèi)的手機(jī)基本都是閹割版本的。因?yàn)椴恍枰褂肎oogle Play,所以國(guó)內(nèi)很多手機(jī)需要下載好谷歌的三件套才能使用,然后就是谷歌官方的硬件Chromecast,在國(guó)內(nèi)基本很難用,因?yàn)橐迷L問(wèn)谷歌的服務(wù)器,所以需要外網(wǎng)才行,
我在集成Chromecast中遇到的坑
申請(qǐng)id
*使用Styled Media Receiver類型注冊(cè),獲取id,然后替換官方demo的id就不會(huì)有sample這個(gè)水印了,我開(kāi)始用的Custom Receiver類型注冊(cè),水印還在。
Android代碼加入
compile 'com.google.android.gms:play-services-cast-framework:10.0.1'//這里要用低版本,困擾兩天
compile 'com.googlecode.android-query:android-query:0.25.9'
compile 'com.android.support:mediarouter-v7:25+'
投屏關(guān)鍵代碼
private MediaInfo buildMediaInfo() {
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, mTitle);
movieMetadata.putString(MediaMetadata.KEY_TITLE, "第" + mPart + "集");
movieMetadata.addImage(new WebImage(Uri.parse(mPictureUrl)));
movieMetadata.addImage(new WebImage(Uri.parse(mPictureUrl)));
// Log.e(TAG, "buildMediaInfo" + mSelectedMedia.getUrl() + " " + mSelectedMedia.getDuration() * 1000);
//第一條為谷歌,第二條為我加密,三 不加密 4 網(wǎng)路不加密
// return new MediaInfo.Builder("https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/hls/WhatCarCanYouGetForAGrand.m3u8")
// return new MediaInfo.Builder("https://cdn61.ytbbs.tv/cn/tv/55550/55550-1/play.m3u8?md5=QXaEWg8r8NkZJo9ln0cZwg&expires=1521010007&token=55550")
// return new MediaInfo.Builder("https://cdn61.ytbbs.tv/cn/tv/54063/54063-1/play.m3u8?md5=DRhHA6ToB4z43_32sex0kw&expires=1521012980&token=54063")
// return new MediaInfo.Builder("http://cdn14.ytbbs.tv/666/ds3/play.m3u8")
// return new MediaInfo.Builder(mSelectedMedia.getUrl())
// url = "https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/mp4/DesigningForGoogleCast.mp4";
//url = "https://cdn61.ytbbs.tv/666/ds3/ds3s.mp4";
LogUtils2.logi(TAG, "buildMediaInfo" + url);
return new MediaInfo.Builder(url)
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setContentType("application/vnd.apple.mpegurl")
// .setContentType("application/x-mpegurl")
// .setContentType("videos/m3u8")
// .setContentType("videos/mp4")
.setMetadata(movieMetadata)
.setStreamDuration(0)
.build();
}
setContentType里面MIME值類型非常重要。很多小伙伴投屏失敗就是因?yàn)闆](méi)有使用正確的MIME類型
DLNA和Miracast區(qū)別
DLNA是基于文件的,媒體文件可能有各種各樣的編碼格式,播放器這端必須能夠處理這么多種編碼格式。通常為了比較好的播放體驗(yàn),DLNA會(huì)先緩存一小段時(shí)間。
Miracast是實(shí)時(shí)的,它可以實(shí)時(shí)傳輸源端(Source)的輸出。源端任何屏幕的操作都會(huì)被傳輸?shù)浇邮?Sink)端。如果源端是播放媒體文件,源端負(fù)責(zé)先對(duì)媒體文件解碼,然后再編碼成H.264的格式。接收端只需要做H.264的解碼就可以了。相對(duì)DLNA,Miracast對(duì)于WiFi通路的要求要更高一些。
安卓手機(jī)投屏電視DLNA推送和鏡像投屏的區(qū)別
安卓手機(jī)投屏電視為什么沒(méi)聲音
Android安全架構(gòu)的核心設(shè)計(jì)思想,就是在默認(rèn)設(shè)置下,所有應(yīng)用都沒(méi)有權(quán)限對(duì)其他應(yīng)用、系統(tǒng)或用戶進(jìn)行較大影響的操作。這其中包括讀寫(xiě)用戶隱私數(shù)據(jù)(聯(lián)系人或電子郵件),讀寫(xiě)其他應(yīng)用文件,訪問(wèn)網(wǎng)絡(luò)或阻止設(shè)備待機(jī)等。而手機(jī)的最重要功能是語(yǔ)音通信,安卓系統(tǒng)充分考慮了手機(jī)語(yǔ)音的安全性,所以不允許其它應(yīng)用獲取手機(jī)的語(yǔ)音數(shù)據(jù),從而保證通話不被截取。也正是由于這個(gè)原因,當(dāng)我們的鏡像程序在手機(jī)端運(yùn)行時(shí),被視為第三方不安全的應(yīng)用程序,從而無(wú)法獲取手機(jī)聲音,導(dǎo)致安卓手機(jī)投屏沒(méi)有聲音。
安卓手機(jī)投屏電視為什么有些有聲音?
有聲音的情況:一種是采用DLNA推送技術(shù)投屏【流媒體播放】,另一種是利用藍(lán)牙技術(shù)將聲音傳輸?shù)酱笃聊灰繇懺O(shè)備上。
采用DLNA推送技術(shù)投屏:當(dāng)下視頻播放軟件,比如愛(ài)奇藝,在播放界面的【TV】標(biāo)識(shí)投屏,就是利用DLNA推送技術(shù),將節(jié)目的資源推送到電視機(jī)上,這樣電視機(jī)在播放的時(shí)候是有聲音的。
利用藍(lán)牙技術(shù):當(dāng)安卓手機(jī)利用其他方式與電腦進(jìn)行鏡像投屏的時(shí)候,也就是安卓手機(jī)的界面與電視是同步顯示的時(shí)候,安卓手機(jī)在播放音、視頻是沒(méi)有聲音的,當(dāng)下大多數(shù)做法就是通過(guò)藍(lán)牙技術(shù)將聲音傳輸?shù)酱笃聊灰繇懺O(shè)備上。
安卓手機(jī)投屏電視DLNA推送和鏡像投屏的區(qū)別
DLNA推送:手機(jī)將播放的節(jié)目資源地址推送給電視,然后我們手機(jī)就可以去刷朋友圈,聊微信,互不干擾。但是這種投屏,需要【節(jié)目資源】支持DLNA,另一方面這種投屏是不能連續(xù)播放,也不能自動(dòng)下一集播放。
鏡像投屏:安卓手機(jī)通過(guò)投屏軟件或者投屏設(shè)備,做到手機(jī)屏幕與電視機(jī)屏幕同步顯示的效果,這種情況大多數(shù)用來(lái)玩游戲。