{"id":1785,"date":"2015-09-06T14:02:33","date_gmt":"2015-09-06T13:02:33","guid":{"rendered":"http:\/\/blog.guiguiabloc.fr\/?p=1785"},"modified":"2015-09-08T20:15:55","modified_gmt":"2015-09-08T19:15:55","slug":"jouons-avec-le-wd-tv-live-et-upnp","status":"publish","type":"post","link":"http:\/\/blog.guiguiabloc.fr\/index.php\/2015\/09\/06\/jouons-avec-le-wd-tv-live-et-upnp\/","title":{"rendered":"Jouons avec le WD Tv Live et UPNP"},"content":{"rendered":"<p><a href=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2015\/09\/wdtvlive.png\"><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-1786\" alt=\"wdtvlive\" src=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2015\/09\/wdtvlive-300x176.png\" width=\"300\" height=\"176\" srcset=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2015\/09\/wdtvlive-300x176.png 300w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2015\/09\/wdtvlive.png 330w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Depuis des ann\u00e9es je dispose d&rsquo;un bo\u00eetier <a title=\"http:\/\/www.wdc.com\/fr\/products\/products.aspx?id=1270\" href=\"http:\/\/www.wdc.com\/fr\/products\/products.aspx?id=1270\" target=\"_blank\">WD TV Live<\/a> qui me permet de lire sur la t\u00e9l\u00e9vision les vid\u00e9os stock\u00e9es sur mon <a title=\"https:\/\/www.synology.com\/fr-fr\/products\/\" href=\"https:\/\/www.synology.com\/fr-fr\/products\/\" target=\"_blank\">NAS Synology<\/a>.<br \/>\nEfficace, ce petit bo\u00eetier fonctionne parfaitement bien et a trouver naturellement sa place dans le meuble TV.<\/p>\n<p>J&rsquo;avais un peu oubli\u00e9 sa pr\u00e9sence jusqu&rsquo;\u00e0 me rendre compte que mon syst\u00e8me domotique ne le connaissait pas.<br \/>\nQu&rsquo;a cela ne tienne, c&rsquo;\u00e9tait le moment de jouer avec \ud83d\ude42<\/p>\n<p>Sur mon t\u00e9l\u00e9phone Android, je dispose d&rsquo;une application, <a title=\"https:\/\/play.google.com\/store\/apps\/details?id=com.wdc.wdremote&amp;hl=fr\" href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.wdc.wdremote&amp;hl=fr\" target=\"_blank\">WD TV Remote<\/a>, qui permet de contr\u00f4ler le boitier par wifi.<br \/>\nCela suffit \u00e0 se dire qu&rsquo;il doit \u00eatre possible d&rsquo;interagir avec lui par le r\u00e9seau local.<\/p>\n<p>Qui dit bo\u00eetier multim\u00e9dia, dit forcement <a title=\"https:\/\/fr.wikipedia.org\/wiki\/Universal_Plug_and_Play\" href=\"https:\/\/fr.wikipedia.org\/wiki\/Universal_Plug_and_Play\" target=\"_blank\">UPNP<\/a>. Une petite d\u00e9couverte via l&rsquo;outil gssdp-discover du projet <a title=\"https:\/\/wiki.gnome.org\/Projects\/GUPnP\" href=\"https:\/\/wiki.gnome.org\/Projects\/GUPnP\" target=\"_blank\">gupnp-tools<\/a> nous donne les points d&rsquo;entr\u00e9es du bo\u00eetier (je vous passe l&rsquo;ensemble des \u00e9quipements trouv\u00e9s pour se concentrer sur le WD) :<\/p>\n<pre lang=\"text\">gssdp-discover -i eth0.8 --timeout=5\r\nUsing network interface eth0.8\r\nScanning for all resources\r\nresource available\r\nresource available\r\nUSN:\u00a0\u00a0\u00a0\u00a0\u00a0 uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77::upnp:rootdevice\r\nLocation: http:\/\/wdtvlive:10184\/\r\nresource available\r\nUSN:\u00a0\u00a0\u00a0\u00a0\u00a0 uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77\r\nLocation: http:\/\/wdtvlive:10184\/\r\nresource available\r\nUSN:\u00a0\u00a0\u00a0\u00a0\u00a0 uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77::urn:schemas-upnp-org:device:MediaRenderer:1\r\nLocation: http:\/\/wdtvlive:10184\/\r\nresource available\r\nUSN:\u00a0\u00a0\u00a0\u00a0\u00a0 uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77::urn:schemas-upnp-org:service:AVTransport:1\r\nLocation: http:\/\/wdtvlive:10184\/\r\nresource available\r\nUSN:\u00a0\u00a0\u00a0\u00a0\u00a0 uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77::urn:schemas-upnp-org:service:ConnectionManager:1\r\nLocation: http:\/\/wdtvlive:10184\/\r\nresource available\r\nUSN:\u00a0\u00a0\u00a0\u00a0\u00a0 uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77::urn:schemas-upnp-org:service:RenderingControl:1\r\nLocation: http:\/\/wdtvlive:10184\/<\/pre>\n<p>Une visite sur l&rsquo;url http:\/\/wdtvlive:10184\/ nous donne un joli arbre <a title=\"https:\/\/fr.wikipedia.org\/wiki\/Extensible_Markup_Language\" href=\"https:\/\/fr.wikipedia.org\/wiki\/Extensible_Markup_Language\" target=\"_blank\">xml<\/a><\/p>\n<pre lang=\"text\">...\r\n<serviceList><service><serviceType>urn:schemas-upnp-org:service:AVTransport:1<\/serviceType><serviceId>urn:upnp-org:serviceId:AVTransport<\/serviceId><SCPDURL>MediaRenderer_AVTransport\/scpd.xml<\/SCPDURL><controlURL>MediaRenderer_AVTransport\/control<\/controlURL><eventSubURL>MediaRenderer_AVTransport\/event<\/eventSubURL><\/service>\r\n...<\/pre>\n<p>D\u00e9formation professionnelle oblige, je lance un <a title=\"https:\/\/play.google.com\/store\/apps\/details?id=lv.n3o.shark\" href=\"https:\/\/play.google.com\/store\/apps\/details?id=lv.n3o.shark\" target=\"_blank\">tcpdump<\/a> sur mon t\u00e9l\u00e9phone et j&rsquo;agis sur la t\u00e9l\u00e9commande WD TV Remote.<\/p>\n<p>On retrouve bien le POST http sur le point d&rsquo;entr\u00e9e du bo\u00eetier et la r\u00e9ponse de se dernier.<\/p>\n<pre lang=\"text\">POST \/MediaRenderer_AVTransport\/control HTTP\/1.1\r\nAccept: *\/*\r\nUser-Agent: Twonky-NMC\/7.3-Android (Android\/4.4.2 (Build KOT49H); samsung\/GT-I9505) DLNADOC\/1.50\r\nHost: wdtvlive:10184\r\nSOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#GetTransportInfo\"\r\nContent-Type: text\/xml; charset=\"utf-8\"\r\nContent-Length: 312\r\n\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http:\/\/schemas.xmlsoap.org\/soap\/encoding\/\" xmlns:s=\"http:\/\/schemas.xmlsoap.org\/soap\/envelope\/\"><s:Body><u:GetTransportInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0<\/InstanceID><\/u:GetTransportInfo><\/s:Body><\/s:Envelope>HTTP\/1.1 200 OK\r\n\r\nTransfer-Encoding: chunked\r\nEXT:\r\nCONTENT-TYPE: text\/xml; charset=\"utf-8\"\r\nSERVER: POSIX, UPnP\/1.0, Intel MicroStack\/1.0.1497\r\n1BF\r\n\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n\r\n<s:Envelope s:encodingStyle=\"http:\/\/schemas.xmlsoap.org\/soap\/encoding\/\" xmlns:s=\"http:\/\/schemas.xmlsoap.org\/soap\/envelope\/\"><s:Body><u:GetTransportInfoResponse xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><CurrentTransportState>PAUSED_PLAYBACK<\/CurrentTransportState><CurrentTransportStatus>OK<\/CurrentTransportStatus><CurrentSpeed>1<\/CurrentSpeed><\/u:GetTransportInfoResponse><\/s:Body><\/s:Envelope><\/pre>\n<p>G\u00e9nial \ud83d\ude42<\/p>\n<p>Ne reste plus qu&rsquo;a tester tout cela avec une belle requ\u00eate curl (accrochez-vous \u00e0 votre clavier..) :<\/p>\n<pre lang=\"bash\">curl -H \"Content-Type: text\/xml\" -H 'SOAPACTION: urn:schemas-upnp-org:service:AVTransport:1#GetTransportInfo\"' -XPOST -d '<s:Envelope xmlns: s=\"http:\/\/schemas.xmlsoap.org\/soap\/envelope\" s:encodingStyle=\"http:\/\/schemas.xmlsoap.org\/soap\/encoding\"><s:Body><u:GetTransportInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0<\/InstanceID><\/u:GetTransportInfo><\/s:Body><\/s:Envelope>' http:\/\/wdtvlive:10184\/MediaRenderer_AVTransport\/control\r\n<\/pre>\n<pre lang=\"xml\">\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<s:Envelope s:encodingStyle=\"http:\/\/schemas.xmlsoap.org\/soap\/encoding\/\" xmlns:s=\"http:\/\/schemas.xmlsoap.org\/soap\/envelope\/\"><s:Body><u:GetTransportInfoResponse xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><CurrentTransportState>PAUSED_PLAYBACK<\/CurrentTransportState><CurrentTransportStatus>OK<\/CurrentTransportStatus><CurrentSpeed>1<\/CurrentSpeed><\/u:GetTransportInfoResponse><\/s:Body><\/s:Envelope><\/pre>\n<p>Elle est pas belle la vie ? :p<\/p>\n<p>On voit dans la r\u00e9ponse le mode actuel du bo\u00eetier :<br \/>\n<CurrentTransportState>PAUSED_PLAYBACK<\/CurrentTransportState><\/p>\n<p>En remplacant la m\u00e9thode \u00ab\u00a0GetTransportInfo\u00a0\u00bb par \u00ab\u00a0GetPositionInfo\u00a0\u00bb, le WD Tv nous donne tout un tas d&rsquo;information dont le film actuellement jou\u00e9 :<\/p>\n<pre lang=\"bash\">curl -H \"Content-Type: text\/xml\" -H 'SOAPACTION: urn:schemas-upnp-org:service:AVTransport:1#GetPositionInfo\"' -XPOST -d '<s:Envelope xmlns: s=\"http:\/\/schemas.xmlsoap.org\/soap\/envelope\" s:encodingStyle=\"http:\/\/schemas.xmlsoap.org\/soap\/encoding\"><s:Body><u:GetPositionInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0<\/InstanceID><\/u:GetPositionInfo><\/s:Body><\/s:Envelope>' http:\/\/wdtvlive:10184\/MediaRenderer_AVTransport\/control\r\n<\/pre>\n<pre lang=\"xml\">\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<s:Envelope s:encodingStyle=\"http:\/\/schemas.xmlsoap.org\/soap\/encoding\/\" xmlns:s=\"http:\/\/schemas.xmlsoap.org\/soap\/envelope\/\"><s:Body><u:GetPositionInfoResponse xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><Track>1<\/Track><TrackDuration>00:22:46<\/TrackDuration><TrackMetaData>&lt;DIDL-Lite xmlns=&quot;urn:schemas-upnp-org:metadata-1-0\/DIDL-Lite\/&quot; xmlns:dc=&quot;http:\/\/purl.org\/dc\/elements\/1.1\/&quot; xmlns:upnp=&quot;urn:schemas-upnp-org:metadata-1-0\/upnp\/&quot;&gt;&lt;item id=&quot;BROWSE_TYPE_KEYvideo*~&gt;_&lt;~*BROWSE_SORT_KEY8*~&gt;_&lt;~*BROWSE_GROUP_KEY0*~&gt;_&lt;~*BROWSE_FILTER_KEYBROWSE_FILTER_TERM_STARTfilepath:&lt;_EQUALS_&gt;:\/tmp\/media\/nfs\/NAS\/FILMS\/Naruto\/Naruto.Shippuden.Saison.7BROWSE_FILTER_TERM_END*~&gt;_&lt;~*Naruto Shippuden 170.mkv&quot; parentID=&quot;BROWSE_TYPE_KEYvideo*~&gt;_&lt;~*BROWSE_SORT_KEY8*~&gt;_&lt;~*BROWSE_GROUP_KEY0*~&gt;_&lt;~*BROWSE_FILTER_KEYBROWSE_FILTER_TERM_STARTfilepath:&lt;_EQUALS_&gt;:\/tmp\/media\/nfs\/NAS\/FILMS\/Naruto\/Naruto.Shippuden.Saison.7BROWSE_FILTER_TERM_ENDBROWSE_FILTER_TERM_STARTname:&lt;_EQUALS_&gt;:Naruto Shippuden 170.mkvBROWSE_FILTER_TERM_END*~&gt;_&lt;~*&quot; restricted=&quot;0&quot;&gt;&lt;dc:title&gt;Naruto Shippuden 170.mkv&lt;\/dc:title&gt;&lt;upnp:class&gt;object.item.videoItem&lt;\/upnp:class&gt;&lt;dc:creator&gt;&lt;\/dc:creator&gt;&lt;upnp:genre&gt;Unknown&lt;\/upnp:genre&gt;&lt;upnp:album&gt;&lt;\/upnp:album&gt;&lt;res bitrate=&quot;1230&quot;  protocolInfo=&quot;file-get:*:video\/x-matroska::DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=00000000001000000000000000000000&quot; protection=&quot;&quot; tokenType=&quot;0&quot; duration=&quot;&quot; size=&quot;210161304&quot; colorDepth=&quot;0&quot; ifoFileURI=&quot;&quot; resolution=&quot;--&quot;&gt;file:\/\/\/tmp\/media\/nfs\/NAS\/FILMS\/Naruto\/Naruto.Shippuden.Saison.7\/Naruto%20Shippuden%20170.mkv&lt;\/res&gt;&lt;\/item&gt;&lt;\/DIDL-Lite&gt;<\/TrackMetaData><TrackURI>file:\/\/\/tmp\/media\/nfs\/NAS\/FILMS\/Naruto\/Naruto.Shippuden.Saison.7\/Naruto%20Shippuden%20170.mkv<\/TrackURI><RelTime>00:08:00<\/RelTime><AbsTime>NOT_IMPLEMENTED<\/AbsTime><RelCount>2147483647<\/RelCount><AbsCount>2147483647<\/AbsCount><\/u:GetPositionInfoResponse><\/s:Body><\/s:Envelope><\/pre>\n<p>Ici je vois que Junior regarde le fichier \u00ab\u00a0Naruto Shippuden 20170.mkv\u00a0\u00bb (ok pas tr\u00e8s instructif comme film&#8230;) et ce depuis 8 minutes.<\/p>\n<p>Python disposant de l&rsquo;excellent module<a title=\"http:\/\/lxml.de\/\" href=\"http:\/\/lxml.de\/\" target=\"_blank\"> lxml<\/a> pour parser les fichiers XML, un coup de scripting tout simple permet d&rsquo;isoler les informations importantes :<\/p>\n<pre lang=\"python\">from lxml import etree\r\n\r\ntree = etree.parse('le fichier xml')\r\nfor element in tree.iter('CurrentTransportState'):\r\nresult = element.text\r\nprint \"WD TV Live status: \"+result\r\n\r\ntree = etree.parse('le fichier xml')\r\nfor element in tree.iter('TrackURI'):\r\nfilm = element.text\r\nprint \"WD TV Live joue : \"+film\r\n\r\nWD TV Live status: PLAYING\r\nWD TV joue: file:\/\/\/tmp\/media\/nfs\/NAS\/FILMS\/Naruto\/Naruto.Shippuden.Saison.7\/Naruto%20Shippuden%20170.mkv<\/pre>\n<p>Toutes les commandes disponibles sont r\u00e9f\u00e9renc\u00e9es sur l&rsquo;<a title=\"http:\/\/www.upnp-database.info\/device.jsp?deviceId=244\" href=\"http:\/\/www.upnp-database.info\/device.jsp?deviceId=244\" target=\"_blank\">upnp database<\/a>.<\/p>\n<p>Maintenant le serveur domotique connait l&rsquo;\u00e9tat du boitier WD TV Live ainsi que le fichier jou\u00e9 sur le t\u00e9l\u00e9viseur.<br \/>\nCe qui nous permet par exemple de programmer une surveillance de ce que Junior regarde&#8230;<\/p>\n<pre lang=\"python\">tree = etree.parse('le fichier xml')\r\nfor element in tree.iter('TrackURI'):\r\nfilm = element.text\r\nif \"Pr0n_A_Papa\" in film:\r\n# power off imm\u00e9diat de la t\u00e9l\u00e9vision<\/pre>\n<p>J&rsquo;esp\u00e8re que ce petit billet vous donnera envie d&rsquo;aller explorer un peu les points d&rsquo;entr\u00e9e UPNP des diff\u00e9rents \u00e9quipements de votre domicile \ud83d\ude09<\/p>\n<p>EDIT : Pour \u00e9teindre et allumer votre WD TV Live par une simpe requ\u00eate http, il suffit d&rsquo;envoyer le POST suivant :<br \/>\ncurl -XPOST -d &lsquo;{\u00ab\u00a0remote\u00a0\u00bb:\u00a0\u00bbw\u00a0\u00bb}&rsquo; http:\/\/wdtvlive\/cgi-bin\/toServerValue.cgi<\/p>\n<p>Amusez-vous bien \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Depuis des ann\u00e9es je dispose d&rsquo;un bo\u00eetier WD TV Live qui me permet de lire sur la t\u00e9l\u00e9vision les vid\u00e9os stock\u00e9es sur mon NAS Synology. Efficace, ce petit bo\u00eetier fonctionne parfaitement bien et a trouver naturellement sa place dans le &hellip; <a href=\"http:\/\/blog.guiguiabloc.fr\/index.php\/2015\/09\/06\/jouons-avec-le-wd-tv-live-et-upnp\/\">Read More <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[137],"tags":[170,216],"_links":{"self":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1785"}],"collection":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/comments?post=1785"}],"version-history":[{"count":8,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1785\/revisions"}],"predecessor-version":[{"id":1794,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1785\/revisions\/1794"}],"wp:attachment":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/media?parent=1785"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/categories?post=1785"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/tags?post=1785"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}