|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* This file is part of libbluray
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is free software; you can redistribute it and/or
|
|
Packit |
5e46da |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License as published by the Free Software Foundation; either
|
|
Packit |
5e46da |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
5e46da |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
5e46da |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
5e46da |
* Lesser General Public License for more details.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License along with this library. If not, see
|
|
Packit |
5e46da |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
package javax.media;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
import java.io.IOException;
|
|
Packit |
5e46da |
import java.net.URL;
|
|
Packit |
5e46da |
import java.util.Vector;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
import javax.media.protocol.DataSource;
|
|
Packit |
5e46da |
import javax.media.protocol.URLDataSource;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
import org.videolan.Logger;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/**
|
|
Packit |
5e46da |
* This file is a stripped down version of the Manager class from FMJ (fmj-sf.net)
|
|
Packit |
5e46da |
* @author Ken Larson
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
public final class Manager {
|
|
Packit |
5e46da |
public static Player createPlayer(URL sourceURL) throws IOException,
|
|
Packit |
5e46da |
NoPlayerException {
|
|
Packit |
5e46da |
return createPlayer(new MediaLocator(sourceURL));
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
public static Player createPlayer(MediaLocator sourceLocator)
|
|
Packit |
5e46da |
throws IOException, NoPlayerException {
|
|
Packit |
5e46da |
final String protocol = sourceLocator.getProtocol();
|
|
Packit |
5e46da |
final Vector dataSourceList = getDataSourceList(protocol);
|
|
Packit |
5e46da |
for (int i = 0; i < dataSourceList.size(); ++i) {
|
|
Packit |
5e46da |
String dataSourceClassName = (String) dataSourceList.get(i);
|
|
Packit |
5e46da |
try {
|
|
Packit |
5e46da |
final Class dataSourceClass = Class.forName(dataSourceClassName);
|
|
Packit |
5e46da |
final DataSource dataSource = (DataSource) dataSourceClass.newInstance();
|
|
Packit |
5e46da |
dataSource.setLocator(sourceLocator);
|
|
Packit |
5e46da |
dataSource.connect();
|
|
Packit |
5e46da |
return createPlayer(dataSource);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
// TODO: JMF seems to disconnect data sources in this method, based on this stack trace:
|
|
Packit |
5e46da |
// java.lang.NullPointerException
|
|
Packit |
5e46da |
// at com.sun.media.protocol.rtp.DataSource.disconnect(DataSource.java:207)
|
|
Packit |
5e46da |
// at javax.media.Manager.createPlayer(Manager.java:425)
|
|
Packit |
5e46da |
// at net.sf.fmj.ui.application.ContainerPlayer.createNewPlayer(ContainerPlayer.java:357)
|
|
Packit |
5e46da |
} catch (NoPlayerException e) {
|
|
Packit |
5e46da |
// no need to log, will be logged by call to createPlayer.
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (ClassNotFoundException e) {
|
|
Packit |
5e46da |
logger.warning("createPlayer: " + e); // no need for call stack
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (IOException e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (NoClassDefFoundError e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (Exception e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
// if none found, try URLDataSource:
|
|
Packit |
5e46da |
final URL url;
|
|
Packit |
5e46da |
try {
|
|
Packit |
5e46da |
url = sourceLocator.getURL();
|
|
Packit |
5e46da |
} catch (Exception e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
throw new NoPlayerException();
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
final URLDataSource dataSource = new URLDataSource(url);
|
|
Packit |
5e46da |
dataSource.connect(); // TODO: there is a problem because we connect to the datasource here, but
|
|
Packit |
5e46da |
// the following call may try twice or more to use the datasource with a player, once
|
|
Packit |
5e46da |
// for the right content type, and multiple times for unknown. The first attempt (for example) may actually
|
|
Packit |
5e46da |
// read data, in which case the second one will be missing data when it reads.
|
|
Packit |
5e46da |
// really, the datasource needs to be recreated.
|
|
Packit |
5e46da |
// The workaround for now is that URLDataSource (and others) allows repeated connect() calls.
|
|
Packit |
5e46da |
return createPlayer(dataSource);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
public static Player createPlayer(DataSource source) throws IOException, NoPlayerException {
|
|
Packit |
5e46da |
return createPlayer(source, source.getContentType());
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
public static DataSource createDataSource(URL sourceURL)
|
|
Packit |
5e46da |
throws IOException, NoDataSourceException {
|
|
Packit |
5e46da |
return createDataSource(new MediaLocator(sourceURL));
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
public static DataSource createDataSource(MediaLocator sourceLocator)
|
|
Packit |
5e46da |
throws IOException, NoDataSourceException {
|
|
Packit |
5e46da |
final String protocol = sourceLocator.getProtocol();
|
|
Packit |
5e46da |
final Vector dataSourceList = getDataSourceList(protocol);
|
|
Packit |
5e46da |
for (int i = 0; i < dataSourceList.size(); ++i) {
|
|
Packit |
5e46da |
String dataSourceClassName = (String) dataSourceList.get(i);
|
|
Packit |
5e46da |
try {
|
|
Packit |
5e46da |
final Class dataSourceClass = Class.forName(dataSourceClassName);
|
|
Packit |
5e46da |
final DataSource dataSource = (DataSource) dataSourceClass.newInstance();
|
|
Packit |
5e46da |
dataSource.setLocator(sourceLocator);
|
|
Packit |
5e46da |
dataSource.connect();
|
|
Packit |
5e46da |
return dataSource;
|
|
Packit |
5e46da |
} catch (ClassNotFoundException e) {
|
|
Packit |
5e46da |
logger.warning("createDataSource: " + e); // no need for call stack
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (IOException e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (NoClassDefFoundError e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (Exception e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
// if none found, try URLDataSource:
|
|
Packit |
5e46da |
final URL url;
|
|
Packit |
5e46da |
try {
|
|
Packit |
5e46da |
url = sourceLocator.getURL();
|
|
Packit |
5e46da |
} catch (Exception e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
throw new NoDataSourceException();
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
final URLDataSource dataSource = new URLDataSource(url);
|
|
Packit |
5e46da |
dataSource.connect();
|
|
Packit |
5e46da |
return dataSource;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
public static TimeBase getSystemTimeBase() {
|
|
Packit |
5e46da |
return systemTimeBase;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
public static Vector getDataSourceList(String protocolName) {
|
|
Packit |
5e46da |
return getClassList(protocolName, PackageManager.getProtocolPrefixList(), "protocol", "DataSource");
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
public static Vector getHandlerClassList(String contentName) {
|
|
Packit |
5e46da |
return getClassList(toPackageFriendly(contentName), PackageManager.getContentPrefixList(), "content", "Handler");
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
private static Player createPlayer(DataSource source, String contentType)
|
|
Packit |
5e46da |
throws IOException, NoPlayerException {
|
|
Packit |
5e46da |
final Vector handlerClassList = getHandlerClassList(contentType);
|
|
Packit |
5e46da |
for (int i = 0; i < handlerClassList.size(); ++i) {
|
|
Packit |
5e46da |
final String handlerClassName = (String) handlerClassList.get(i);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
try {
|
|
Packit |
5e46da |
System.out.println(handlerClassName);
|
|
Packit |
5e46da |
final Class handlerClass = Class.forName(handlerClassName);
|
|
Packit |
5e46da |
if (!Player.class.isAssignableFrom(handlerClass) &&
|
|
Packit |
5e46da |
!MediaProxy.class.isAssignableFrom(handlerClass)) {
|
|
Packit |
5e46da |
continue; // skip any classes that will not be matched below.
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
final MediaHandler handler = (MediaHandler) handlerClass.newInstance();
|
|
Packit |
5e46da |
handler.setSource(source);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (handler instanceof Player) {
|
|
Packit |
5e46da |
return (Player) handler;
|
|
Packit |
5e46da |
} else if (handler instanceof MediaProxy) {
|
|
Packit |
5e46da |
final MediaProxy mediaProxy = (MediaProxy) handler;
|
|
Packit |
5e46da |
return createPlayer(mediaProxy.getDataSource());
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
} catch (ClassNotFoundException e) {
|
|
Packit |
5e46da |
// no need for call stack
|
|
Packit |
5e46da |
logger.warning("createPlayer: " + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (IncompatibleSourceException e) {
|
|
Packit |
5e46da |
// no need for call stack
|
|
Packit |
5e46da |
logger.warning("createPlayer(" + source + ", " + contentType + "): " + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (IOException e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (NoPlayerException e) {
|
|
Packit |
5e46da |
// no need to log, will be logged by call to createPlayer.
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (NoClassDefFoundError e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
} catch (Exception e) {
|
|
Packit |
5e46da |
logger.warning("" + e);
|
|
Packit |
5e46da |
continue;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
logger.error("No player found for " + contentType + " / " + source.getLocator());
|
|
Packit |
5e46da |
throw new NoPlayerException("No player found for " + source.getLocator());
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
private static char toPackageFriendly(char c) {
|
|
Packit |
5e46da |
if (c >= 'a' && c <= 'z')
|
|
Packit |
5e46da |
return c;
|
|
Packit |
5e46da |
else if (c >= 'A' && c <= 'Z')
|
|
Packit |
5e46da |
return c;
|
|
Packit |
5e46da |
else if (c >= '0' && c <= '9')
|
|
Packit |
5e46da |
return c;
|
|
Packit |
5e46da |
else if (c == '.')
|
|
Packit |
5e46da |
return c;
|
|
Packit |
5e46da |
else if (c == '/')
|
|
Packit |
5e46da |
return '.';
|
|
Packit |
5e46da |
else
|
|
Packit |
5e46da |
return '_';
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
private static String toPackageFriendly(String contentName) {
|
|
Packit |
5e46da |
final StringBuffer b = new StringBuffer();
|
|
Packit |
5e46da |
for (int i = 0; i < contentName.length(); ++i) {
|
|
Packit |
5e46da |
final char c = contentName.charAt(i);
|
|
Packit |
5e46da |
b.append(toPackageFriendly(c));
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
return b.toString();
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
public static Vector getClassList(String contentName, Vector packages, String component2, String className) {
|
|
Packit |
5e46da |
final Vector result = new Vector();
|
|
Packit |
5e46da |
//result.add("media." + component2 + "." + contentName + "." + className);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
for (int i = 0; i < packages.size(); ++i) {
|
|
Packit |
5e46da |
result.add(((String) packages.get(i)) + ".media." + component2 + "." + contentName + "." + className);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return result;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
public static final String UNKNOWN_CONTENT_NAME = "unknown";
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
private static final TimeBase systemTimeBase = new SystemTimeBase();
|
|
Packit |
5e46da |
private static final Logger logger = Logger.getLogger(Manager.class.getName());
|
|
Packit |
5e46da |
}
|