Sky+HD DNLA SkyPlay2/SkyPlay Endpoint update

Just a quick post to say that as of last night’s Sky+HD box firmware OTA update, Sky have updated the DNLA endpoint for SkyPlay requests to /SkyPlay, from /SkyPlay2.

You’ll need to update any SkyPlay requests to this, or get an “Invalid Action” back from the UPnP/DNLA endpoint.

  • sea2wright

    It’s changed yet again with R007 firmware on my box from /SkyPlay to /444D5276-3253-6B79-436F-0019fbca82ccSkyPlay
    Looks like it’s incorporating a URN which maybe box specific.

    • lgladdy

      sea2wright Ha. Fun times. Is this still provided by UPnP description xml files though?

      • sea2wright

        lgladdy sea2wright I need to investigate further but I guess so as with correct USERAGENT works without modification.

        • lgladdy

          sea2wright lgladdy Yup – indeed. It’s a device specific ID but is still provided in the description file. Weird. I wonder why NDS keep changing this stuff. It’s not like it makes it harder.. maybe they’re just trolling us 🙂

        • lgladdy

          sea2wright lgladdy Also – has SkyRC changed? It looks like it has a way to reset the box to factory defaults now? I wonder if this is a new kind of remote support system Sky are planning…

        • sea2wright

          lgladdysea2wrightNo SkyRC needs preceeding with URN but has same options as before: CurrentPresetNameList : FactoryDefaults thought if there had been a change it would let me change the value but it doesn’t. Don’t know why this has been introduced but wonder if it could have anything to do with tightening security for the long awaited Planner Sharing?

        • BruH5200

          sea2wright lgladdy I’ve not played with this stuff for a while, but I need to fix my ipad remote (iRule).  What headers do I need to retrieve the description0.xml ?  I’m gettin unauthorized.

  • Rhysorwin

    Thanks for all of your work on the Sky remote, it works really well. I’m trying to integrate it into SiriProxy and am having trouble adapting the code. Does this need to be changed? SOAPACTION: “urn:schemas-nds-com:service:SkyPlay:2#Pause” (by removing the 2?)

    Any help would be awesome.

  • Glenn Edwards

    Hi All,
    I’ve cracked it!! By passing the correct messages to the CreateRecordSchedule SOAP action of the SkyBook service, I can now do the following:
    Create a new recording (optionally with keep and/or series link)
     Add a series link to an existing recording
    In order to record something, you first need to know what it is you want to record. To do that you can either check the results of the now and next service:{channel id}/now/nn/{1 to 4}
    which will return JSON data similar to below:
    {“listings”:{“1251”:[{“m”:[504,7500,0,1,”–“],”rr”:”R”,”s”:1381350900,”t”:”Just Go with It”,”url”:”"},{"m":[538,2100,0,1,"–"],"rr":"S","s":1381358400,"sid":37903,"t":"Mobs Mheiriceá”,”url”:”″}]}}
    or check the results of the EPG service:{channel id}/{yyyy-mm-dd}/{page 0 to 4}.json
    which will return JSON data similar to below:
    {“listings”:{“1251”:[{“d”:”The latest stories.”,”m”:[246,1260,0,1,”–“],”rr”:”S”,”s”:1381250400,”sid”:7497,”t”:”Nuacht RTÉ”},{“d”:”The latest national and international news.”,”m”:[768,3540,0,1,”–“],”rr”:”S”,”s”:1381251660,”sid”:13306,”t”:”RTÉ News: Six One”},{“d”:”Craft competition. Judges Sonya Lennon, Brian McGee, Louise Kennedy and Paul Costelloe announce the winner of Craft Master 2013.”,”m”:[785,1800,0,1,”–“],”rr”:”S”,”s”:1381255200,”sid”:15650,”t”:”Craft Master”},{“d”:”An exhausted Janine plays right into Michael’s hands when Scarlett’s safety is plunged into jeopardy. Guilt eats away at Dexter when he has doubts about his upcoming operation.”,”m”:[408,1800,0,1,”–“],”rr”:”S”,”s”:1381257000,”sid”:24480,”t”:”EastEnders”},{“d”:”Paddy is
    Note the {channel id} in the above service calls, is the decimal representation of the internal Sky channel number e.g. Channel 4 = 1621 not 104
    Incidentally, you can get the current channel list from sky by calling
    From the above listings, the most important information you need, in order to be able to set a recording are the channel number, the “sid” if you want to series link, and you also need the program code.
    In the above JSON results the channel number is 1251, so is pretty easy to spot as it’s just after the word “listings” in the results. The program code is contained within the “m” field, that is of the form “[246,1260,0,1,”–“]”. In this example the program code is 246. Combined with the channel number, this is the unique id that you need in order to identify and set a recording.
    part 2 to follow in next post…..

  • Glenn Edwards

    Now, how to record.You need to call the CreateRecordSchedule SOAP action of the SkyBook service. Please see elsewhere in this blog for how to do that. The CreateRecordSchedule takes an Elements parameter, to which you must pass a specially constructed XML document (defined in UPnP as a RecordSchedulePart). The form of this XML document is below:
    <?xml version=”1.0″ encoding=”UTF-8″?>
    <srs xmlns=”urn:schemas-upnp-org:av:srs”
     xsi:schemaLocation=” urn:schemas-upnp-org:av:srs“>
      <desiredRecordQuality type=”DEFAULT”></desiredRecordQuality> –>
      <scheduledProgramCode type=”nds.com_URI”>xsi://4E3;F6~20131114T230500Z–PT01H00M00S?keep=0&type=1&seriesid=1D49</scheduledProgramCode>
    When passing this parameter you may need to escape <>& with <  >  & etc
    In the above XML document, there is a URI that you must pass to identify the recording:
    This is of the form:
    xsi://{channel no hex};{prog code hex}~{start datetime yyyymmddThhmmssZ}–{duration PThhHmmMssS}?keep=0&type=1&seriesid={sid in hex}
    Just take the channel number, program code, and sid (series id) from the listings, convert them to hex, and put the in the URI. From my testting, the value for the start datetime, and duration are unimportant, as long as you pass a valid date, and duration they will be accepted. The actual start time and duration are set for you by the box when the recording is scheduled.
    Sometimes I’ve found that the channel number when passed, has to have 1 added to it, but not always. Please experiment.
    Note that desiredRecordQuality is required, but does nothing. I’ve tried the other available settings HD, ED, SD and they do nothing. The Sky box always defaults to AUTO, which is based on the program type e.g. HD or SD
    Set “keep = 1” if you want the recording scheduled with keep selected.
    The “type” parameter I do not understand, but setting it to 1 seemed to work. If someone wants to try other values and let me know the result then please do.

  • Glenn Edwards

    When you’ve successfully created a recording schedule using the above, you will receive back a record schedule id in the form RSE:{schedule id}
    You can call the GetRecordSchedule action with the RSE:{schedule id} to see the record schedule object.
    Like wise you can get the record task associated with the record schedule by calling the GetRecordTask action and passing in RT:{schedule id}.
    You can enable and disable record tasks by calling EnableRecordTask, and DisableRecordTask accordingly. This does stop and start an in progress recording, or even prevents a recording from starting entirely.
    If a recording has not yet started, you can call DeleteRecordSchedule and pass the RSE:{schedule id} to delete the recording schedule, and associated record task objects. If the recording has started you cannot delete the schedule.
    When a recording has completed, the record schedule, and record task objects still exist. This is normal, but they just state the recording has completed, indicate errors with the recording, missed bits etc.
    If a record schedule has started, or completed, you can’t delete it with DeleteRecordSchedule. You must call the Browse action of the Browse service to find the entry in the planner, and then call DestroyObject passing in the object id from the planner entry.
    This is probably the best way to delete any record schedule / task, as they all have planner entries. So instead of calling DeleteRecordSchedule, just call DestroyObject instead. Then it won’t matter what the status of the recording is.

    So, how to add a series link to an existing scheduled recording?
    You need to call CreateRecordSchedule with a different XML document in the Element parameter, again with escaped characters where required.
    <?xml version=”1.0″ encoding=”UTF-8″?>
    <srs xmlns=”urn:schemas-upnp-org:av:srs”
     xsi:schemaLocation=” urn:schemas-upnp-org:av:srs“>
      <recordDestination mediaType=”HDD”>Hard Disk</recordDestination>
      <matchingID type=”nds.com_SID”>E6F1</matchingID>
    In the above example, replace the matchingId with the hex equivalent of the SID (series id) from the listings, also, you need to set the vx:X_NDSRecordTaskID to the if of the record task that you want to set the series link. Remember the record task id is the same as the record schedule id, just prepended with RT: instead of RSE:
    When successfull, the series link will be set, and you will get back a new record schedule id of the form RSS:{schedule id}
    There will now be two record schedule objects, which you can verify with GetRecordSchedule. You’ll notice the record task, if you call GetRecordTask, is now associated with the new RSS recording schedule. I’m not sure why this is, but it all works fine.
    I have no idea how to remove a series link, so if someone can figure that out?
    Oh yeah, when you call DestroyObject on a planner entry, it isn’t destroyed or deleted, but is moved to the recycle bin. You can verify this by calling the Browse action on container 6, which is the recycle bin. To delete a planner entry, completely, you have get the new id, which in container 6 is of the form RECYC:{id}.  Once you have removed a planner entry from the recycle bin, any associated record schedules and tasks will be deleted too.
    Any questions, or problems using the above, please let me know,

  • Glenn Edwards

    Sorry should have added, that when setting a recording, you don’t have to pass the seriesid parameter in the xsi:// URI

    If you don’t want to set a series link when you set a recording, don’t pass that parameter e.g.:

  • rhysdojones

    Hi there,
    Anyone workout what the DLNA endpoint has been updated to after the recent software update?

  • lgladdy

    rhysdojones  Hey Rhys,

    Most of us are using software that uses UPnP detection to abstract needing to know what the DLNA endpoint is. You’d be better of to switch to that kind of discovery in your app too!

  • cheneysroad

    I am having trouble creating an IP driver so I would like some help please

  • cheneysroad

    I am trying to create a 1 way control driver to mimic the original Sky HD remote, I will be using a 3rd party remote which can issue commands over IP.I do not need to use any replies. If I could see an example of one of the strings it would make it easier for me

  • Mitchell Mann

    I know I’m late to the party here, but after using the Sky+ app recently to show off some photos on my iPhone to guests we had round I wondered if there was a Mac (or PC) app that allowed photos to be shared from a computer to the TV via the Sky+ box as I’ve many more on my Mac than I have on my iPhone. I used Wireshark to intercept the traffic to see how it worked and it *seemed* rather simple:-

    1. The app on the iPhone (or iPad/iPodTouch) opens a local port that acts as a web server, 51178 in my case although I’m sure this is randomly assigned.
    2. After initiating a TCP connection to the Sky+ box the app sends this: GET /photo-viewing/start?uri= HTTP/1.1 to port 49159 of the Sky+ box ( being the IP of my iPhone and photo1763828098 being the jpg photo file on my iPhone.
    3. The photo is streamed from the iPhone to the Sky+ box and displayed.

    Quite simple. I thought I could initiate a TCP connection with netcat to port 49159 of the Sky+ box and substitute the IP of my iPhone for the IP of a local web server and specify port 80 and replace photo1763828098 with whatever photo file was stored in the home/root directory of the web server, but nothing happened. So I did some searching and came across this old blog and upon reviewing Liam’s excellent I realise there are probably a few more steps required to make this work but my Python skills aren’t even noob level and as it already seems a pretty capable script I thought maybe adding this extra functionality would be quicker/easier than for me to code something from the ground up in a language I’m more familiar with.

    I hope this sparks some renewed interest and apologies for the spam as I notice there are a couple of related threads on this blog which I shall be copying and pasting this post to verbatim