perrce
04-13-2008, 06:38 PM
I come back looking for help -- this time with streaming MP3 files. I've been playing with the sample music.java file that comes with the HME SDK, and have had mixed success. The problem I've run into is that I can get an MP3 to play using the simulator, but when I run it on the TiVo, I can't get any sound to come out. The funny thing is that even though my code is based on the HME sample mp3 player, the sample player works just fine while mine does not. I've tried using both absolute paths and relative directories, with the same results.
I'm including below a really stripped down test application. Note that to run the program, you'll need to change the value of MP3Test.MP3TestFactory.musicRoot, which is the path to the directory that contains the mp3 files. (You'll also have to supply your own mp3, obviously.)
If anyone can shed some light on why it would work on the simulator, but not on the TiVo, I'd be grateful. Thanks.
/**
*
*/
package org.dazeend.mp3Test;
import com.tivo.hme.bananas.*;
import com.tivo.hme.sdk.*;
import com.tivo.hme.interfaces.*;
import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
public class MP3Test extends BApplication {
BScreen nowPlayingScreen;
/**
* Application initialization. Run when application is started from TiVo.
*/
public void init(IContext context) throws Exception {
// Initialization from superclass.
super.init(context);
this.nowPlayingScreen = new BScreen(this);
String track = ((MP3TestFactory)this.getFactory()).musicList.get(0);
this.play(track);
}
public void play(String path) {
//
// Construct the URI to send to the receiver. The receiver will
// connect back to our factory and ask for the file. The URI
// consists of:
//
// (our base URI) + (the track's path name)
//
String url = this.getContext().getBaseURI().toString();
try {
url += URLEncoder.encode(path, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("#### Playing MP3: " + url);
System.out.flush();
// stop any music that might be playing
this.stop();
// MP3's are played as a resource streamed to the nowPlayingScreen
this.nowPlayingScreen.setResource(this.nowPlayingScreen.crea teStream(url, null, true));
}
public void stop() {
// MP3's are played as a resource streamed to the nowPlayingScreen
Resource resource = this.nowPlayingScreen.getResource();
// stop the current stream if one exists
if (resource != null) {
resource.remove();
}
}
/**
* Server side factory.
*
*/
public static class MP3TestFactory extends Factory {
public String musicRoot = "/home/ceperry/workspace/MP3Test/test data";
public List<String> musicList = new ArrayList<String>();
/**
* Create the factory.
* Run when server-side application begins execution.
*/
@Override
protected void init(IArgumentList args) {
// Create the music collection
this.loadMusic(this.musicRoot, "");
}
/**
* Recursively search for music and load it into the collection.
*
* @param musicDir the root directory to search
* @param path
*/
private void loadMusic(String root, String path) {
File file = new File(root, path);
if (file.isDirectory()) {
if (path.length() > 0 && !path.endsWith("/")) {
path += "/";
}
String list[] = file.list();
for (int i = 0; i < list.length; i++) {
this.loadMusic(root, path + list[i]);
}
} else if ( path.toLowerCase().endsWith(".mp3") ) {
System.out.println("Found: " + path);
this.musicList.add(path);
}
}
/* (non-Javadoc)
* @see com.tivo.hme.sdk.MP3Factory#getMP3StreamFromURI(java.lang.St ring)
*/
public InputStream getStream(String uri) throws IOException
{
System.out.println("### MP3Test.MP3TestFactory.getStream");
System.out.println("URI: " + uri);
System.out.flush();
File file = new File(this.musicRoot, URLDecoder.decode(uri, "UTF-8"));
if (file.exists())
{
System.out.println("File Exists");
System.out.flush();
InputStream in = new FileInputStream(file);
return in;
}
else
{
System.out.println("File DNE: treating as uri");
System.out.flush();
return super.getStream(uri);
}
}
}
}
I'm including below a really stripped down test application. Note that to run the program, you'll need to change the value of MP3Test.MP3TestFactory.musicRoot, which is the path to the directory that contains the mp3 files. (You'll also have to supply your own mp3, obviously.)
If anyone can shed some light on why it would work on the simulator, but not on the TiVo, I'd be grateful. Thanks.
/**
*
*/
package org.dazeend.mp3Test;
import com.tivo.hme.bananas.*;
import com.tivo.hme.sdk.*;
import com.tivo.hme.interfaces.*;
import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
public class MP3Test extends BApplication {
BScreen nowPlayingScreen;
/**
* Application initialization. Run when application is started from TiVo.
*/
public void init(IContext context) throws Exception {
// Initialization from superclass.
super.init(context);
this.nowPlayingScreen = new BScreen(this);
String track = ((MP3TestFactory)this.getFactory()).musicList.get(0);
this.play(track);
}
public void play(String path) {
//
// Construct the URI to send to the receiver. The receiver will
// connect back to our factory and ask for the file. The URI
// consists of:
//
// (our base URI) + (the track's path name)
//
String url = this.getContext().getBaseURI().toString();
try {
url += URLEncoder.encode(path, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("#### Playing MP3: " + url);
System.out.flush();
// stop any music that might be playing
this.stop();
// MP3's are played as a resource streamed to the nowPlayingScreen
this.nowPlayingScreen.setResource(this.nowPlayingScreen.crea teStream(url, null, true));
}
public void stop() {
// MP3's are played as a resource streamed to the nowPlayingScreen
Resource resource = this.nowPlayingScreen.getResource();
// stop the current stream if one exists
if (resource != null) {
resource.remove();
}
}
/**
* Server side factory.
*
*/
public static class MP3TestFactory extends Factory {
public String musicRoot = "/home/ceperry/workspace/MP3Test/test data";
public List<String> musicList = new ArrayList<String>();
/**
* Create the factory.
* Run when server-side application begins execution.
*/
@Override
protected void init(IArgumentList args) {
// Create the music collection
this.loadMusic(this.musicRoot, "");
}
/**
* Recursively search for music and load it into the collection.
*
* @param musicDir the root directory to search
* @param path
*/
private void loadMusic(String root, String path) {
File file = new File(root, path);
if (file.isDirectory()) {
if (path.length() > 0 && !path.endsWith("/")) {
path += "/";
}
String list[] = file.list();
for (int i = 0; i < list.length; i++) {
this.loadMusic(root, path + list[i]);
}
} else if ( path.toLowerCase().endsWith(".mp3") ) {
System.out.println("Found: " + path);
this.musicList.add(path);
}
}
/* (non-Javadoc)
* @see com.tivo.hme.sdk.MP3Factory#getMP3StreamFromURI(java.lang.St ring)
*/
public InputStream getStream(String uri) throws IOException
{
System.out.println("### MP3Test.MP3TestFactory.getStream");
System.out.println("URI: " + uri);
System.out.flush();
File file = new File(this.musicRoot, URLDecoder.decode(uri, "UTF-8"));
if (file.exists())
{
System.out.println("File Exists");
System.out.flush();
InputStream in = new FileInputStream(file);
return in;
}
else
{
System.out.println("File DNE: treating as uri");
System.out.flush();
return super.getStream(uri);
}
}
}
}