Changeset 142
- Timestamp:
- 2014-01-05 12:41:24 (11 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/I_Sonos1.xml ¶
r141 r142 280 280 artist = upnp.decode(didlTable["r:albumArtist"] or didlTable["dc:creator"] or artist) 281 281 album = upnp.decode(didlTable["upnp:album"] or album) 282 if (didlTable["dc:title"] == nil 283 and didlTable["r:albumArtist"] == nil 284 and didlTable["r:streamContent"] ~= nil) then 285 local title2, artist2 = didlTable["r:streamContent"]:match(".*|TITLE ([^|]*)|ARTIST ([^|]*)") 286 title = upnp.decode(title2 or title) 287 artist = upnp.decode(artist2 or artist) 282 details = upnp.decode(didlTable["r:streamContent"] or details) 283 local title2, artist2 = details:match(".*|TITLE ([^|]*)|ARTIST ([^|]*)") 284 if (title2 ~= nil) then 285 title = title2 286 end 287 if (artist2 ~= nil) then 288 artist = artist2 288 289 end 289 290 if (didlTable["upnp:albumArtURI"] ~= nil) then 290 291 albumArt = upnp.decode(didlTable["upnp:albumArtURI"]) 291 292 end 292 if (artist ~= "" oralbum ~= "") then293 if (artist ~= "" and album ~= "") then 293 294 complement = string.format(" (%s, %s)", artist, album) 295 elseif (artist ~= "") then 296 complement = string.format(" (%s)", artist) 297 elseif (album ~= "") then 298 complement = string.format(" (%s)", album) 294 299 end 295 300 elseif (didlTable["upnp:class"] == "object.item.audioItem.audioBroadcast") then … … 423 428 changed = setData("Volume", "0", device, changed) 424 429 changed = setData("Mute", "0", device, changed) 425 changed = setData("SavedQueues", " <DIDL-Lite></DIDL-Lite>", device, changed)426 changed = setData("FavoritesRadios", " <DIDL-Lite></DIDL-Lite>", device, changed)427 changed = setData("Queue", " <DIDL-Lite></DIDL-Lite>", device, changed)430 changed = setData("SavedQueues", "", device, changed) 431 changed = setData("FavoritesRadios", "", device, changed) 432 changed = setData("Queue", "", device, changed) 428 433 changed = setData("GroupCoordinator", "", device, changed) 429 434 changed = setData("ZonePlayerUUIDsInGroup", "", device, changed) … … 623 628 end 624 629 630 local function parseSavedQueues(xml) 631 local result = "" 632 local title, id 633 for title, id in xml:gmatch("<container%s?[^>]->.-<dc:title%s?[^>]->(.-)</dc:title>.-<res%s?[^>]->file:///jffs/settings/savedqueues.rsq#(%d+)</res>.-</container>") do 634 title = upnp.decode(title) 635 result = result .. id .. "@" .. title .. "\n" 636 end 637 return result 638 end 639 640 local function parseFavoritesRadios(xml) 641 local result = "" 642 local title, res 643 for title, res in xml:gmatch("<item%s?[^>]->.-<dc:title%s?[^>]->(.-)</dc:title>.-<res%s?[^>]->(.-)</res>.-</item>") do 644 title = upnp.decode(title) 645 result = result .. res .. "@" .. title .. "\n" 646 end 647 return result 648 end 649 650 local function parseQueue(xml) 651 local result = "" 652 local title 653 for title in xml:gmatch("<item%s?[^>]->.-<dc:title%s?[^>]->(.-)</dc:title>.-</item>") do 654 title = upnp.decode(title) 655 result = result .. title .. "\n" 656 end 657 return result 658 end 659 625 660 local function refreshNow(device, force) 626 661 debug("refreshNow: start") 627 662 628 663 if (upnp.proxyVersionAtLeast(1) and force == false) then 629 return 664 return "" 630 665 end 631 666 632 667 local uuid = UUIDs[device] 633 668 if (uuid == nil or uuid == "") then 634 return 669 return "" 635 670 end 636 671 … … 646 681 if (status ~= true) then 647 682 commsFailure(device, tmp) 648 return 683 return "" 649 684 end 650 685 if (deviceIsOnline(device)) then … … 664 699 if (status ~= true) then 665 700 commsFailure(device, tmp) 666 return 701 return "" 667 702 end 668 703 changed = setData("TransportState", upnp.extractElement("CurrentTransportState", tmp, ""), device, changed) … … 720 755 if (status ~= true) then 721 756 commsFailure(device, tmp) 722 return 757 return "" 723 758 end 724 759 changed = setData("Mute", upnp.extractElement("CurrentMute", tmp, ""), device, changed) … … 730 765 731 766 -- Sonos queue 732 info = upnp.browseContent(uuid, UPNP_MR_CONTENT_DIRECTORY_SERVICE, "Q:0", false) 767 local queueContent = upnp.browseContent(uuid, UPNP_MR_CONTENT_DIRECTORY_SERVICE, "Q:0", false) 768 info = parseQueue(queueContent) 733 769 changed = setData("Queue", info, device, changed) 734 770 … … 736 772 setVariableValue(HADEVICE_SID, "LastUpdate", os.time(), device) 737 773 end 774 775 return queueContent 738 776 end 739 777 … … 858 896 if (device2 ~= nil) then 859 897 cxt[uuid] = {} 860 refreshNow(device2, true)898 cxt[uuid].Queue = refreshNow(device2, true) 861 899 cxt[uuid].TransportState = dataTable[uuid].TransportState 862 900 cxt[uuid].TransportPlaySpeed = dataTable[uuid].TransportPlaySpeed … … 871 909 cxt[uuid].Mute = dataTable[uuid].Mute 872 910 cxt[uuid].Volume = dataTable[uuid].Volume 873 cxt[uuid].Queue = dataTable[uuid].Queue874 911 cxt[uuid].GroupCoordinator = dataTable[uuid].GroupCoordinator 875 912 end … … 1033 1070 end 1034 1071 elseif (uri:sub(1, 3) == "SQ:") then 1035 uri = getValueFromXML(dataTable[localUUID].SavedQueues, "container", "dc:title", uri:sub(4), "res")1036 1072 requireQueuing = true 1073 local found = false 1074 if (dataTable[localUUID].SavedQueues ~= nil) then 1075 local line, id, title 1076 for line in dataTable[localUUID].SavedQueues:gmatch("(.-)\n") do 1077 id, title = line:match("^(%d+)@(.-)$") 1078 if (id ~= nil and title == uri:sub(4)) then 1079 found = true 1080 uri = "file:///jffs/settings/savedqueues.rsq#" .. id 1081 break 1082 end 1083 end 1084 end 1085 if (found == false) then 1086 uri = nil 1087 end 1037 1088 elseif (uri:sub(1, 38) == "file:///jffs/settings/savedqueues.rsq#") then 1038 1089 requireQueuing = true 1039 1090 elseif (uri:sub(1, 3) == "FR:") then 1040 1091 station = uri:sub(4) 1041 uri = getValueFromXML(dataTable[localUUID].FavoritesRadios, "item", "dc:title", station, "res") 1092 local found = false 1093 if (dataTable[localUUID].FavoritesRadios ~= nil) then 1094 local line, res, title 1095 for line in dataTable[localUUID].FavoritesRadios:gmatch("(.-)\n") do 1096 res, title = line:match("^(.+)@(.-)$") 1097 if (res ~= nil and title == uri:sub(4)) then 1098 found = true 1099 uri = res 1100 break 1101 end 1102 end 1103 end 1104 if (found == false) then 1105 uri = nil 1106 end 1042 1107 elseif (uri:sub(1, 3) == "TR:") then 1043 1108 serviceId = getSonosServiceId("TuneIn") or "254" … … 1046 1111 elseif (uri:sub(1, 3) == "SR:") then 1047 1112 station = uri:sub(4) 1048 serviceId = getSonosServiceId("Sirius ") or "37"1113 serviceId = getSonosServiceId("SiriusXM") or "37" 1049 1114 uri = "x-sonosapi-hls:r%3a" .. station .. "?sid=" .. serviceId .. "&flags=288" 1050 log("Sirius URI: " .. uri)1051 1115 elseif (uri:sub(1, 3) == "GZ:") then 1052 1116 controlByGroup = false … … 1069 1133 .. '</item></DIDL-Lite>' 1070 1134 else 1071 log("Service name for serviceId: " .. serviceId .. ": " .. service)1072 1135 uriMetaData = '<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">' 1073 1136 .. '<item><dc:title>' .. station .. '</dc:title>' … … 1588 1651 -- Sonos playlists 1589 1652 info = upnp.browseContent(uuid, UPNP_MR_CONTENT_DIRECTORY_SERVICE, "SQ:", false) 1653 info = parseSavedQueues(info) 1590 1654 changed = setData("SavedQueues", info, device, changed) 1591 1655 1592 1656 -- Favorites radio stations 1593 1657 info = upnp.browseContent(uuid, UPNP_MR_CONTENT_DIRECTORY_SERVICE, "R:0/0", false) 1658 info = parseFavoritesRadios(info) 1594 1659 changed = setData("FavoritesRadios", info, device, changed) 1595 1660 end … … 1689 1754 -- Sonos playlists 1690 1755 info = upnp.browseContent(uuid, UPNP_MR_CONTENT_DIRECTORY_SERVICE, "SQ:", false) 1756 info = parseSavedQueues(info) 1691 1757 changed = setData("SavedQueues", info, device, changed) 1692 1758 elseif (id:find("R:0,") == 1) then 1693 1759 -- Favorites radio stations 1694 1760 info = upnp.browseContent(uuid, UPNP_MR_CONTENT_DIRECTORY_SERVICE, "R:0/0", false) 1761 info = parseFavoritesRadios(info) 1695 1762 changed = setData("FavoritesRadios", info, device, changed) 1696 1763 elseif (id:find("Q:0,") == 1) then 1697 1764 -- Sonos queue 1698 1765 info = upnp.browseContent(uuid, UPNP_MR_CONTENT_DIRECTORY_SERVICE, "Q:0", false) 1766 info = parseQueue(info) 1699 1767 changed = setData("Queue", info, device, changed) 1700 1768 end -
TabularUnified trunk/J_Sonos1.js ¶
r141 r142 133 133 html += '<select id="savedQueues"/>'; 134 134 html += '<button id="playSQ" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_playSQ('+device+');">Play</button>'; 135 // html += '<button type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px" onclick="Sonos_enqueueSQ('+device+');">Enqueue</button>';136 // html += '<button type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px" onclick="Sonos_enqueuePlaySQ('+device+');">Enqueue & Play</button>';137 // html += '<button type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px" onclick="Sonos_playNextSQ('+device+');">Play next</button>';138 // html += '<button type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px" onclick="Sonos_replaceQueueSQ('+device+');">Replace queue</button>';139 135 html += '</td>'; 140 136 html += '</tr>'; … … 329 325 var favRadios = get_device_state(device, CONTENT_DIRECTORY_SID, "FavoritesRadios", 1); 330 326 if (favRadios != undefined && favRadios != "") { 331 var xmlFavRadios = Sonos_parseXml(favRadios); 332 if (typeof xmlFavRadios != 'undefined') { 333 var items = xmlFavRadios.getElementsByTagName("item"); 334 for (i=0; i<items.length; i++) { 335 var title = Sonos_extractXmlTag(items[i], 'dc:title'); 336 if (typeof title != 'undefined') { 337 html += '<tr>'; 338 html += '<td>Favorite radio "' + title + '"</td>'; 339 html += '<td></td>'; 340 html += '<td>FR:' + title + '</td>'; 341 html += '</tr>'; 342 break; 343 } 344 } 345 } 327 var pos = favRadios.indexOf('\n', 0); 328 if (pos >= 0) { 329 var line = favRadios.substring(0, pos); 330 var pos2 = line.indexOf('@'); 331 if (pos2 >= 0) { 332 var title = line.substr(pos2+1); 333 html += '<tr>'; 334 html += '<td>Favorite radio "' + title + '"</td>'; 335 html += '<td></td>'; 336 html += '<td>FR:' + title + '</td>'; 337 html += '</tr>'; 338 } 339 } 346 340 } 347 341 348 342 var savedQueues = get_device_state(device, CONTENT_DIRECTORY_SID, "SavedQueues", 1); 349 343 if (savedQueues != undefined && savedQueues != "") { 350 var xmlSavedQueues = Sonos_parseXml(savedQueues); 351 if (typeof xmlSavedQueues != 'undefined') { 352 var containers = xmlSavedQueues.getElementsByTagName("container"); 353 for (i=0; i<containers.length; i++) { 354 var title = Sonos_extractXmlTag(containers[i], 'dc:title'); 355 var value = Sonos_extractXmlTag(containers[i], 'res'); 356 if (typeof title != 'undefined' && typeof value != 'undefined') { 357 html += '<tr>'; 358 html += '<td>Sonos playlist "' + title + '"</td>'; 359 html += '<td>' + value + '</td>'; 360 html += '<td>SQ:' + title + '</td>'; 361 html += '</tr>'; 362 } 363 } 344 var pos1 = 0; 345 var pos2 = savedQueues.indexOf('\n', pos1); 346 while (pos2 >= 0) { 347 var line = savedQueues.substring(pos1, pos2); 348 var pos3 = line.indexOf('@'); 349 if (pos3 >= 0) { 350 var value = line.substring(0, pos3); 351 var title = line.substr(pos3+1); 352 html += '<tr>'; 353 html += '<td>Sonos playlist "' + title + '"</td>'; 354 html += '<td>file:///jffs/settings/savedqueues.rsq#' + value + '</td>'; 355 html += '<td>SQ:' + title + '</td>'; 356 html += '</tr>'; 357 } 358 pos1 = pos2+1; 359 pos2 = savedQueues.indexOf('\n', pos1); 364 360 } 365 361 } … … 586 582 var title = name; 587 583 if (title.length > 60) { 588 title = title.substr(0, 59) + '...';584 title = title.substr(0, 60) + '...'; 589 585 } 590 586 html += '<option value="AI:' + name + '">' + title + '</option>'; … … 601 597 var savedQueues = get_device_state(device, CONTENT_DIRECTORY_SID, "SavedQueues", 1); 602 598 if (savedQueues != undefined && savedQueues != "" && savedQueues != Sonos_prevSavedQueues) { 603 var xmlSavedQueues = Sonos_parseXml(savedQueues); 604 if (typeof xmlSavedQueues != 'undefined') { 605 var html = ""; 606 var containers = xmlSavedQueues.getElementsByTagName("container"); 607 for (i=0; i<containers.length; i++) { 608 var title = Sonos_extractXmlTag(containers[i], 'dc:title'); 609 var value = Sonos_extractXmlTag(containers[i], 'res'); 610 if (typeof title != 'undefined' && typeof value != 'undefined') { 611 if (title.length > 60) { 612 title = title.substr(0, 59) + '...'; 613 } 614 html += '<option value="' + value + '">' + title + '</option>'; 615 } 616 } 617 $('savedQueues').innerHTML = html; 618 if (Sonos_browserIE) { 619 $('savedQueues').outerHTML=$('savedQueues').outerHTML.replace($('savedQueues').innerHTML+'</select>',html+'</select>'); 620 } 599 var html = ""; 600 var pos1 = 0; 601 var pos2 = savedQueues.indexOf('\n', pos1); 602 while (pos2 >= 0) { 603 var line = savedQueues.substring(pos1, pos2); 604 var pos3 = line.indexOf('@'); 605 if (pos3 >= 0) { 606 var value = line.substring(0, pos3); 607 var title = line.substr(pos3+1); 608 if (title.length > 60) { 609 title = title.substr(0, 60) + '...'; 610 } 611 html += '<option value="' + value + '">' + title + '</option>'; 612 } 613 pos1 = pos2+1; 614 pos2 = savedQueues.indexOf('\n', pos1); 615 } 616 $('savedQueues').innerHTML = html; 617 if (Sonos_browserIE) { 618 $('savedQueues').outerHTML=$('savedQueues').outerHTML.replace($('savedQueues').innerHTML+'</select>',html+'</select>'); 621 619 } 622 620 Sonos_prevSavedQueues = savedQueues; … … 625 623 var queue = get_device_state(device, CONTENT_DIRECTORY_SID, "Queue", 1); 626 624 if (queue != undefined && queue != "" && queue != Sonos_prevQueue) { 627 var xmlQueue = Sonos_parseXml(queue); 628 if (typeof xmlQueue != 'undefined') { 629 var html = ""; 630 var items = xmlQueue.getElementsByTagName("item"); 631 for (i=0; i<items.length; i++) { 632 var title = Sonos_extractXmlTag(items[i], 'dc:title'); 633 var artist = Sonos_extractXmlTag(items[i], 'dc:creator'); 634 var value = Sonos_extractXmlTag(items[i], 'res'); 635 if (typeof title != 'undefined' && typeof value != 'undefined') { 636 var title2 = title; 637 if (typeof artist != 'undefined') { 638 title2 += ' (' + artist + ')'; 639 } 640 if (title2.length > 50) { 641 title2 = title2.substr(0, 49) + '...'; 642 } 643 html += '<option value="' + value + '">' + title2 + '</option>'; 644 } 645 } 646 $('queue').innerHTML = html; 647 if (Sonos_browserIE) { 648 $('queue').outerHTML=$('queue').outerHTML.replace($('queue').innerHTML+'</select>',html+'</select>'); 649 } 625 var html = ""; 626 var pos1 = 0; 627 var pos2 = queue.indexOf('\n', pos1); 628 while (pos2 >= 0) { 629 var title = queue.substring(pos1, pos2); 630 if (title.length > 50) { 631 title = title.substr(0, 50) + '...'; 632 } 633 html += '<option>' + title + '</option>'; 634 pos1 = pos2+1; 635 pos2 = queue.indexOf('\n', pos1); 636 } 637 $('queue').innerHTML = html; 638 if (Sonos_browserIE) { 639 $('queue').outerHTML=$('queue').outerHTML.replace($('queue').innerHTML+'</select>',html+'</select>'); 650 640 } 651 641 Sonos_prevQueue = queue; … … 654 644 var favRadios = get_device_state(device, CONTENT_DIRECTORY_SID, "FavoritesRadios", 1); 655 645 if (favRadios != undefined && favRadios != "" && favRadios != Sonos_prevFavRadios) { 656 var xmlFavRadios = Sonos_parseXml(favRadios); 657 if (typeof xmlFavRadios != 'undefined') { 658 var html = ""; 659 var items = xmlFavRadios.getElementsByTagName("item"); 660 for (i=0; i<items.length; i++) { 661 var title = Sonos_extractXmlTag(items[i], 'dc:title'); 662 if (typeof title != 'undefined') { 663 var title2 = title; 664 if (title2.length > 60) { 665 title2 = title2.substr(0, 59) + '...'; 666 } 667 html += '<option value="' + title + '">' + title2 + '</option>'; 668 } 669 } 670 $('favRadios').innerHTML = html; 671 if (Sonos_browserIE) { 672 $('favRadios').outerHTML=$('favRadios').outerHTML.replace($('favRadios').innerHTML+'</select>',html+'</select>'); 673 } 646 var html = ""; 647 var pos1 = 0; 648 var pos2 = favRadios.indexOf('\n', pos1); 649 while (pos2 >= 0) { 650 var line = favRadios.substring(pos1, pos2); 651 var pos3 = line.indexOf('@'); 652 if (pos3 >= 0) { 653 var value = line.substr(pos3+1); 654 var title = value; 655 if (title.length > 60) { 656 title = title.substr(0, 60) + '...'; 657 } 658 html += '<option value="' + value + '">' + title + '</option>'; 659 } 660 pos1 = pos2+1; 661 pos2 = favRadios.indexOf('\n', pos1); 662 } 663 $('favRadios').innerHTML = html; 664 if (Sonos_browserIE) { 665 $('favRadios').outerHTML=$('favRadios').outerHTML.replace($('favRadios').innerHTML+'</select>',html+'</select>'); 674 666 } 675 667 Sonos_prevFavRadios = favRadios; … … 906 898 || transportUri.indexOf('x-rincon-mp3radio:', 0) == 0 907 899 || transportUri.indexOf('x-sonosapi-stream:', 0) == 0 900 || transportUri.indexOf('x-sonosapi-hls:', 0) == 0 908 901 || transportUri.indexOf('x-sonosapi-radio:', 0) == 0 909 902 || transportUri.indexOf('pndrradio:', 0) == 0) { … … 912 905 && title != '') { 913 906 $('titleLabel').innerHTML = 'Stream:'; 907 } 908 else if (transportUri.indexOf('x-sonosapi-hls:', 0) == 0 && title != '') { 909 $('titleLabel').innerHTML = 'Title:'; 914 910 } 915 911 else if (transportUri.indexOf('x-rincon-stream:', 0) == 0 && title != '') { … … 1163 1159 { 1164 1160 if ($('savedQueues').selectedIndex >= 0) { 1165 var uri = $('savedQueues').options[$('savedQueues').selectedIndex].value;1161 var uri = 'file:///jffs/settings/savedqueues.rsq#' + $('savedQueues').options[$('savedQueues').selectedIndex].value; 1166 1162 //$('debug').innerHTML = uri; 1167 1163 Sonos_callAction(device, SONOS_SID, 'PlayURI', {'URIToPlay':uri} ); … … 1169 1165 } 1170 1166 1171 // function Sonos_enqueueSQ(device)1172 // {1173 // if ($('savedQueues').selectedIndex >= 0) {1174 // var uri = $('savedQueues').options[$('savedQueues').selectedIndex].value;1175 // Sonos_callAction(device, SONOS_SID, 'EnqueueURI', {'URIToEnqueue':uri, 'EnqueueMode':'ENQUEUE'} );1176 // }1177 // }1178 1179 // function Sonos_enqueuePlaySQ(device)1180 // {1181 // if ($('savedQueues').selectedIndex >= 0) {1182 // var uri = $('savedQueues').options[$('savedQueues').selectedIndex].value;1183 // Sonos_callAction(device, SONOS_SID, 'EnqueueURI', {'URIToEnqueue':uri, 'EnqueueMode':'ENQUEUE_AND_PLAY'} );1184 // }1185 // }1186 1187 // function Sonos_playNextSQ(device)1188 // {1189 // if ($('savedQueues').selectedIndex >= 0) {1190 // var uri = $('savedQueues').options[$('savedQueues').selectedIndex].value;1191 // Sonos_callAction(device, SONOS_SID, 'EnqueueURI', {'URIToEnqueue':uri, 'EnqueueMode':'ENQUEUE_AT_NEXT_PLAY'} );1192 // }1193 // }1194 1195 // function Sonos_replaceQueueSQ(device)1196 // {1197 // if ($('savedQueues').selectedIndex >= 0) {1198 // var uri = $('savedQueues').options[$('savedQueues').selectedIndex].value;1199 // Sonos_callAction(device, SONOS_SID, 'EnqueueURI', {'URIToEnqueue':uri, 'EnqueueMode':'REPLACE_QUEUE_AND_PLAY'} );1200 // }1201 // }1202 1167 1203 1168 function Sonos_clearQueue(device)
Note: See TracChangeset
for help on using the changeset viewer.