net.pms.dlna.DLNAMediaSubtitle.java Source code

Java tutorial

Introduction

Here is the source code for net.pms.dlna.DLNAMediaSubtitle.java

Source

/*
 * PS3 Media Server, for streaming any medias to your PS3.
 * Copyright (C) 2008  A.Brochard
 * Copyright (C) 2012  I. Sokolov
 *
 * 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.dlna;

import com.ibm.icu.text.CharsetMatch;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import net.pms.PMS;
import net.pms.formats.v2.SubtitleType;
import static net.pms.formats.v2.SubtitleType.UNKNOWN;
import static net.pms.util.Constants.CHARSET_UTF_8;
import net.pms.util.FileUtil;
import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class keeps track of the subtitle information for media.
 */
public class DLNAMediaSubtitle extends DLNAMediaLang implements Cloneable {
    private static final Logger LOGGER = LoggerFactory.getLogger(DLNAMediaSubtitle.class);
    private SubtitleType type = UNKNOWN;

    private String subtitlesTrackTitleFromMetadata;

    private File externalFile;
    private String subsCharacterSet;

    private String liveSubURL;
    private String liveSubFile;
    private boolean isStreamable = false;

    /**
     * Returns whether or not the subtitles are embedded.
     *
     * @return True if the subtitles are embedded, false otherwise.
     * @since 1.51.0
     */
    public boolean isEmbedded() {
        return (externalFile == null);
    }

    /**
     * Returns whether or not the subtitles are external.
     *
     * @return True if the subtitles are external file, false otherwise.
     * @since 1.70.0
     */
    public boolean isExternal() {
        return !isEmbedded();
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        result.append("id: ");
        result.append(getId());
        result.append(", type: ");
        result.append(type);

        if (isNotBlank(subtitlesTrackTitleFromMetadata)) {
            result.append(", subtitles track title from metadata: ");
            result.append(subtitlesTrackTitleFromMetadata);
        }

        result.append(", lang: ");
        result.append(getLang());

        if (externalFile != null) {
            result.append(", externalFile: ");
            result.append(externalFile.toString());
            result.append(", external file character set: ");
            result.append(subsCharacterSet);
        }

        return result.toString();
    }

    /**
     * @deprecated charset is autodetected for text subtitles after setExternalFile()
     */
    @Deprecated
    public void checkUnicode() {
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    /**
     * @return the type
     */
    public SubtitleType getType() {
        return type;
    }

    /**
     * @param type the type to set
     */
    public void setType(SubtitleType type) {
        if (type == null) {
            throw new IllegalArgumentException("Can't set null SubtitleType.");
        }
        this.type = type;
    }

    /**
     * @deprecated use getSubtitlesTrackTitleFromMetadata()
     */
    @Deprecated
    public String getFlavor() {
        return getSubtitlesTrackTitleFromMetadata();
    }

    /**
     * @deprecated use setSubtitlesTrackTitleFromMetadata()
     */
    @Deprecated
    public void setFlavor(String value) {
        setSubtitlesTrackTitleFromMetadata(value);
    }

    public String getSubtitlesTrackTitleFromMetadata() {
        return subtitlesTrackTitleFromMetadata;
    }

    public void setSubtitlesTrackTitleFromMetadata(String value) {
        this.subtitlesTrackTitleFromMetadata = value;
    }

    /**
     * @deprecated use {@link #FileUtil.convertFileFromUtf16ToUtf8()} for UTF-16 -> UTF-8 conversion.
     */
    public File getPlayableExternalFile() {
        return getExternalFile();
    }

    /**
     * @return the externalFile
     */
    public File getExternalFile() {
        return externalFile;
    }

    /**
     * @param externalFile the externalFile to set
     */
    public void setExternalFile(File externalFile) throws FileNotFoundException {
        if (externalFile == null) {
            throw new FileNotFoundException("Can't read file: no file supplied");
        } else if (!FileUtil.getFilePermissions(externalFile).isReadable()) {
            throw new FileNotFoundException("Insufficient permission to read " + externalFile.getAbsolutePath());
        }

        this.externalFile = externalFile;
        setFileSubsCharacterSet();
    }

    private void setFileSubsCharacterSet() {
        if (type.isPicture()) {
            subsCharacterSet = null;
        } else {
            try {
                CharsetMatch match = FileUtil.getFileCharsetMatch(externalFile);
                if (match != null) {
                    subsCharacterSet = match.getName().toUpperCase(PMS.getLocale());
                    lang = match.getLanguage();
                    LOGGER.debug("Set detected charset \"{}\" and language \"{}\" for {}", match.getName(), lang,
                            externalFile.getAbsolutePath());
                } else {
                    subsCharacterSet = null;
                    LOGGER.debug("No charset detected for {}", externalFile.getAbsolutePath());
                }

            } catch (IOException ex) {
                subsCharacterSet = null;
                LOGGER.warn("Exception during external file charset detection: ", ex.getMessage());
            }
        }
    }

    /**
     * @deprecated use {@link #setSubCharacterSet(String)}
     */
    public void setExternalFileCharacterSet(String charSet) {
        setSubCharacterSet(charSet);
    }

    public void setSubCharacterSet(String charSet) {
        subsCharacterSet = charSet;
    }

    /**
     * @deprecated use {@link #getSubCharacterSet()}
     */
    public String getExternalFileCharacterSet() {
        return getSubCharacterSet();
    }

    public String getSubCharacterSet() {
        return subsCharacterSet;
    }

    /**
     * @return true if subtitles is UTF-8 encoded, false otherwise.
     */
    public boolean isSubsUtf8() {
        return equalsIgnoreCase(subsCharacterSet, CHARSET_UTF_8);
    }

    /**
     * @return true if external subtitles file is UTF-8 encoded, false otherwise.
     */
    public boolean isExternalFileUtf8() {
        return FileUtil.isCharsetUTF8(subsCharacterSet);
    }

    /**
     * @return true if external subtitles file is UTF-16 encoded, false otherwise.
     */
    public boolean isExternalFileUtf16() {
        return FileUtil.isCharsetUTF16(subsCharacterSet);
    }

    /**
     * @return true if external subtitles file is UTF-32 encoded, false otherwise.
     */
    public boolean isExternalFileUtf32() {
        return FileUtil.isCharsetUTF32(subsCharacterSet);
    }

    /**
     * @return true if external subtitles file is UTF-8 or UTF-16 encoded, false otherwise.
     */
    public boolean isExternalFileUtf() {
        return (isExternalFileUtf8() || isExternalFileUtf16() || isExternalFileUtf32());
    }

    public void setLiveSub(String url) {
        setLiveSub(url, null);
    }

    public void setLiveSub(String url, String file) {
        liveSubURL = url;
        liveSubFile = file;
    }

    public String getLiveSubURL() {
        return liveSubURL;
    }

    public String getLiveSubFile() {
        return liveSubFile;
    }

    public boolean isStreamable() {
        return isExternal() && isStreamable;
    }

    public void setSubsStreamable(boolean isStreamable) {
        this.isStreamable = isStreamable;
    }
}