How to browse a Digital Living Network Alliance (DLNA) media server
In this tutorial we describe how to browse a Digital Living Network Alliance (DLNA) media server. We will use the Browse method provided by the ContentDirectory service, and we will use cURL to send messages to the server.
This tutorial covers the following steps.
- Find your media server.
- Set up a Browse configuration file for cURL.
- Browse the root directory of the server.
- Browse subdirectories on the server.
- Identify content files.
- Get metadata for a content file.
For a description of how to play a music or video file once you have its metadata, see the AVTransport tutorial.
Before you begin
Before you begin, you will need to do the following.
- Install cURL in your development environment. This tutorial uses cURL to send SOAP messages to the media server.
- Set up a media server on your network. One quick way to set up a media server is to add music files to a USB memory stick and plug it in to a Sony home audio or personal audio device.
Step 1: Discovery - find your media server
To find your media server, use the UPnP SSDP M-SEARCH method, with a search target of urn:schemas-upnp-org:service:ContentDirectory:1
. The response should contain a list of all the media servers available to browse. Identify the media server to browse, and record the IP address and port number from media server’s LOCATION field.
Next, use the full path from the LOCATION field to download the description file for the media server. Locate the ContentDirectory service; it will have a serviceType element with a value of urn:schemas-upnp-org:service:ContentDirectory:1
. Record the value of the associated controlURL element.
You will use the following content directory URL to access the ContentDirectory service, http://{IP}:{PORT}{controlURL}
, where {IP} is the IP address, {PORT} is the port number, and {controlURL} is the controlURL for your chosen media server. The result should be something like /upnp/control/ContentDirectory
.
Step 2: Set up a Browse configuration file for cURL
To simplify the use of cURL commands, create a browse.conf file that has the following contents. Use your content directory URL for the url value in the file.
url = "/upnp/control/ContentDirectory"
header = "Content-Type: text/xml; charset=utf-8"
header = "SOAPAction: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\""
You can include this information in a cURL command using the -K argument.
Step 3: Example Browse with cURL
To get the contents of the root directory, use the Browse command.
The command is sent as a SOAP message. Create the message in a browseroot.data file. You will use cURL to send the message. Note, the root directory is always ObjectID "0".
browse.data
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
<ObjectID>0</ObjectID>
<BrowseFlag>BrowseDirectChildren</BrowseFlag>
<Filter>*</Filter>
<StartingIndex>0</StartingIndex>
<RequestedCount>0</RequestedCount>
<SortCriteria></SortCriteria>
</u:Browse>
</s:Body>
</s:Envelope>
To run this command, enter
To run this command, enter the following in your terminal or command prompt.
Note that the value of the Result element is HTML-escaped XML.
curl -K browse.conf --data-binary @./browseroot.data
The following is an example response, where the content of the Result element has been unescaped.
<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:BrowseResponse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"><Result><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/"
xmlns:arib="urn:schemas-arib-or-jp:elements-1-0/"
xmlns:av="urn:schemas-sony-com:av">
<container id="10" restricted="1" parentID="0"><dc:title>USB</dc:title><upnp:class>object.container</upnp:class><av:mediaClass>M</av:mediaClass><av:removableMedia>1</av:removableMedia></container></DIDL-Lite>
</Result><NumberReturned>1</NumberReturned><TotalMatches>1</TotalMatches><UpdateID>52</UpdateID></u:BrowseResponse></s:Body></s:Envelope>
In this response we see a container with an id attribute of "10". The title of the container is "USB". This is a subdirectory of the root directory.
Step 4: Browse a subdirectory
To get the contents of the subdirectory, use the Browse command again, and change the ObjectID to the container id you want to search, in this example the new ObjectID is set to 10. Create a new SOAP message file named browseDir.data.
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
<ObjectID>10</ObjectID>
<BrowseFlag>BrowseDirectChildren</BrowseFlag>
<Filter>*</Filter>
<StartingIndex>0</StartingIndex>
<RequestedCount>0</RequestedCount>
<SortCriteria></SortCriteria>
</u:Browse>
</s:Body>
</s:Envelope>
Use cURL to run the command.
curl -K browse.conf --data-binary @./browseUSB.data
Repeat this process until the result indicates that the contents include a audio or video file you want to play.
Step 5: Identify a content file
<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:BrowseResponse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"><Result><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/"
xmlns:arib="urn:schemas-arib-or-jp:elements-1-0/"
xmlns:av="urn:schemas-sony-com:av">
<item id="I_01_05_2_-1_00_00_0_35_0_0" restricted="1" parentID="35"><dc:title>01 - Overture.mp3</dc:title><upnp:class>object.item.audioItem.musicTrack</upnp:class><dc:date>2017-05-16T13:37:01</dc:date><res protocolInfo="http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000">http://192.168.1.119:60151/I_01_05_2_-1_00_00_0_35_0_0</res></item></DIDL-Lite>
</Result><NumberReturned>1</NumberReturned><TotalMatches>1</TotalMatches><UpdateID>52</UpdateID></u:BrowseResponse></s:Body></s:Envelope>
A content file is represented by an item element. The URI for the source is provided by the res sub element.
The following is an example response, where the content of the Result element has been unescaped. The URI is /I_01_05_2_-1_00_00_0_35_0_0, and the file ID is I_01_05_2_-1_00_00_0_35_0_0.
Step 6: Get Metadata with cURL
Before you can play the file, you need its metadata.
You also use the Browse method to get the metadata for a file. Set the value of the BrowseFlag element to BrowseMetadata, and set the value of the ObjectID element to the item’s file ID.
Create a new SOAP message file named browseMetadata.data.
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
<ObjectID>I_01_05_2_-1_00_00_0_35_0_0</ObjectID>
<BrowseFlag>BrowseMetadata</BrowseFlag>
<Filter></Filter>
<StartingIndex>0</StartingIndex>
<RequestedCount>0</RequestedCount>
<SortCriteria></SortCriteria>
</u:Browse>
</s:Body>
</s:Envelope>
Use cURL to run the command.
curl -K browse.conf --data-binary @./browseMetadata.data
In the following sample response, the Result element has not been unescaped, as you will need the HTML escaped version to play the file.
<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:BrowseResponse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"><Result><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/"
xmlns:arib="urn:schemas-arib-or-jp:elements-1-0/"
xmlns:av="urn:schemas-sony-com:av">
<item id="I_01_05_2_-1_00_00_0_35_0_0" restricted="1" parentID="35"><dc:title>01 - Overture.mp3</dc:title><upnp:class>object.item.audioItem.musicTrack</upnp:class></item></DIDL-Lite>
</Result><NumberReturned>1</NumberReturned><TotalMatches>1</TotalMatches><UpdateID>52</UpdateID></u