# mp3 stream works in simulator but not on Tivo



## iolsen (Aug 19, 2009)

I've been trying to resurrect the Last.fm tivo app (from http://sourceforge.net/projects/lastfmhme/).

I've got it working nicely in the simulator. But the same audio mp3 stream that's working in the simulator fails when I run it on an actual Tivo (a series 2 or 3).

I create the stream resource the usual way:

StreamResource sr = createStream(url, null, true);

The url here is actually the last.fm mp3. A second or two later in the simulator, there's music playing and sr.getStatus() returns RSRC_STATUS_PLAYING.

On a real Tivo, the music never starts and sr.getStatus() returns RSRC_STATUS_ERROR.

I've tried declaring the stream type various ways, e.g. "audio/mp3", "audio/mpeg", and "audio/mpeg3". That had no effect.

What else could it be? I know this is an mp3 stream, so it can't be simply an unsupported encoding. Is there a way to coax more troubleshooting/debugging information out of the Tivo beyond just the RSRC_STATUS_ERROR status code?


----------



## davidblackledge (Sep 9, 2008)

Quick note... the mp3 player in the tivo crashes sometimes... try rebooting the TiVo then try again. I've made it crash with "unsatisfactory" streams before and then it just stops working for anything until you reboot.


----------



## iolsen (Aug 19, 2009)

I figured this out. There were several things going on:


I never got the Tivo to directly request and play the real mp3 stream itself. I don't know why.
Rather than sending the receiver the direct URL to the stream, I sent a URL so it would request the stream from my app, with a URL including the real stream's URL encoded therein.
That change resulted in my application's Factory's getStream() method being called to handle these streams. So in there, I pull out the actual mp3 stream and request it myself from Last.FM.
Last.FM always does an HTTP 302 redirect, so I had to handle that. (Eventually I discovered java.net.HttpURLConnection has redirect support.)
After that, I always mysteriously got two calls to my Factory's getStream() method. Because these are Last.FM streams, they can only be requested once. Turns out, the HME SDK includes ridiculous code that retrieves all mp3 streams twice in order to determine their playback duration. (See com.tiivo.hme.sdk.Factory.handleHTTP() in version 1.4 of the SDK.) I switched to building the SDK myself and yanked that out. It was straightforward to instead use Last.FM's API to retrieve a reliable playback duration for a particular mp3.

Then it worked.


----------



## davidblackledge (Sep 9, 2008)

Ah, yes... sorry I hadn't had more time to think about it... (some?) redirects appear to be an issue with TiVos... to handle more URLs, I use the following Utility class which includes a method for pre-redirecting the URL before handing it off to the TiVo. Same basic result, but it's pre-processing it instead of handling it from the Factory.
http://david.blackledge.com/javadoc.../Utility.html#handleRedirect(java.lang.String)
The class also has methods to handle other preprocessing issues like finding the valid image content type for the URL to pass in to createStream method for ugly image URLs, a test for bad URLs that make TiVo barf, and automatic corrections for some invalid URLs that web browsers are smart enough to work around.
That class is included in several of my jar files from my site... definitely in the MultiTasker jar at least. (MultiTaskerApplication.createImageStream handles all issues with image streams to prevent a crash)

Something else to watch out for... keep in mind the LIMIT constant for URL lengths.
In MultiTasker I added a tiny url-like functionality to map a long URL to a short URL handled/proxied by the Factory, and the MultiTaskerApplication class overrides createStream to use that functionality if a URL is beyond the LIMIT_URL_NBYTES.

And, yeah, that double-request thing is a known oddity... I'm glad Last.FM has an API for that purpose. I also have code related to that in MultiTasker... specifically if the mapped tiny url is requested twice in a row it does some special handling... I don't recall how I made it work, though so it may not have prevented the two requests to the real URL.


----------

