io.humble.video.customio.URLProtocolManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of humble-video-noarch Show documentation
Show all versions of humble-video-noarch Show documentation
This is the main Humble Video Java library. It contains no native code, but all Java runtime code.
It must be paired up with the correct humble-video-arch-*.jar library for your OS. For most
users, depending on humble-video-all will work better.
/*******************************************************************************
* Copyright (c) 2013, Art Clarke. All rights reserved.
*
* This file is part of Humble-Video.
*
* Humble-Video is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Humble-Video is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Humble-Video. If not, see .
*******************************************************************************/
package io.humble.video.customio;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.humble.video.customio.FfmpegIO;
import io.humble.video.customio.FileProtocolHandlerFactory;
import io.humble.video.customio.IURLProtocolHandler;
import io.humble.video.customio.IURLProtocolHandlerFactory;
import io.humble.video.customio.NullProtocolHandlerFactory;
import io.humble.video.customio.URLProtocolManager;
/**
* This class manages URL protocols that we have handlers for. It is used
* (and called from) the Native code that integrates with FFMPEG.
*
* To register a handler you would use the singleton manager as follows:
*
*
* URLProtocolManager mgr = URLProtocolManager.getManager();
* mgr.registerFactory("myprotocol", myProtocolHandlerFactory);
*
*
*/
public class URLProtocolManager
{
private final Logger log = LoggerFactory.getLogger(this.getClass());
private final ConcurrentMap mProtocols;
public static final String DEFAULT_PROTOCOL = "humblefile";
public static final String NULL_PROTOCOL = "humblenull";
private static final URLProtocolManager sManager = new URLProtocolManager();
/**
* Factory method to get the global protocol manager.
*/
public static URLProtocolManager getManager()
{
return sManager;
}
/**
* Method to be called to initialize this library.
*/
public static void init()
{
// just calling this method causes sManager to be initialized
// in the static constructor, which is the only initialization
// we currently need.
}
// Don't let people create one of these; instead they must
// use the Singleton factory method.
private URLProtocolManager()
{
mProtocols = new ConcurrentHashMap();
// Always register the DEFAULT
registerFactory(DEFAULT_PROTOCOL, new FileProtocolHandlerFactory());
// And the NULL protocols
registerFactory(NULL_PROTOCOL, new NullProtocolHandlerFactory());
}
/**
* Register a new factory for IURLProtocolHandlers for a given protocol.
*
* FFMPEG is very picky; protocols must be only alpha characters (no numbers).
*
* @param protocol The protocol, without colon, this factory is to be used for.
* @param factory The factory for the manager to use whenever a handler is requested for a registered protocol;
* null means disable handling for this factory.
* @return The factory that was previously used for that protocol (or null if none).
*/
public IURLProtocolHandlerFactory registerFactory(String protocol,
IURLProtocolHandlerFactory factory)
{
if (protocol == null)
throw new IllegalArgumentException("protocol required");
IURLProtocolHandlerFactory oldFactory;
if (factory == null)
oldFactory = mProtocols.remove(protocol);
else
oldFactory = mProtocols.put(protocol, factory);
log.trace("Registering factory for URLProtocol: {}", protocol);
if (oldFactory == null)
{
// we previously didn't have something registered for this factory
// so tell FFMPEG we're now the protocol manager for this protocol.
log.trace("Letting FFMPEG know about an additional protocol: {}",
protocol);
FfmpegIO.registerProtocolHandler(protocol, this);
}
return oldFactory;
}
/*
* Get a IURLProtocolHandler for this url.
*
* IMPORTANT: This function is called from native code, and so the name and signature cannot
* change without changing the native code.
*
* This function is eventually invoked whenever someone tries to call url_open("yourprotocol:...", flags)
* from FFMPEG native code. It returns a protocol handler which will then have open(...) called on it.
*
* @param url The URL we want to handle.
* @param flags Any flags that the url_open() function will want to pass.
*
* @returns A protocol handler to use.
*/
public IURLProtocolHandler getHandler(String url, int flags)
{
IURLProtocolHandler result = null;
log.trace("looking for protocol handler for: {}", url);
if (url == null || url.length() == 0)
throw new IllegalArgumentException("expected valid URL");
int colonIndex = url.indexOf(":");
String protocol = null;
if (colonIndex > 0)
{
protocol = url.substring(0, colonIndex);
}
else
{
protocol = DEFAULT_PROTOCOL;
}
IURLProtocolHandlerFactory factory = mProtocols.get(protocol);
if (factory != null)
{
result = factory.getHandler(protocol, url, flags);
}
else
{
log.error("asked to get handler for unsupported protocol: {}",
protocol);
}
return result;
}
/**
* Get the resource portion of a url. For example for the URL
*
* http://www.humble.io/video
*
* The protocol string is http
and the resource
* string is www.humble.io/video
*
* @param url The url to parse
* @return The resource
*/
public static String getResourceFromURL(String url)
{
String retval = url;
if (url != null && url.length() > 0)
{
int colonIndex;
colonIndex = url.indexOf("://");
if (colonIndex > 0)
retval = url.substring(colonIndex+3);
else {
colonIndex = url.indexOf(":");
if (colonIndex > 1) // handle windows drive letters.
{
// remove the URL prefix
retval = url.substring(colonIndex + 1);
}
}
}
return retval;
}
/**
* Get the protocol portion of a url. For example for the URL
*
* http://www.humble.io/video
*
* The protocol string is http
and the resource
* string is //www.humble.io/video
*
* @param url The url to parse
* @return The protocol
*/
public static String getProtocolFromURL(String url)
{
String retval = null;
if (url != null && url.length() > 0)
{
int colonIndex = url.indexOf(":");
if (colonIndex > 0)
{
// remove the URL suffix
retval = url.substring(0, colonIndex);
}
}
return retval;
}
}