基於DLNA實現iOS,Android投屏:SOAP控制裝置

BrikerMan發表於2016-04-26

基於DLNA實現iOS,Android投屏:SOAP控制裝置

UPdP網路中,控制點和服務之間使用簡單物件訪問協議(Simple Object Access Protocol,SOAP)

根據基於DLNA實現iOS,Android投屏:SSDP發現裝置收到裝置描述文件(DDD)和服務描述文件(SDD),通過解析DDD獲取 <controlURL> 控制點可以知道該裝置上某個服務的控制點地址。再通過解析 DDD 中 <action> 中的 <name><argumentList> 獲取該服務動作的動作名稱,引數要求。控制點向 controlURL 發出服務呼叫資訊,表明動作名稱和相應引數來呼叫相應的服務。

SOAP簡單物件訪問協議

控制點和服務之間使用簡單物件訪問協議(Simple Object Access Protocol,SOAP)的格式。SOAP 的底層協議一般也是HTTP。在 UPnP 中,把 SOAP 控制/響應資訊分成 3 種: UPnP Action Request、UPnP Action Response-Success 和 UPnP Action Response-Error。SOAP 和 SSDP 不一樣,所使用的 HTTP 訊息是有 Body 內容,Body 部分可以寫想要呼叫的動作,叫做 Action invocation,可能還要傳遞引數,如想播放一個網路上的視訊,就要把視訊的URL傳過去;服務收到後要 response ,回答能不能執行呼叫,如果出錯則返回一個錯誤程式碼。

動作呼叫(UPnP Action Request)

使用POST方法傳送控制訊息的格式如下

  • control URL: 基於DLNA實現iOS,Android投屏:SSDP發現裝置 中提到的 裝置描述檔案urn:upnp-org:serviceId:AVTransport 服務的 <controlURL>
  • HOST: 上述伺服器的根地址和埠號。
  • actionName: 需要呼叫動作的名稱,對應相應服務的 服務描述檔案<SCPDURL> 中的 <action><name> 欄位。
  • argumentName: 輸入引數名稱,對應相應服務的 服務描述檔案<SCPDURL> 中的 <action> <argument> <name> 欄位。
  • in arg values: 輸入引數值,具體的可以通過 ,可以通過 服務描述檔案<SCPDURL> <action> <relatedStateVariable> 提到的狀態變數來得知值得型別。
  • urn:schemas-upnp-org:service:serviceType:v:對應該 裝置描述檔案 相應服務的 <serviceType 欄位。

動作響應(UPnP Action Response-Succes)

收到控制點發來的動作呼叫請求後,裝置上的服務必須執行動作呼叫。,並在 30s 內響應。如果需要超過 30s 才能完成執行的動作,則可以先返回一個應答訊息,等動作執行完成再利用事件機制返回動作響應。

  • actionNameResponse: 響應的動作名稱
  • arugumentName: 當動作帶有輸出變數時必選,輸出變數名稱
  • out arg values: 輸出變數名稱值

動作錯誤響應(UPnP Action Response-Succes)

如果處理動作過程中出現錯誤,則返回一個一下格式的錯誤響應。

  • faultcode: SOAP規定使用元素,呼叫動作遇到的錯誤型別,一般為s:Client。
  • faultstring: SOAP規定使用元素,值必須為 UPnPError。
  • detail: SOAP規定使用元素,錯誤的詳細描述資訊。
  • UPnPError: UPnP規定元素。
  • errorCode: UPnP規定元素,整數。詳見下表。
  • errorDescription: UPnP規定元素,簡短錯誤描述。
errorCode errorDescription 描述
401 Invalid Action 這個服務中沒有該名稱的動作
402 Invalid Args 引數資料錯誤 not enough in args, too many in arg, no in arg by that name, one or more in args 之一
403 Out of Sycs 不同步
501 Action Failed 可能在當前服務狀態下返回,以避免呼叫此動作
600 ~ 699 TBD 一般動作錯誤,由 UPnP 論壇技術委員會定義
700 ~ 799 TBD 面向標準動作的特定錯誤,由 UPnP 論壇工作委員會定義
800 ~ 899 TBD 面向非標準動作的特定錯誤,由 UPnP 廠商會定義

