How to send SetAVTransportURI using UPnP C #?

I am trying to send a command to a TV (Sony Bravia KDL-42W800A) to play the video through UPnP. I can detect all UPnP devices on my network using SSDP. Here is an example of a response from a 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 followed Location to get an XML file containing more details on the TV. 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 a TV to play a video if I have a link? I tried to build on what I read online and got this code so far that AVTransportURI should install, but it continues to throw a 500 Internal Server Error.

  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.

+6
source share
2 answers

Try putting some DIDL-Lite metadata in the CurrentURIMetaData parameter. My LG TV refuses to play anything if I just leave this field blank.

For example, the following works for me (naturally, this should be avoided when it is embedded in the external XML structure):

 <?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> 

It may also be necessary to have some special headers in the HTTP response to the request of the TV carrier (at the URL you specify). My LG TV refuses to play if the response of the media file does not have the following headers (case sensitive BTW!):

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

When implementing UPnP / DLNA, many errors can occur. If there is something the TV does not like, it will simply refuse to accept it. Error messages can be quite nonspecific. Many test iterations are necessary in order to understand how various implementations of DLNA devices can be used to work together. Many / most television devices on the market implement only a small subset of the specifications. In my own way.

Search for SetAVTransportURI etc. when searching for code, Github can be useful for figuring out how others implemented things.

+5
source

I encode my Sony BRAVIA KDL-40EX505 and had the same problem.

192.168.0.102 - my computer and server for music files. 192.168.0.10 - Sony TV.

When I do setAVTransportURI, the following happens:

The next POST is sent to the TV

 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 transmits a HEAD request to the URL specified in CurrentURI from the POST above:

 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 

Response to a HEAD request:

 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 answers the first POST request with 200 OK, otherwise you will get 500 Internal Server Error.

Result

So, for Sony BRAVIA KDL-40EX505 it is important to enable

 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. I did this with the php file:

 <?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 through 192.168.0.102:80/music.php?f=geradeaus and returns geradeaus.mp3

Learn the line contentFeatures.dlna.org

I used BubbleUPnP for Android (you need to find a UPnP player that works for you) to play the music file. After that, I opened the Cling Workbench ( http://4thline.org/projects/cling/workbench/ ), selecting my TV, select AVTransport in the tree structure and the "Use Service" button. The URI of the file being played through BubbleUPnP is displayed in the Current URI section. Then I made a HEAD call against this URI using the HEADER I found through WireShark (the important ones are getcontentFeatures.dlna.org, X-AV-Physical-Unit-Info and X-AV-Client-Info, you can also send http GET to your TV: 52323 / upnp / control / AVTransport instead of using WireShark, which returns X-AV-Physical-Unit-Info and X-AV-Client-Info in the response header).

HEAD call for BubbleUPnP on Android:

 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 responds with the correct line 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 
+1
source

Source: https://habr.com/ru/post/982238/


All Articles