Your Universal Remote Control Center
RemoteCentral.com
Philips Pronto Professional Forum - View Post
Previous section Next section Previous page Next page Up level
Up level
The following page was printed from RemoteCentral.com:

Login:
Pass:
 
 

Page 1 of 3
Topic:
Heres one - Reading XML output from an HDI Dune Player
This thread has 42 replies. Displaying posts 1 through 15.
Post 1 made on Tuesday June 4, 2024 at 03:14
mpg7321
Regular Member
Joined:
Posts:
June 2020
145
I wouldn't even know how to begin a search for this issue, feedback from a Dune HD media player looks like this from a web browser,
param name="playback_speed" value="256"/>
param name="playback_duration" value="6836"/>
param name="playback_position" value="1886"/>
param name="playback_position_version" value="21"/>
param name="playback_repeat" value="0"/>
param name="playback_shuffle" value="0"/>
param name="playback_caption" value="Dark Phoenix (7 of 24)"/>

I am parsing out the data with
var duration = info.match("playback_duration\" value=\"(.*?)\"")[1];
var title = info.match("playback_caption\" value=\"(.*?)\"")[1];

each line works but I can only have one line in the script at a time. If I add both line to the script neither seems to work.

LRM - Edited to change the thread title to be more reflective of the ask.

Last edited by Lyndel McGee (moderator) on June 15, 2024 11:19.
Post 2 made on Tuesday June 4, 2024 at 14:24
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
13,059
Not sure if this will work but maybe between before each line that is doing a .match(...) , insert the following line.
info.lastIndex = 0;


You may have to convert your code to build Regular expressions and the do a myRegEx.match(info) to get this to work.

[Link: developer.mozilla.org]


Can you please post an full example that will compile and run including the text that is in the variable named info? It's easy enough to do.

Last edited by Lyndel McGee on June 15, 2024 11:19.
Lyndel McGee
Philips Pronto Addict/Beta Tester
OP | Post 3 made on Friday June 14, 2024 at 01:49
mpg7321
Regular Member
Joined:
Posts:
June 2020
145
Sorry it took a while, hears the script I am running,
var url = CF.widget("DuneHD_URL","DuneHD_URL").label;
var CR = " HTTP/1.1\r\n\r\n";
function DuneHD_IP(command) {
var SEND = command.concat(CR);
var socket = new TCPSocket(false);
socket.onConnect = function()
{
socket.write(SEND)
};
socket.onData = function()
{
var info = socket.read();
info.lastIndex = 0;
var title = info.match("playback_caption\" value=\"(.*?)\\(")[1];
info.lastIndex = 0;
var duration = info.match("playback_duration\" value=\"(.*?)\"")[1];
GUI.widget("DuneHD_Title").label=title;
GUI.widget("DuneHD_Duration").label=duration;
socket.close();
};
socket.onIOError = function(e)
{
socket.close();
};
socket.connect(url,80);
};


the command being sent is,
[Link: 192.168.1.51]

Sample of the returned data, minus the space following <

This XML file does not appear to have any style information associated with it. The document tree is shown below.
< command_result>
< param name="protocol_version" value="6"/>
< param name="phv_md5" value="D41D8CD98F00B204E9800998ECF8427E"/>
< param name="pltv_enabled" value="0"/>
< param name="playback_caption" value="Dazed and Confused (1 of 19)"/>
< param name="playback_extra_caption" value="Last Day of School, May 28, 1976, 1:05 p.m."/>
< param name="md5" value="AA82118DFFF0E8AC5393DA2259966DA5"/>
< param name="product_id" value="tv175v"/>
< param name="serial_number" value="0000-0001-6075-9349-5201-249D-8928-B3B3"/>
< param name="firmware_version" value="240123_0207_r22"/>
< param name="commercial_serial_number" value="EC175V001232100148"/>
< param name="product_name" value="Pro Vision 4K Solo"/>
< /command_result>
there can be over a 100 lines of returned date.

when I display INFO in a panel and run the simulator, repeating query every 5 seconds, I noticed it switches between the above example to HTTP/1.0 200 OK

Is it being an XML file?

