简体   繁体   English

如何使用UPnP C#发送SetAVTransportURI?

[英]How to send SetAVTransportURI using UPnP C#?

I'm trying to send a command to my TV (Sony Bravia KDL-42W800A) to play a video through UPnP. 我正在尝试向我的电视(Sony Bravia KDL-42W800A)发送命令,通过UPnP播放视频。 I can discover all UPnP devices on my network using SSDP. 我可以使用SSDP发现网络上的所有UPnP设备。 Here is a sample response from the TV: 以下是来自电视的示例回复:

HTTP/1.1 200 OK
CACHE-CONTROL: max-age=1800
EXT: 
LOCATION: http://192.168.1.11:52323/dmr.xml
SERVER: Linux/2.6 UPnP/1.0 KDL-42W800A/1.7
ST: urn:schemas-upnp-org:service:AVTransport:1
USN: uuid:00000000-0000-1010-8000-d8d43c73618b::urn:schemas-upnp-org:service:AVTransport:1
X-AV-Physical-Unit-Info: pa="BRAVIA KDL-42W800A";
X-AV-Server-Info: av=5.0; cn="Sony Corporation"; mn="BRAVIA KDL-42W800A"; mv="1.7";

From this I have followed the Location to retrieve the XML file containing more specifics on the TV. 从这里我已经按照位置检索包含电视上更多细节的XML文件。 Given below: 给出如下:

