# broken music streaming in HME 1.4.1 (experimental)



## s2kdave (Jan 28, 2005)

I mostly figured out the problems with why streaming music no longer works in HME 1.4.1 (experimental). It's because they changed the protocol and didn't implement any sort of backwards compatibility.

Here's the deal. If you look at IHmeProtocol, there is a comment on the latest version of the protocol.


```
/** 0.45: Adds map for parameters to stream resources */
    int VERSION_0_45			= (0 << 8) | 45;
```
That was the hint. You will also notice that there is a new createStream method too. Undocumented of course!


```
public StreamResource createStream(	String uri, 
    					String contentType,
					boolean play, 
					TeDict contentParams)
```
Well the magic is in the contentParams (I believe). I was digging through the code and found a bad hack where it loads an mp3 stream twice so that it can figure out the duration of it and put it in the HTTP headers. My guess is they fixed that and made it so you can pass information relating to the stream in the contentParams. And made it so it doesn't load if the contentParams does have the right info in it. Well this is the second time they've done crap like this. And I don't know of any official tivo HME apps that do music so we can't reverse engineer it.

The good news is I found a workaround. Quite the hack, but I encapsulated it in my bananas-plus api on code.google.com. All you have to do is extend FactoryPlus instead of Factory and pass in true to the constructor and music should work.

The workaround is to override the version number of the protocol (hack) so it thinks it's talking to an older version. HME 1.4 uses version 0.41 so that's what I do with the FactoryPlus class. I haven't tested it completely to make sure it didn't break anything else, but it looks okay so far. That's the main reason I didn't make it the default behavior.


----------



## perrce (Feb 8, 2007)

Nice work! If only this had been available three months ago! Obviously, I'm not ready to do anything with this in Harmonium yet, but I'll definitely look at it after H settles down a bit and gets stable. In the meantime, I'll try to throw together some sample code and kick the tires on the new version of BananasPlus.

...and seriously. If they're going to change something as big as that, you'd think that they'd at least throw a README file in the zip file!


----------



## perrce (Feb 8, 2007)

Btw, could you give me a quick rundown of the advantages of 1.4.1 + BananasPlus versus 1.4 + Bananas?

I know you've mentioned the scrolling BText and better art for standard definition. It seems that there were a few other things that escape my memory...


----------



## wmcbrine (Aug 2, 2003)

s2kdave said:


> The workaround is to override the version number of the protocol (hack) so it thinks it's talking to an older version.


Or, you can just pass an empty TeDict in contentParams. (At least, that works with the equivalent HME for Python code, when I bump the HME protocol version up to 0.45.)


----------



## s2kdave (Jan 28, 2005)

wmcbrine said:


> Or, you can just pass an empty TeDict in contentParams. (At least, that works with the equivalent HME for Python code, when I bump the HME protocol version up to 0.45.)


hmm. I tried this and it doesn't work when the protocol is set to 0.45. There must be something else going on with it. Looking at the code if you pass in null for dict, it defaults to an empty one anyway.


```
TeDict dict = new TeDict();
        getRoot().setResource(createStream("http://192.168.1.114:7288/test/test.mp3",
                "audio/mpeg3", true, dict));
```


----------



## s2kdave (Jan 28, 2005)

perrce said:


> Btw, could you give me a quick rundown of the advantages of 1.4.1 + BananasPlus versus 1.4 + Bananas?
> 
> I know you've mentioned the scrolling BText and better art for standard definition. It seems that there were a few other things that escape my memory...


There are extra control types:
BMovableListPlus (similar to the season pass list)
BShuttleBarPlus (for streams, aka the trickplay bar that goes over recordings/live)
BScrollPanePlus (a scrolling viewport of a set of views)
BTilesPlus (a view that tiles another view repeatedly

Some enhancements to existing controls:
-buttons and lists both support "disabled" highlights (the black bar instead of the blue one)
-BKeyboardPlus is a more skinnable version of the keyboards and lets you make new keyboards that aren't restricted to a specific layout. It also gives you a "tall" keyboard similar to the browse by title feature on tivo.
-New layout manager to layout a screen using stretching and anchoring so you make one layout that adjusts itself depending on screen size instead of a layout for every resolution.
-All plus controls (except keyboard) extend their non plus counterpart so you can use them interchangeably for the most part.
-dynamically resizable skin graphics if you use the ScaledImageElement class.
-fonts, colors and other settings are stored in the skin and scaled to the resolution and are easily overridden.
-Automatic resource management in components. Like BButtonPlus has a setValue method and automatically disposes of the resource when it's no longer used.
-Lists have cell renderers with a good default so you don't have to extend a list in most cases and can set the renderer to tell it how to render your list items. Makes code a little cleaner.

Each plus component knows how to size itself appropriately for the resolution it is on. Here' a good example snippet from your code:

Instead of doing this with an if/else statement:


```
if(this.app.getHeight() >= 720) {
            this.keyboard = new HDKeyboard(    this.getNormal(),                            // Parent view
                                            this.safeTitleH,                            // x
                                            this.screenHeight / 4,                        // y
                                            this.screenWidth - (2 * this.safeTitleH),    // width
                                            this.rowHeight * 7,                            // height
                                            HDKeyboard.PLAIN_KEYBOARD,                    // keyboard type
                                            true                                        // show tips
            );
        }
        else {
            this.keyboard = new BKeyboard(    this.getNormal(),                            // Parent view
                                            this.safeTitleH,                            // x
                                            this.screenHeight / 4,                        // y
                                            this.screenWidth - (2 * this.safeTitleH),    // width
                                            this.rowHeight * 7,                            // height
                                            BKeyboard.PLAIN_KEYBOARD,                    // keyboard type
                                            true                                        // show tips
            );
        }
```
All you need to do is this instead:


```
this.keyboard = new BKeyboardPlus(    this.getNormal(),                            // Parent view
                                            this.safeTitleH,                            // x
                                            this.screenHeight / 4,                        // y
                                            BKeyboardPlus.PLAIN_KEYBOARD,                    // keyboard type
                                            true                                        // show tips
            );
```
It's easy for you to start using Bananas Plus if you want. You can mix regular Bananas and Plus in the same app. You just need to convert your BApplication to a BApplicationPlus and then get rid of the hmehd references.

Harmonium.java
-extend BApplicationPlus
-change initService() to just init()
-have your HarmoniumFactory extend FactoryPlus and pass in true to the constructor. (until I figure out the real problem with 0.45)

HSkin.java:
-extend BSkinPlus
-move the guts of the constructor into an overriden configure(Resolution) method.

In the screens where you use HDKeyboard, use BKeyboardPlus instead.

That should be about it to get it started.


----------



## wmcbrine (Aug 2, 2003)

s2kdave said:


> hmm. I tried this and it doesn't work


Yeah, sorry. It worked for video streams, but not mp3 streams.


----------



## perrce (Feb 8, 2007)

I'm going to try to migrate Harmonium to BananasPlus, but I have a few questions:

On the GoogleCode page, there's a bananas-plus-0.1.0.jar download. Does that version incorporate the fix you put in to get music streaming working again?

Are there any JavaDocs for BananasPlus, or should I refer to the source?

When I upgrade to BananasPlus, I need to upgrade to HME 1.4.1e and Bananas 1.3.1e at the same time, right?


----------



## s2kdave (Jan 28, 2005)

yes, that version has the fix in it. I didn't build the javadoc files so refer to the source. And yes you have to upgrade both to 1.4.1e.


----------



## s2kdave (Jan 28, 2005)

BTW, also included in the source is the bananas samples with most of them converted to use bananas plus with some additional samples for the new components.


----------