Last edited by mpg7321 on June 14, 2024 13:28.
OP | Post 4 made on Friday June 14, 2024 at 14:45
mpg7321
Regular Member
Joined:
Posts:
June 2020
145
I got it working with adding

info = info.replace(/^<\?xml\s+version\s*=\s*(['"])[^\1]+\1[^?]*\?>/, "");
Post 5 made on Friday June 14, 2024 at 18:30
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
13,059
Great to hear!

I presume you got that RegEx from com.philips.Util.js or perhaps on the web somewhere?

Here's the original bug for XML processing about having to remove the XML preprocessor instruction via replace().

[Link: bugzilla.mozilla.org]

Now if you want to process that data without all the substrings and matches, try this one. Google for the single acronym "E4X"

ECMAscript for XML is available in the Javascript engine on the Pronto and will work after you remove that preprocessing instruction.

You can learn to use this "dead" extension to Javascript via Adobe Tutorials. My first version of a weather app many years ago processed XML data on the Pronto using the E4X extension.

[Link: help.adobe.com]

or from the specification

[Link: www-archive.mozilla.org]

Another tutorial as well.
[Link: w3schools.sinsixx.com]

Last edited by Lyndel McGee on June 15, 2024 11:22.
Lyndel McGee
Philips Pronto Addict/Beta Tester
Post 6 made on Saturday June 15, 2024 at 12:15
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
13,059
Put this code into a button and run the simulator with ProntoScript Console.

It should give you some ideas as to how you could simplify your code drastically.

In this post, the line where 'text' is assigned, wraps. Make sure when you paste into button code that is all on 1 line.


System.setDebugMask(9);

var text = '<command_result><param name="protocol_version" value="4"/><param name="player_state" value="standby"/></command_result>';

var command_result = new XML(text);

var extractedParamsArray = [];
var extractedParams = {};
// For each loop to show each param by enumerating the XMLList.
for each (var param in command_result.param) {

//System.print(param.toSource());
// must use the . before @ as E4X needs to know to look inside param
// for attributes
var name = param.@name;
var value = param.@value;
//System.print(name + "=" + value);
extractedParamsArray.push({"name":name, "value":value});
extractedParams[name] = value;
}

System.print(extractedParamsArray.toSource());

System.print(extractedParams.toSource());
Lyndel McGee
Philips Pronto Addict/Beta Tester
Post 7 made on Saturday June 15, 2024 at 12:23
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
13,059
Here's the output I see locally:

protocol_version=4
player_state=standby
[{name:protocol_version, value:4}, {name:player_state, value:standby}]
({protocol_version:4, player_state:standby})
Lyndel McGee
Philips Pronto Addict/Beta Tester
OP | Post 8 made on Saturday June 15, 2024 at 20:52
mpg7321
Regular Member
Joined:
Posts:
June 2020
145
On June 15, 2024 at 12:15, Lyndel McGee said...
Put this code into a button and run the simulator with ProntoScript Console.

It should give you some ideas as to how you could simplify your code drastically.

In this post, the line where 'text' is assigned, wraps. Make sure when you paste into button code that is all on 1 line.


System.setDebugMask(9);

var text = '';

var command_result = new XML(text);

var extractedParamsArray = [];
var extractedParams = {};
// For each loop to show each param by enumerating the XMLList.
for each (var param in command_result.param) {

//System.print(param.toSource());
// must use the . before @ as E4X needs to know to look inside param
// for attributes
var name = param.@name;
var value = param.@value;
//System.print(name + "=" + value);
extractedParamsArray.push({"name":name, "value":value});
extractedParams[name] = value;
}

System.print(extractedParamsArray.toSource());

System.print(extractedParams.toSource());

I got this to work but I don't see what your seeing, the player_State value does not change when playing vs not playing a movie, I only see,
[{name:protocol_version, value:4}, {name:player_state, value:standby}]
({protocol_version:4, player_state:standby})
I do not see,
protocol_version=4
player_state=standby

I also wonder for my DunePlayer the only values I get for Player_State, are
< param name="player_state" value="navigator"/>
< param name="player_state" value="file_playback"/>

Last edited by mpg7321 on June 16, 2024 02:43.
OP | Post 9 made on Saturday June 15, 2024 at 21:06
mpg7321
Regular Member
Joined:
Posts:
June 2020
145
My code is very glitchy, I think the issue may be that the return data bounce back and forth between the example listed above and " HTTP/1.0 200 OK", or at least that is what is being displayed when I display "info" in a panel on the remote. I repeat the code every 5 seconds. Not sure where the " HTTP/1.0 200 OK" is coming from, for I do not see it from a web browser.

What I don't understand is why I can only parse one at a time, once the data is loaded into 'info' shouldn't I be able to parse it out as much as I want too?


After doing a bit more digging, I am getting an error stating that
var title = info.match("playback_caption\" value=\"(.*?)\\(")[1];
has no properties..

Last edited by mpg7321 on June 16, 2024 16:28.
Post 10 made on Sunday June 16, 2024 at 17:10
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
13,059
The web browser communicates using the HTTP prototol and the 200 OK is the HTTP status for OK. Your web browser hides all of this and only gives you back whatever is in the Response Body.

In my example, 'text' variable contains ONLY the Response body (What you see as content in Chrome) I received when I connected to my Dune Player when the power was off.

For your example to work, you'd need to create an XML object out of all the data you received from ONLY the response body.

If this is over your head, please continue doing it the way you were but if you want to do it the best and most sane way, here's how. Replace your socket.onData function with the one below.


socket.onData = function()
{
var info = socket.read();
// Per WebMaster In a Nutshell from O'reilly books - Recommend this book for learning HTTP Protocol.
// Skip past the HTTP Response Status Line and any Response Headers.
var body = info.substring(info.indexOf("\r\n\r\n") + 4);
// Remove the XML Preprocessor instruction as you were doing before
body = body.replace(/^<\?xml\s+version\s*=\s*(['"])[^\1]+\1[^?]*\?>/, "");
var command_result = new XML(body);

// what we want to do here is to extract all params from XML response to an object as key-value pairs.
var extractedParams = {};
// For each loop to show each param by enumerating the XMLList.
for each (var param in command_result.param) {
// must use the . before @ as E4X needs to know to look inside param
// for attributes
var name = param.@name;
var value = param.@value;
extractedParams[name] = value;
}
// Now you have all the content in an XML object you can use as my example did.
// GUI.widget("PLAYER_STATE").label = extractedParams['player_state'];
GUI.widget("DuneHD_Title").label= '' + extractedParams['playback_caption'];
GUI.widget("DuneHD_Duration").label='' + extractedParams['playback_duration'];
socket.close();
};


Note that all this stuff will work if you don't have an titles that have UTF8 encoded characters. If you do, you may see errors on those titles.

For this reason, many of us use the Philips Http Library to do this processing as it handles the UTF8 decoding for us.
Lyndel McGee
Philips Pronto Addict/Beta Tester
Post 11 made on Sunday June 16, 2024 at 18:41
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
13,059
When you mention 'glitchy' code, please be aware that the Dune may send multiple blocks of data. You are not concatenating the strings received from the Dune but instead using what has just been sent.

var info = socket.read();

Your solution is not a robust solution in that if the Dune sends multiple blocks of data over the socket, your code will only process what was sent in that block.

That's why many of us use the Philips Http Library so that when the HTTP request has completed, we then read the data.

I have many examples of doing this locally in my setups. However, writing about how to do this here, requires lots of tutorials.

The Beta Dev guide included an appendix on using the Philips HTTP library. I cannot recall if they provided examples. Have you reviewed that before?
Lyndel McGee
Philips Pronto Addict/Beta Tester
OP | Post 12 made on Sunday June 16, 2024 at 18:47
mpg7321
Regular Member
Joined:
Posts:
June 2020
145
Thanks will start to try and rap my head around using the HTTP library's, I will stop what I have been doing and start over for it has not been working properly. LOL

Thnaks
Understand better now why it was not working, so at least I learned something.

Side question, does your Dune player sort movies properly? I have a large library and I have a handful of movies that are not listed in the proper alphabetical order. For an example the movie "The Mist" is the very first movie listed in my library. I have been in contact with support but not herd back yet. I have a DuneHD 4k solo, with the latest bata firmware that you can DL right from the unit installed

Last edited by mpg7321 on June 16, 2024 19:09.
OP | Post 13 made on Sunday June 16, 2024 at 19:08
mpg7321
Regular Member
Joined:
Posts:
June 2020
145
On June 16, 2024 at 17:10, Lyndel McGee said...
The web browser communicates using the HTTP prototol and the 200 OK is the HTTP status for OK. Your web browser hides all of this and only gives you back whatever is in the Response Body.

In my example, 'text' variable contains ONLY the Response body (What you see as content in Chrome) I received when I connected to my Dune Player when the power was off.

For your example to work, you'd need to create an XML object out of all the data you received from ONLY the response body.

If this is over your head, please continue doing it the way you were but if you want to do it the best and most sane way, here's how. Replace your socket.onData function with the one below.


socket.onData = function()
{
var info = socket.read();
// Per WebMaster In a Nutshell from O'reilly books - Recommend this book for learning HTTP Protocol.
// Skip past the HTTP Response Status Line and any Response Headers.
var body = info.substring(info.indexOf("\r\n\r\n") + 4);
// Remove the XML Preprocessor instruction as you were doing before
body = body.replace(/^<\?xml\s+version\s*=\s*(['"])[^\1]+\1[^?]*\?>/, "");
var command_result = new XML(body);

// what we want to do here is to extract all params from XML response to an object as key-value pairs.
var extractedParams = {};
// For each loop to show each param by enumerating the XMLList.
for each (var param in command_result.param) {
// must use the . before @ as E4X needs to know to look inside param
// for attributes
var name = param.@name;
var value = param.@value;
extractedParams[name] = value;
}
// Now you have all the content in an XML object you can use as my example did.
// GUI.widget("PLAYER_STATE").label = extractedParams['player_state'];
GUI.widget("DuneHD_Title").label= '' + extractedParams['playback_caption'];
GUI.widget("DuneHD_Duration").label='' + extractedParams['playback_duration'];
socket.close();
};


Note that all this stuff will work if you don't have an titles that have UTF8 encoded characters. If you do, you may see errors on those titles.

For this reason, many of us use the Philips Http Library to do this processing as it handles the UTF8 decoding for us.

For this example, I get "undefined" displayed, if I'm lucking to get that, also not seeing any errors. Also your earlier example with the code to be placed in a button, I get "Empty String" where I should be seeing the returneddata.
Post 14 made on Sunday June 16, 2024 at 23:11
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
13,059
M,

Please send me an email from an address that can receive a configuration file attachment and I will send you a working PEP2 one that you can play with. This configuration will install the HTTP library I use (both commented and non-commented - loads a little faster) versions.

I'm also including a printLine function that I used to ensure that we don't run into issues due to limitations in Pronto's System.print function.

The approach I used is 100% the best way to approach this problem. IMO, the Dune HTTP interface does not usually provide detail must users are looking for. As such, I don't use it at all.

I've tested this config with Blu Ray, DVD, .mkv, and Audio playlist playback. On my Dune, none of these show the parameter you cited above named 'playback_title'.

It is completely up to you to finish this off. But from the code I will give you, hopefully you can.

Lyndel
Lyndel McGee
Philips Pronto Addict/Beta Tester
Post 15 made on Sunday June 16, 2024 at 23:16
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
13,059
Sent to your 'rogers' account as well as gmail.

When you get the file, please make time to review all code in the DuneMonitor activity's script as well as the code in the DuneStatus page's script.

I conveniently used the pageInterval of 5 seconds on the DuneStatus page to get the refresh.
Lyndel McGee
Philips Pronto Addict/Beta Tester
Page 1 of 3


Jump to


Protected Feature Before you can reply to a message...
You must first register for a Remote Central user account - it's fast and free! Or, if you already have an account, please login now.

Please read the following: Unsolicited commercial advertisements are absolutely not permitted on this forum. Other private buy & sell messages should be posted to our Marketplace. For information on how to advertise your service or product click here. Remote Central reserves the right to remove or modify any post that is deemed inappropriate.

Hosting Services by ipHouse