net.pms.dlna.DVDISOTitle.java Source code

Java tutorial

Introduction

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

Source

/*
 * 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.dlna;

import net.pms.Messages;
import net.pms.PMS;
import net.pms.configuration.PmsConfiguration;
import net.pms.configuration.RendererConfiguration;
import net.pms.formats.FormatFactory;
import net.pms.formats.v2.SubtitleType;
import net.pms.io.OutputParams;
import net.pms.io.ProcessWrapperImpl;
import net.pms.util.FileUtil;
import net.pms.util.ProcessUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import static org.apache.commons.lang3.StringUtils.isNotBlank;

public class DVDISOTitle extends DLNAResource {
    private static final Logger logger = LoggerFactory.getLogger(DVDISOTitle.class);
    private static final PmsConfiguration configuration = PMS.getConfiguration();
    private File file;
    private int title;
    private long length;

    public DVDISOTitle(File file, int title) {
        this.file = file;
        this.title = title;
        setLastModified(file.lastModified());
    }

    @Override
    protected void resolveOnce() {
        String cmd[] = new String[] { configuration.getMplayerPath(), "-identify", "-endpos", "0", "-v", "-ao",
                "null", "-vc", "null", "-vo", "null", "-dvd-device",
                ProcessUtil.getShortFileNameIfWideChars(file.getAbsolutePath()), "dvd://" + title };

        OutputParams params = new OutputParams(configuration);
        params.maxBufferSize = 1;

        if (configuration.isDvdIsoThumbnails()) {
            try {
                params.workDir = configuration.getTempFolder();
            } catch (IOException e1) {
                logger.debug("Caught exception", e1);
            }

            cmd[2] = "-frames";
            cmd[3] = "2";
            cmd[7] = "-quiet";
            cmd[8] = "-quiet";
            String frameName = "" + this.hashCode();
            frameName = "mplayer_thumbs:subdirs=\"" + frameName + "\"";
            frameName = frameName.replace(',', '_');
            cmd[10] = "jpeg:outdir=" + frameName;
        }

        params.log = true;
        final ProcessWrapperImpl pw = new ProcessWrapperImpl(cmd, params, true, false);

        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                }
                pw.stopProcess();
            }
        };

        Thread failsafe = new Thread(r, "DVD ISO Title Failsafe");
        failsafe.start();
        pw.runInSameThread();
        List<String> lines = pw.getOtherResults();

        String duration = null;
        int nbsectors = 0;
        String fps = null;
        String aspect = null;
        String width = null;
        String height = null;
        ArrayList<DLNAMediaAudio> audio = new ArrayList<DLNAMediaAudio>();
        ArrayList<DLNAMediaSubtitle> subs = new ArrayList<DLNAMediaSubtitle>();

        if (lines != null) {
            for (String line : lines) {
                if (line.startsWith("DVD start=")) {
                    nbsectors = Integer.parseInt(line.substring(line.lastIndexOf("=") + 1).trim());
                }

                if (line.startsWith("audio stream:")) {
                    DLNAMediaAudio lang = new DLNAMediaAudio();
                    lang.setId(Integer
                            .parseInt(line.substring(line.indexOf("aid: ") + 5, line.lastIndexOf(".")).trim()));
                    lang.setLang(line.substring(line.indexOf("language: ") + 10, line.lastIndexOf(" aid")).trim());
                    int end = line.lastIndexOf(" langu");

                    if (line.lastIndexOf("(") < end && line.lastIndexOf("(") > line.indexOf("format: ")) {
                        end = line.lastIndexOf("(");
                    }

                    lang.setCodecA(line.substring(line.indexOf("format: ") + 8, end).trim());

                    if (line.contains("(stereo)")) {
                        lang.getAudioProperties().setNumberOfChannels(2);
                    } else {
                        lang.getAudioProperties().setNumberOfChannels(6);
                    }

                    audio.add(lang);
                }

                if (line.startsWith("subtitle")) {
                    DLNAMediaSubtitle lang = new DLNAMediaSubtitle();
                    lang.setId(Integer.parseInt(
                            line.substring(line.indexOf("): ") + 3, line.lastIndexOf("language")).trim()));
                    lang.setLang(line.substring(line.indexOf("language: ") + 10).trim());

                    if (lang.getLang().equals("unknown")) {
                        lang.setLang(DLNAMediaLang.UND);
                    }

                    lang.setType(SubtitleType.UNKNOWN);
                    subs.add(lang);
                }

                if (line.startsWith("ID_VIDEO_WIDTH=")) {
                    width = line.substring(line.indexOf("ID_VIDEO_WIDTH=") + 15).trim();
                }

                if (line.startsWith("ID_VIDEO_HEIGHT=")) {
                    height = line.substring(line.indexOf("ID_VIDEO_HEIGHT=") + 16).trim();
                }

                if (line.startsWith("ID_VIDEO_FPS=")) {
                    fps = line.substring(line.indexOf("ID_VIDEO_FPS=") + 13).trim();
                }

                if (line.startsWith("ID_LENGTH=")) {
                    duration = line.substring(line.indexOf("ID_LENGTH=") + 10).trim();
                }

                if (line.startsWith("ID_VIDEO_ASPECT=")) {
                    aspect = line.substring(line.indexOf("ID_VIDEO_ASPECT=") + 16).trim();
                }
            }
        }

        if (configuration.isDvdIsoThumbnails()) {
            try {
                String frameName = "" + this.hashCode();
                frameName = configuration.getTempFolder() + "/mplayer_thumbs/" + frameName + "00000001/0000000";
                frameName = frameName.replace(',', '_');
                File jpg = new File(frameName + "2.jpg");

                if (jpg.exists()) {
                    InputStream is = new FileInputStream(jpg);
                    try {
                        int sz = is.available();

                        if (sz > 0) {
                            getMedia().setThumb(new byte[sz]);
                            is.read(getMedia().getThumb());
                        }
                    } finally {
                        if (is != null) {
                            is.close();
                        }
                    }

                    if (!jpg.delete()) {
                        jpg.deleteOnExit();
                    }

                    // Try and retry
                    if (!jpg.getParentFile().delete() && !jpg.getParentFile().delete()) {
                        logger.debug("Failed to delete \"" + jpg.getParentFile().getAbsolutePath() + "\"");
                    }
                }

                jpg = new File(frameName + "1.jpg");

                if (jpg.exists()) {
                    if (!jpg.delete()) {
                        jpg.deleteOnExit();
                    }

                    if (!jpg.getParentFile().delete()) {
                        jpg.getParentFile().delete();
                    }
                }
            } catch (IOException e) {
                logger.trace("Error in DVD ISO thumbnail retrieval: " + e.getMessage());
            }
        }

        length = nbsectors * 2048;

        double d = 0;
        if (duration != null) {
            d = Double.parseDouble(duration);
        }

        getMedia().setAudioTracksList(audio);
        getMedia().setSubtitleTracksList(subs);

        if (duration != null) {
            getMedia().setDuration(d);
        }

        getMedia().setFrameRate(fps);
        getMedia().setAspect(aspect);
        getMedia().setDvdtrack(title);
        getMedia().setContainer("iso");
        getMedia().setCodecV("mpeg2video");

        try {
            getMedia().setWidth(Integer.parseInt(width));
        } catch (NumberFormatException nfe) {
            logger.debug("Could not parse width \"" + width + "\"");
        }

        try {
            getMedia().setHeight(Integer.parseInt(height));
        } catch (NumberFormatException nfe) {
            logger.debug("Could not parse height \"" + height + "\"");
        }

        getMedia().setMediaparsed(true);
    }

    public long getLength() {
        return length;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return null;
    }

    @Override
    public String getName() {
        return String.format(Messages.getString("DVDISOTitle.1"), title);
    }

    @Override
    public String getSystemName() {
        return file.getAbsolutePath();
    }

    @Override
    public boolean isFolder() {
        return false;
    }

    @Override
    public boolean isValid() {
        if (getFormat() == null) {
            setFormat(FormatFactory.getAssociatedFormat("dummy.iso"));
        }
        return true;
    }

    @Override
    public long length() {
        return DLNAMediaInfo.TRANS_SIZE;
    }

    // Ditlew
    @Override
    public long length(RendererConfiguration mediaRenderer) {
        // WDTV Live at least, needs a realistic size for stop/resume to works proberly. 2030879 = ((15000 + 256) * 1024 / 8 * 1.04) : 1.04 = overhead
        int cbr_video_bitrate = getDefaultRenderer().getCBRVideoBitrate();
        return (cbr_video_bitrate > 0)
                ? (long) (((cbr_video_bitrate + 256) * 1024 / 8 * 1.04) * getMedia().getDurationInSeconds())
                : length();
    }

    @Override
    public InputStream getThumbnailInputStream() throws IOException {
        File cachedThumbnail = null;
        File thumbFolder = null;
        boolean alternativeCheck = false;

        while (cachedThumbnail == null) {
            if (thumbFolder == null) {
                thumbFolder = file.getParentFile();
            }

            cachedThumbnail = FileUtil.getFileNameWithNewExtension(thumbFolder, file, "jpg");

            if (cachedThumbnail == null) {
                cachedThumbnail = FileUtil.getFileNameWithNewExtension(thumbFolder, file, "png");
            }

            if (cachedThumbnail == null) {
                cachedThumbnail = FileUtil.getFileNameWithAddedExtension(thumbFolder, file, ".cover.jpg");
            }

            if (cachedThumbnail == null) {
                cachedThumbnail = FileUtil.getFileNameWithAddedExtension(thumbFolder, file, ".cover.png");
            }

            if (alternativeCheck) {
                break;
            }

            if (isNotBlank(configuration.getAlternateThumbFolder())) {
                thumbFolder = new File(configuration.getAlternateThumbFolder());

                if (!thumbFolder.isDirectory()) {
                    thumbFolder = null;
                    break;
                }
            }

            alternativeCheck = true;
        }

        if (cachedThumbnail != null) {
            return new FileInputStream(cachedThumbnail);
        } else if (getMedia() != null && getMedia().getThumb() != null) {
            return getMedia().getThumbnailInputStream();
        } else {
            return getGenericThumbnailInputStream("images/cdrwblank-256.png");
        }
    }
}