/* * PS3 Media Server, for streaming any medias to your PS3. * Copyright (C) 2008 A.Brochard * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package net.pms.formats; import net.pms.configuration.RendererConfiguration; import net.pms.dlna.DLNAMediaInfo; import net.pms.dlna.InputFile; import net.pms.network.HTTPResource; import net.pms.util.FileUtil; import net.pms.util.GenericIcons; import net.pms.util.StringUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Abstract class to store known information about a given format. */ public abstract class Format implements Cloneable { private static final Logger LOGGER = LoggerFactory.getLogger(Format.class); private String icon = null; protected int type = UNKNOWN; protected Format secondaryFormat; /** * The extension or protocol that was matched for a * particular filename or URL. Requires {@link #match(String)} * to be called first. */ private String matchedExtension; public enum Identifier { AC3, ADPCM, ADTS, AIFF, APE, ATRAC, AU, AUDIO_AS_VIDEO, ASS, BMP, DSD, DTS, DVRMS, EAC3, FLAC, GIF, RGBE, ICNS, ICO, IFF, IDX, ISO, JPG, M4A, MICRODVD, MKA, MKV, MLP, MP3, MPA, MPC, MPG, OGG, PCX, PICT, PNG, PNM, PSD, RA, RAW, SAMI, SGI, SHN, SUBRIP, SUP, TGA, THD, THREEGA, THREEG2A, TIFF, TTA, TXT, WAV, WBMP, WEB, WEBVTT, WMA, WV, CUSTOM, PLAYLIST } public static final int AUDIO = 1; public static final int IMAGE = 2; public static final int VIDEO = 4; public static final int UNKNOWN = 8; public static final int PLAYLIST = 16; public static final int ISO = 32; public static final int SUBTITLE = 64; public int getType() { return type; } /** * Returns the extension or protocol that was matched * for a particular filename or URL. Requires {@link #match(String)} to be * called first. * * @return The matched extension or protocol. */ public String getMatchedExtension() { return matchedExtension; } /** * Sets the extension or protocol that was matched * for a particular filename or URL. * * @param extension the extension or protocol that was matched. * @since 1.90.0 */ public void setMatchedExtension(String extension) { matchedExtension = extension; } public Format getSecondaryFormat() { return secondaryFormat; } public void setSecondaryFormat(Format secondaryFormat) { this.secondaryFormat = secondaryFormat; } public void setType(int type) { if (isUnknown()) { this.type = type; } } /** * @deprecated Use {@link #getSupportedExtensions} instead. */ @Deprecated public String[] getId() { return getSupportedExtensions(); } /** * Returns a list of file extensions to use to identify * a particular format e.g. "mp3" or "mpg". Extensions * are expected to be in lower case. The default value is * <code>null</code>, indicating no matching should be done * by file extension. * * @return An array of extensions. * @since 1.90.0 */ public String[] getSupportedExtensions() { return null; } /** * Returns whether or not media can be handled by the renderer natively, * based on the given media information and renderer. If the format can be * streamed (as opposed to having to be transcoded), <code>true</code> will * be returned. * * @param media * The media information. * @param renderer * The renderer for which to check. If <code>null</code> is set * as renderer, the default renderer configuration will be used. * * @return True if the format can be handled by the renderer, false * otherwise. * * @since 1.50.1 */ public boolean isCompatible(DLNAMediaInfo media, RendererConfiguration renderer) { RendererConfiguration referenceRenderer; if (renderer != null) { // Use the provided renderer as reference referenceRenderer = renderer; } else { // Use the default renderer as reference referenceRenderer = RendererConfiguration.getDefaultConf(); } // Let the renderer configuration decide on native compatibility return referenceRenderer.isCompatible(media, this); } public abstract boolean transcodable(); public String mimeType() { return HTTPResource.getDefaultMimeType(type); } /** * Not in use, handled by {@link GenericIcons} * * @deprecated */ public void setIcon(String filename) { icon = filename; } public String getIcon() { return icon; } /** * Returns whether or not this format matches the supplied filename. * Returns false if the filename is a URI, otherwise matches * against the file extensions returned by {@link #getSupportedExtensions()}. * * @param filename the filename to match * @return <code>true</code> if the format matches, <code>false</code> otherwise. */ public boolean match(String filename) { if (filename == null) { return false; } filename = filename.toLowerCase(); String[] supportedExtensions = getSupportedExtensions(); if (supportedExtensions != null) { String protocol = FileUtil.getProtocol(filename); if (protocol != null) { // URIs are handled by WEB.match return false; } for (String extension : supportedExtensions) { String ext = extension.toLowerCase(); if (filename.endsWith("." + ext)) { setMatchedExtension(ext); return true; } } } return false; } public boolean isVideo() { return (type & VIDEO) == VIDEO; } public boolean isAudio() { return (type & AUDIO) == AUDIO; } public boolean isImage() { return (type & IMAGE) == IMAGE; } public boolean isUnknown() { return (type & UNKNOWN) == UNKNOWN; } public boolean isSubtitle() { return (type & SUBTITLE) == SUBTITLE; } @Override protected Object clone() { Object o = null; try { o = super.clone(); } catch (CloneNotSupportedException e) { LOGGER.error(null, e); } return o; } public Format duplicate() { return (Format) this.clone(); } @Deprecated public void parse(DLNAMediaInfo media, InputFile file, int type) { parse(media, file, type, null); } /** * Chooses which parsing method to parse the file with. */ public void parse(DLNAMediaInfo media, InputFile file, int type, RendererConfiguration renderer) { if (renderer != null && renderer.isUseMediaInfo()) { renderer.getFormatConfiguration().parse(media, file, this, type, renderer); } else { media.parse(file, this, type, false, false, renderer); } LOGGER.trace("Parsing results for file \"{}\": {}", file.toString(), media.toString()); } /** * Returns whether or not the matched extension of this format is among * the list of supplied extensions. * * @param extensions String of comma-separated extensions * * @return True if this format matches an extension in the supplied lists, * false otherwise. * * @see #match(String) */ public boolean skip(String... extensions) { for (String extensionsString : extensions) { if (extensionsString == null) { continue; } if ("*".equals(extensionsString)) { return true; } String[] extensionsArray = extensionsString.split(","); for (String extension : extensionsArray) { if (StringUtil.hasValue(extension) && extension.equalsIgnoreCase(matchedExtension)) { return true; } } } return false; } /** * Return the class name for string representation. * @return The name. */ @Override public String toString() { return getClass().getSimpleName(); } /** * Returns the specific identifier for the format. * * @return The identifier. */ public abstract Identifier getIdentifier(); }