<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0"
      xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11"
      xmlns:df="http://schemas.microsoft.com/windows/2008/09/devicefoundation">
  <specVersion>
    <major>1</major>
    <minor>0</minor>
  </specVersion>
  <device>
    <deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
    <friendlyName>BRAVIA KDL-42W800A</friendlyName>
    <manufacturer>Sony Corporation</manufacturer>
    <manufacturerURL>http://www.sony.net/</manufacturerURL>
    <modelName>KDL-42W800A</modelName>
    <modelNumber>MINT1.7.0.1</modelNumber>
    <UDN>uuid:00000000-0000-1010-8000-d8d43c73618b</UDN>
    <dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMR-1.50</dlna:X_DLNADOC>
    <microsoft:magicPacketWakeSupported xmlns:microsoft="urn:schemas-microsoft-com:WMPNSS-1-0">1</microsoft:magicPacketWakeSupported>
    <iconList>
      <icon>
        <mimetype>image/png</mimetype>
        <width>32</width>
        <height>32</height>
        <depth>24</depth>
        <url>/MediaRenderer_32x32.png</url>
      </icon>
      <icon>
        <mimetype>image/png</mimetype>
        <width>48</width>
        <height>48</height>
        <depth>24</depth>
        <url>/MediaRenderer_48x48.png</url>
      </icon>
      <icon>
        <mimetype>image/png</mimetype>
        <width>60</width>
        <height>60</height>
        <depth>24</depth>
        <url>/MediaRenderer_60x60.png</url>
      </icon>
      <icon>
        <mimetype>image/png</mimetype>
        <width>120</width>
        <height>120</height>
        <depth>24</depth>
        <url>/MediaRenderer_120x120.png</url>
      </icon>
      <icon>
        <mimetype>image/jpeg</mimetype>
        <width>32</width>
        <height>32</height>
        <depth>24</depth>
        <url>/MediaRenderer_32x32.jpg</url>
      </icon>
      <icon>
        <mimetype>image/jpeg</mimetype>
        <width>48</width>
        <height>48</height>
        <depth>24</depth>
        <url>/MediaRenderer_48x48.jpg</url>
      </icon>
      <icon>
        <mimetype>image/jpeg</mimetype>
        <width>60</width>
        <height>60</height>
        <depth>24</depth>
        <url>/MediaRenderer_60x60.jpg</url>
      </icon>
      <icon>
        <mimetype>image/jpeg</mimetype>
        <width>120</width>
        <height>120</height>
        <depth>24</depth>
        <url>/MediaRenderer_120x120.jpg</url>
      </icon>
    </iconList>
    <serviceList>
      <service>
        <serviceType>urn:schemas-upnp-org:service:RenderingControl:1</serviceType>
        <serviceId>urn:upnp-org:serviceId:RenderingControl</serviceId>
        <SCPDURL>/RenderingControlSCPD.xml</SCPDURL>
        <controlURL>/upnp/control/RenderingControl</controlURL>
        <eventSubURL>/upnp/event/RenderingControl</eventSubURL>
      </service>
      <service>
        <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
        <serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
        <SCPDURL>/ConnectionManagerSCPD.xml</SCPDURL>
        <controlURL>/upnp/control/ConnectionManager</controlURL>
        <eventSubURL>/upnp/event/ConnectionManager</eventSubURL>
      </service>
      <service>
        <serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
        <serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
        <SCPDURL>/AVTransportSCPD.xml</SCPDURL>
        <controlURL>/upnp/control/AVTransport</controlURL>
        <eventSubURL>/upnp/event/AVTransport</eventSubURL>
      </service>
      <service>
        <serviceType>urn:dial-multiscreen-org:service:dial:1</serviceType>
        <serviceId>urn:dial-multiscreen-org:serviceId:dial</serviceId>
        <SCPDURL>/DIALSCPD.xml</SCPDURL>
        <controlURL>/upnp/control/DIAL</controlURL>
        <eventSubURL></eventSubURL>
      </service>
      <service>
        <serviceType>urn:schemas-sony-com:service:IRCC:1</serviceType>
        <serviceId>urn:schemas-sony-com:serviceId:IRCC</serviceId>
        <SCPDURL>/IRCCSCPD.xml</SCPDURL>
        <controlURL>http://192.168.1.11/sony/IRCC</controlURL>
        <eventSubURL></eventSubURL>
      </service>
      <service>
        <serviceType>urn:schemas-sony-com:service:ScalarWebAPI:1</serviceType>
        <serviceId>urn:schemas-sony-com:serviceId:ScalarWebAPI</serviceId>
        <SCPDURL>/ScalarWebApiSCPD.xml</SCPDURL>
        <controlURL>/upnp/control/ScalarAPI</controlURL>
        <eventSubURL></eventSubURL>
      </service>
    </serviceList>
    <av:X_MaxBGMCount xmlns:av="urn:schemas-sony-com:av">64</av:X_MaxBGMCount>
    <av:X_StandardDMR xmlns:av="urn:schemas-sony-com:av">1.1</av:X_StandardDMR>
    <av:X_ScreenResolution xmlns:av="urn:schemas-sony-com:av">2K</av:X_ScreenResolution>
    <av:X_IRCCCodeList xmlns:av="urn:schemas-sony-com:av">
      <av:X_IRCCCode command="Power">AAAAAQAAAAEAAAAVAw==</av:X_IRCCCode>
      <av:X_IRCCCode command="Power ON">AAAAAQAAAAEAAAAuAw==</av:X_IRCCCode>
      <av:X_IRCCCode command="Power OFF">AAAAAQAAAAEAAAAvAw==</av:X_IRCCCode>
    </av:X_IRCCCodeList>
    <pnpx:X_compatibleId>MS_DigitalMediaDeviceClass_DMR_V001</pnpx:X_compatibleId>
    <pnpx:X_deviceCategory>MediaDevices</pnpx:X_deviceCategory>
    <pnpx:X_hardwareId>VEN_0106&amp;DEV_0006&amp;REV_01</pnpx:X_hardwareId>
    <df:X_deviceCategory>Display.TV Multimedia.DMR</df:X_deviceCategory>
    <av:X_TrackID_DeviceInfo xmlns:av="urn:schemas-sony-com:av">
      <av:X_TrackID_BaseURL>http://192.168.1.11/sony/BgmSearch</av:X_TrackID_BaseURL>
    </av:X_TrackID_DeviceInfo>
    <av:X_DIALEX_DeviceInfo xmlns:av="urn:schemas-sony-com:av"> 
        <av:X_DIALEX_AppsListURL>http://192.168.1.11/DIAL/sony/applist</av:X_DIALEX_AppsListURL>
    </av:X_DIALEX_DeviceInfo>
    <av:X_ScalarWebAPI_DeviceInfo xmlns:av="urn:schemas-sony-com:av">
      <av:X_ScalarWebAPI_Version>1.0</av:X_ScalarWebAPI_Version>
      <av:X_ScalarWebAPI_BaseURL>http://192.168.1.11/sony</av:X_ScalarWebAPI_BaseURL>
      <av:X_ScalarWebAPI_ServiceList>
        <av:X_ScalarWebAPI_ServiceType>guide</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>system</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>videoScreen</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>audio</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>avContent</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>recording</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>appControl</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>browser</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>notification</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>cec</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>accessControl</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>irCommandProxy</av:X_ScalarWebAPI_ServiceType>
      </av:X_ScalarWebAPI_ServiceList>
    </av:X_ScalarWebAPI_DeviceInfo>
    <av:X_RDIS_DeviceInfo xmlns:av="urn:schemas-sony-com:av">
      <av:X_RDIS_Version>1.0</av:X_RDIS_Version>
      <av:X_RDIS_SESSION_CONTROL>false</av:X_RDIS_SESSION_CONTROL>
      <av:X_RDIS_ENTRY_PORT>20677</av:X_RDIS_ENTRY_PORT>
    </av:X_RDIS_DeviceInfo>
  </device>
