package com.skcraft.playblock.media; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import net.minecraft.server.MinecraftServer; import com.skcraft.playblock.queue.QueueException; import com.skcraft.playblock.util.Validate; /** * A media resolver identifies types and media and returns metadata about media * when it can be retrieved. An example of metadata would be the length of a * clip. */ public class MediaResolver { private static final boolean ALLOW_ANY_URI = System.getProperty("playBlock.allowAnyUri", "false").equalsIgnoreCase("true"); // VLC 2.0.x does not actually support RTMP private static final Pattern allowedUri = Pattern.compile("^(https?|ftps?|rtp|mmsh?|rtsp(u|t)?|rtmpe?|tcp|udp)://.+$", Pattern.CASE_INSENSITIVE); private final List<MediaProvider> providers = new ArrayList<MediaProvider>(); /** * Create a new instance of the media resolver. */ public MediaResolver() { // Add default resolvers providers.add(new YouTube()); } /** * Lookup information about the given URI and return a non-null * {@link Media} object describing the media located at the given URI, as * best as possible. * * @param uri * the URI * @return information about the given URI, possibly none * @throws IOException * on an error * @throws QueueException * on non-I/O error */ public Media lookup(String uri) throws IOException, QueueException { Validate.notNull(uri); MediaProvider mostConfident = null; int topConfidence = 0; Media info = null; for (MediaProvider provider : providers) { int confidence = provider.getConfidence(uri); if (confidence > topConfidence) { mostConfident = provider; } } if (mostConfident == null) { info = new Media(uri); } else { info = mostConfident.lookup(uri); if (info == null) { throw new NullPointerException("Got null MediaInfo from " + mostConfident.getClass().getCanonicalName() + "for URI '" + uri + "'"); } } return info; } /** * Try to clean up poorly copied and pasted URIs. * * @param uri * the URI * @return a cleaned up URI */ public static String cleanUri(String uri) { Validate.notNull(uri); uri = uri.trim(); if (uri.startsWith("\'") && uri.endsWith("\'")) { uri = uri.substring(1, uri.length() - 1); } if (uri.startsWith("\"") && uri.endsWith("\"")) { uri = uri.substring(1, uri.length() - 1); } // @TODO: Support other quotation marks uri = uri.trim(); return uri; } /** * Checks if a URI is allowed to play. * * @param uri * the URI * @return true if valid */ public static boolean canPlayUri(String uri) { Validate.notNull(uri); if (uri.isEmpty()) { return false; } // Override with -DplayBlock.allowAnyUri=true or Singleplayer MinecraftServer server = MinecraftServer.getServer(); if (ALLOW_ANY_URI || (server != null && server.isSinglePlayer())) { return true; } return allowedUri.matcher(uri).matches(); } }