天天看點

iOS DLNA程式設計

iOS DLNA程式設計

近期實作了iOS下的DLNA,發現ios下的DLNA程式設計資料很少,其實DLNA文檔還好 (28m) ,但是真的确定要看文檔自己去實作麼? 下面先介紹一下DLNA的基本概念,已經有概念的同學可以跳過,直接看iOS下的DLNA庫

什麼是DLNA

DLNA的全稱是DIGITAL LIVING NETWORK ALLIANCE, 其宗旨是Enjoy your music, photos and videos, anywhere anytime, DLNA (Digital Living Network Alliance) 由索尼、英特爾、微軟等發起成立、旨在解決個人PC, 消費電器, 移動裝置在内的無線網絡和有線網絡的互聯互通, 使得數字媒體和内容服務的無限制的共享和增長成為可能, 目前成員公司已達280多家.DLNA并不是創造技術, 而是形成一種解決的方案, 一種大家可以遵守的規範. 是以, 其選擇的各種技術和協定都是目前所應用很廣泛的技術和協定.DLNA将其整個應用規定成5個功能元件. 從下到上依次為:網絡互連, 網絡協定, 媒體傳輸, 裝置的發現控制和管理, 媒體格式. 以上摘自百度百科.通俗的說就是一幫人為實作某些功能,定義了一個标準.

功能

  • 探索:網絡中尋找無配置的裝置并計算出其提供的性能
  • 浏覽:浏覽内容并通過不同方式分類
  • 搜尋:在裝置上尋找特定内容
  • 分流:全網發送多媒體内容
  • 服務:網絡通知通訊錄
  • 列印:向網絡附屬列印機發送内容
  • 控制:使用網絡改變裝置狀态
  • 上傳:發送内容到伺服器
  • 下載下傳:接收并儲存内容
  • 自動譯碼:改變分辨率或内容格式來確定裝置正确翻譯
  • 服務保證:區分網絡交通優先次序, 若網絡超載, 優先放棄最弱的優先權

功能子產品

數字媒體伺服器 (DMS, Digital Media Server) :提供了媒體檔案的擷取、錄制、存儲以及作為源頭的裝置. 數字媒體播放器 (DMP, Digital Media Player) :可查找并播放或輸出任何由DMS所提供的媒體檔案的裝置. 移動式數字媒體伺服器 (M-DMS, Mobile Digital Media Server) :針對手機等體積較小、輕巧可移動式的電子裝置所定義的伺服器, 多媒體格式支援與一般DMS稍有不同. 移動式數字媒體播放器 (M-DMP, Mobile Digital Media Player) :同樣是針對移動裝置的播放器, 多媒體格式支援與一般DMP稍有不同. 數字媒體控制器 (DMC, Digital MediaController) :作為遙控裝置使用, 可查找DMS上的多媒體檔案, 并指定可播放該多媒體檔案的DMP進行播放或是控制多媒體檔案上下傳到DMS的裝置. 數字媒體列印機 (DMPr, Digital Media Printer) :DMPr的列印機可以在DLNA網絡架構下提供列印功能.

iOS下的DLNA庫

git上搜的話,隻搜到一個oc包裝的庫https://github.com/FuruyamaTakeshi/DLNA 這個庫的問題還是有些的 文檔嘛,去了作者的個人站點,發現有了和沒有一樣. demo不全,不是所有的功能寫了 還有個bug,seek那裡應該用REL_TIME 所有的請求是走是程同步,非多線程 初始化到啟動時間過長,ip6測試從init開始到搜尋需要6s左右. DLNA協定實作的也不全,但是再不全也比自己重寫的好.

iOS下的DLNA

咱項目呢,需要用的是DMC那部分,通俗的說就是把手機上的線上的視訊投放到小米盒子之類的産品上. 具體的實作:

// 搜尋裝置,我們這裡就隻搜DMR了

CGUpnpAvController *avCtrl = [[CGUpnpAvController alloc] init];

avCtrl.delegate  = self;

// 這個 start 要6s

[self.avCtrl start];

[self.avCtrl searchWithST:DLNAService__CG_UPNPAV_DMR_DEVICE_TYPE];

// 響應裝置跟新的委托

-  (void) controlPoint: (CGUpnpControlPoint *) controlPoint deviceAdded: (NSString *) deviceUdn;

-  (void) controlPoint: (CGUpnpControlPoint *) controlPoint deviceUpdated: (NSString *) deviceUdn;

-  (void) controlPoint: (CGUpnpControlPoint *) controlPoint deviceRemoved: (NSString *) deviceUdn;

-  (void) controlPoint: (CGUpnpControlPoint *) controlPoint deviceInvalid: (NSString *) deviceUdn; 

// 有裝置後,給裝置發送相應的指令,控制裝置的行為

// 給指定的裝置設定播放位址

// 這裡DLNA的文檔上是用了這個action後DMP會變成play狀态,就是會自動播放

BOOL b = [_currentRenderer setAVTransportUrl:url];

// 但是騰訊是又發了一個play的action,可能是騰訊測試的機子多,發現有些裝置沒有自動播放吧

b = [_currentRenderer play] && b;

// 設定seek的時間,這裡記得fix下庫的bug

[_currentRenderer seek:iTime]

// 這樣就完成了将網上的視訊投放到盒子 (電視上了) ,但是還沒完,我們不知道播放進度

// 我們得自己寫個定時器,主動問裝置,您播放到哪秒了啊

CGUpnpAVPositionInfo *positionInfo = [_currentRenderer positionInfo];

// 最後就是關于停止暫停的一些方法了

[_currentRenderer stop];

[_currentRenderer pause];

// 如果你還想改音量啊,連續播放視訊啊

// 呵呵,這個庫沒帶,請自己實作

// 類似下面的下一個

-  (BOOL) next

{

    CGUpnpAction *action = [self actionOfTransportServiceForName:@"Next"];

    if  (!action) 

        return NO;

    [action setArgumentValue:@"0" forName:@"InstanceID"];

    if  (![action post]) 

        return NO;

    return YES;

}

// 當你實作了連續播放視訊的功能時候呢,你會發現,小米盒子沒實作這個功能

// SetVolume這個action是實作設定音量的,這個可以試試看哦

看了上述代碼發現其實也不難嘛,具體試了之後呢會發現一堆坑的,如seek, 文檔上是說隻有play或者stop的狀态下發送才能成功.是以呢,你直接發完play的action後,立馬發一個seek,覺得會成功麼?DMR剛剛收到setAVTransportUrl後是下載下傳,不是play狀态哦,但是這個時候已經回複你action成功了.如果你想知道DMR的狀态是有辦法的,但是這個oc包裝的庫沒寫.但是呢有的裝置可以直接就發送seek,有的就必須等下載下傳完成開始play後才能seek,我說的裝置還都是小米盒子.

SOAP協定實作UPnP-AV播放系統裝置控制

http://xuehuile.com/thesis/cf8a94932cbf4e88b4a11a8ed6b01307.html

官方位址 http://www.cybergarage.org/do/view/

問題點

  • 切片(需要自己拼接)
  • 破解(ok)
  • 支援的格式

關注

  • 最新的庫

流程

  • 初始化
  • 搜尋裝置
  • 連接配接裝置
  • 查詢伺服器協定
  • 查詢播放器協定(沒接口)
  • 擷取伺服器播放link
  • 丢給播放器
  • 做播放器控制
  • 定時查詢播放時間