投屏基本命令及其響應

所有命令以發向 基於DLNA實現iOS,Android投屏:SSDP發現裝置 發現的裝置。除了網址以外,其餘部分均不需要修改。

所有動作請求使用 POST 請求傳送,並且請求Header均如下所示,其中:

  • control URL: 基於DLNA實現iOS,Android投屏:SSDP發現裝置 中提到的 裝置描述檔案urn:upnp-org:serviceId:AVTransport 服務的 <controlURL>
  • HOST: 上述伺服器的根地址和埠號。
  • urn:schemas-upnp-org:service:serviceType:v:對應相應裝置的 裝置描述檔案 相應服務的 <serviceType 欄位。
  • actionName: 需要呼叫動作的名稱,對應相應服務的 服務描述檔案<SCPDURL> 中的 <action><name> 欄位。

下面請求和響應均忽略Header,引數列表中列出Header的SOAPACTION值

設定播放資源URI

動作請求

設定當前播放視訊動作統一名稱為 SetAVTransportURI 。 需要傳遞引數有

  • InstanceID:設定當前播放時期時為 0 即可。
  • CurrentURI: 播放資源URI
  • CurrentURIMetaData: 媒體meta資料,可以為空
  • Header_SOAPACTION: “urn:upnp-org:serviceId:AVTransport#SetAVTransportURI”

有些裝置傳遞播放URI後就能直接播放,有些裝置設定URI後需要傳送播放命令,可以在接收到 SetAVTransportURIResponse 響應後呼叫播放動作來解決。

響應

播放

動作請求

播放視訊動作統一名稱為 Play 。 需要傳遞引數有

  • InstanceID:設定當前播放時期時為 0 即可。
  • Speed:播放速度,預設傳 1 。
  • Header_SOAPACTION: “urn:upnp-org:serviceId:AVTransport#Pause”

響應

暫停

動作請求

暫停視訊動作統一名稱為 Pause 。 需要傳遞引數有

  • InstanceID:設定當前播放時期時為 0 即可。
  • Header_SOAPACTION: “urn:upnp-org:serviceId:AVTransport#Pause”

響應

獲取播放進度

動作請求

獲取播放進度動作統一名稱為 GetPositionInfo 。 需要傳遞引數有

  • InstanceID:設定當前播放時期時為 0 即可。
  • MediaDuration: 可以為空。
  • Header_SOAPACTION: “urn:upnp-org:serviceId:AVTransport#MediaDuration”

響應

獲取播放進度響應中包含了比較多的資訊,其中我們主要關心的有一下三個:

  • TrackDuration: 目前播放視訊時長
  • RelTime: 真實播放時長
  • AbsTime: 相對播放時長

注:目前為止還沒發現 RelTime AbsTime 和不一樣的情況,選用 RelTime 就ok。

跳轉至特定進度或視訊

動作請求

跳轉到特定的進度或者特定的視訊(多個視訊播放情況),需要呼叫 Seek 動作,傳遞引數有:

  • InstanceID: 一般為 0 。
  • Unit:REL_TIME(跳轉到某個進度)或 TRACK_NR(跳轉到某個視訊)。
  • Target: 目標值,可以是 00:02:21 格式的進度或者整數的 TRACK_NR。
  • Header_SOAPACTION: “urn:upnp-org:serviceId:AVTransport#Seek”

響應

iOS實現

需要用到庫

  1. AEXML – 輕量 XML 庫,用於構造和解析XML

構造動作XML

首先利用 AEXML 構造動作 XML 部分。由於所有動作結構相似,寫了個構造方法

根據不同動作構造 XML ,比如 傳遞URI播放動作

傳送動作請求

解析響應

解析請求響應

相關文章