</root>

Using this information, how can I request the TV to play a video if I have the link? 使用此信息,如果我有链接,如何请求电视播放视频? I have tried to based on what I've read online and got this code so far, which is supposed to set the AVTransportURI, but it keeps on giving error 500 Internal Server Error. 我试图根据我在网上阅读的内容并获得此代码到目前为止,这应该设置AVTransportURI,但它一直给出错误500内部服务器错误。

    private const string SetAvTransportURIXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                                                    "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" +
                                                        "<s:Body>" +
                                                            "<u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\">" +
                                                                "<InstanceID>0</InstanceID>" +
                                                                "<CurrentURI>{0}</CurrentURI>" +
                                                                "<CurrentURIMetaData></CurrentURIMetaData>" +
                                                            "</u:SetAVTransportURI>" +
                                                        "</s:Body>" +
                                                    "</s:Envelope>";

    public void PlayVideo(string videoLink)
    {
        byte[] bytes;
        bytes = Encoding.UTF8.GetBytes(String.Format(SetAvTransportURIXml, videoLink));

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://192.168.1.11:52323/upnp/control/AVTransport");
        request.Headers.Add("SOAPAction", "\"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"");
        request.ContentType = "text/xml; encoding=\"utf-8\"";
        request.ContentLength = bytes.Length;
        request.Method = "POST";
        Stream requestStream = request.GetRequestStream();
        requestStream.Write(bytes, 0, bytes.Length);
        requestStream.Flush();
        requestStream.Close();
        var response = (HttpWebResponse) request.GetResponse();
        if (response.StatusCode == HttpStatusCode.OK)
        {
            Stream responseStream = response.GetResponseStream();
            if (responseStream == null) return;
            string responseStr = new StreamReader(responseStream).ReadToEnd();
            Console.WriteLine(responseStr);
        }
    }

Any help would be appreciated, thanks. 任何帮助将不胜感激,谢谢。

Try to put some DIDL-Lite meta-data in the CurrentURIMetaData parameter. 尝试在CurrentURIMetaData参数中放入一些DIDL-Lite元数据。 My LG TV refuses to play anything if I just leave that field empty. 如果我把那个场地留空,我的LG电视拒绝播放任何东西。

For example the following works for me (naturally this needs to be escaped when embedded in the outer XML structure): 例如,以下对我有用(当然,当嵌入在外部XML结构中时需要进行转义):

<?xml version="1.0"?>
<DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sec="http://www.sec.co.kr/">
<item id="f-0" parentID="0" restricted="0">
    <dc:title>Video</dc:title>
    <dc:creator>Anonymous</dc:creator>
    <upnp:class>object.item.videoItem</upnp:class>
    <res protocolInfo="http-get:*:video/mp4:DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000">{0}</res>
</item>
</DIDL-Lite>

Also there may be a need to have some special headers in the HTTP response to the TV's media request (at the URL you supply). 此外,可能需要在对电视媒体请求的HTTP响应中(在您提供的URL处)具有一些特殊标头。 My LG TV refuses to play unless the media file response has the following headers (case-sensitive BTW!): 我的LG电视拒绝播放,除非媒体文件响应具有以下标题(区分大小写的BTW!):

contentFeatures.dlna.org: DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000
transferMode.dlna.org: Streaming

There are a lot of things that can go wrong when implementing UPnP/DLNA. 实施UPnP / DLNA时可能会出现很多问题。 If there is anything that the TV does not like, it will just refuse to accept it. 如果电视不喜欢任何东西,它就会拒绝接受它。 The error messages can be rather unspecific. 错误消息可能非常不明确。 Lots of testing iterations are needed to figure how different DLNA device implementations can be coerced to co-operate. 需要大量的测试迭代来确定如何强制不同的DLNA设备实现以进行协作。 Many/most of the TV devices on the market implement only a small subset of the specs. 市场上的许多/大多数电视设备仅实现了规格的一小部分。 In their own way. 以他们自己的方式。

Searching for SetAVTransportURI etc. at Github code search can be helpful for figuring out how others have implemented things. 在Github代码搜索中搜索SetAVTransportURI等有助于弄清楚其他人是如何实现的。

I'm coding for my Sony BRAVIA KDL-40EX505 and had the same problem. 我正在为我的索尼BRAVIA KDL-40EX505编码并遇到同样的问题。

192.168.0.102 is my computer and server for the music files. 192.168.0.102是我的音乐文件的计算机和服务器。 192.168.0.10 is the Sony TV. 192.168.0.10是索尼电视。

When I do the setAVTransportURI, the following happens: 当我执行setAVTransportURI时,会发生以下情况:

The following POST is sent to the TV 以下POST将发送到电视

POST /upnp/control/AVTransport HTTP/1.1
Host: 192.168.0.10:52323
Connection: keep-alive
Content-Length: 442
Cache-Control: no-cache
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Content-Type: text/xml;charset="UTF-8"
Soapaction: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
Postman-Token: a8169b28-fb09-7029-60a9-b7e2641dc1d6
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
         <InstanceID>0</InstanceID>
         <CurrentURI>http://192.168.0.102:80/music.php?f=geradeaus</CurrentURI>
         <CurrentURIMetaData></CurrentURIMetaData>
      </u:SetAVTransportURI>
   </s:Body>
</s:Envelope>

The TV sents a HEAD request to the URL specified in the CurrentURI from the POST above: TV从上面的POST中将HEAD请求发送到CurrentURI中指定的URL:

HEAD /music.php?f=geradeaus HTTP/1.1
getcontentFeatures.dlna.org: 1
X-AV-Physical-Unit-Info: pa="BRAVIA KDL-40EX505";
X-AV-Client-Info: av="5.0"; cn="Sony Corporation"; mn="BRAVIA KDL-40EX505"; mv="1.7";
Host: 192.168.0.102:80

The answer for the HEAD request is: HEAD请求的答案是:

HTTP/1.1 200 OK
Date: Sat, 05 Mar 2016 20:58:58 GMT
Server: Apache/2.4.9 (Win64) PHP/5.5.12
X-Powered-By: PHP/5.5.12
Content-Length: 9622288
transferMode.dlna.org: Streaming
Accept-Ranges: bytes
Cache-Control: no-cache
contentFeatures.dlna.org: DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01700000000000000000000000000000
Content-Type: audio/mpeg

If everything worked, the TV responses the first POST request with a 200 OK, otherwise you get a 500 Internal Server Error. 如果一切正常,电视会以200 OK响应第一个POST请求,否则会出现500内部服务器错误。

Result 结果

So, for the Sony BRAVIA KDL-40EX505 it is important to enable 因此,对于索尼BRAVIA KDL-40EX505,重要的是启用

transferMode.dlna.org: Streaming

and

contentFeatures.dlna.org: DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01700000000000000000000000000000

in the response of the HEADER request to the audio or video file. 在HEADER请求对音频或视频文件的响应中。 I did that with a php file: 我用php文件做到了:

<?php 
   $file = $_GET['f'].'.mp3';

   header('Content-Length: '.filesize($file));
   header('Content-Type: audio/mpeg');
   header('transferMode.dlna.org: Streaming');
   header('Accept-Ranges: bytes');
   header('Cache-Control: no-cache');
   header('contentFeatures.dlna.org: DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01700000000000000000000000000000');

   fpassthru(fopen($file, 'rb'));
   exit;
?>

This is called via 192.168.0.102:80/music.php?f=geradeaus and returns geradeaus.mp3 这是通过192.168.0.102:80/music.php?f=geradeaus调用并返回geradeaus.mp3

Find out the contentFeatures.dlna.org string 找出contentFeatures.dlna.org字符串

I used BubbleUPnP for Android (you have to find a UPnP player that works for you) to play a music file. 我使用BubbleUPnP for Android(你必须找到适合你的UPnP播放器)才能播放音乐文件。 After that I opened Cling Workbench ( http://4thline.org/projects/cling/workbench/ ) choose my TV, choose AVTransport in the treeview and the "Use Service" button. 之后我打开Cling Workbench( http://4thline.org/projects/cling/workbench/ )选择我的电视,在树视图中选择AVTransport并选择“使用服务”按钮。 The URI of the file played via BubbleUPnP is displayed under "Current URI". 通过BubbleUPnP播放的文件的URI显示在“当前URI”下。 Then I did a HEAD call against that URI with the HEADERs I found via WireShark (important are getcontentFeatures.dlna.org, X-AV-Physical-Unit-Info and X-AV-Client-Info, you could also send a http GET to yourTV:52323/upnp/control/AVTransport instead of using WireShark, which returns X-AV-Physical-Unit-Info and X-AV-Client-Info in the response header). 然后我用通过WireShark找到的HEADER对该URI进行了HEAD调用(重要的是getcontentFeatures.dlna.org,X-AV-Physical-Unit-Info和X-AV-Client-Info,你也可以发送一个http GET到yourTV:52323 / upnp / control / AVTransport而不是使用WireShark,它在响应头中返回X-AV-Physical-Unit-Info和X-AV-Client-Info。

HEAD call to BubbleUPnP on Android: HEAD在Android上调用BubbleUPnP:

HEAD /external/audio/media/8588.mp3 HTTP/1.1
Host: 192.168.0.12:57645
Connection: keep-alive
Cache-Control: no-cache
X-AV-Physical-Unit-Info: pa="BRAVIA KDL-40EX505";
X-AV-Client-Info: av="5.0"; cn="Sony Corporation"; mn="BRAVIA KDL-40EX505"; mv="1.7";
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
getcontentFeatures.dlna.org: 1
Postman-Token: 39fabd1c-7464-6631-2645-c62cdca6f83d
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4

BubbleUPnP answers with the correct contentFeatures.dlna.org string BubbleUPnP使用正确的contentFeatures.dlna.org字符串回答

HTTP/1.1 200 OK
Date: Sat, 05 Mar 2016 21:31:37 GMT
Server: Android, UPnP/1.0 DLNADOC/1.50, BubbleUPnP/2.6.0.2-amz
Cache-Control: no-cache
transferMode.dlna.org: Streaming
contentFeatures.dlna.org: DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01700000000000000000000000000000
Content-Type: audio/mpeg
Last-Modified: Sat, 05 Mar 2016 18:21:43 GMT
Content-Length: 8523162
Accept-Ranges: bytes

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM