net.pms.dlna.CueFolder.java Source code

Java tutorial

Introduction

Here is the source code for net.pms.dlna.CueFolder.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 jwbroek.cuelib.*;
import net.pms.PMS;
import net.pms.configuration.PmsConfiguration;
import net.pms.dlna.Range.Time;
import net.pms.encoders.FFmpegAudio;
import net.pms.encoders.MEncoderVideo;
import net.pms.encoders.Player;
import net.pms.formats.Format;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

public class CueFolder extends DLNAResource {
    private static final Logger logger = LoggerFactory.getLogger(CueFolder.class);
    private static final PmsConfiguration configuration = PMS.getConfiguration();
    private File playlistfile;

    public File getPlaylistfile() {
        return playlistfile;
    }

    private boolean valid = true;

    public CueFolder(File f) {
        playlistfile = f;
        setLastModified(playlistfile.lastModified());
    }

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

    @Override
    public String getName() {
        return playlistfile.getName();
    }

    @Override
    public String getSystemName() {
        return playlistfile.getName();
    }

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

    @Override
    public boolean isValid() {
        return valid;
    }

    @Override
    public long length() {
        return 0;
    }

    @Override
    protected void resolveOnce() {
        if (playlistfile.length() < 10000000) {
            CueSheet sheet;

            try {
                sheet = CueParser.parse(playlistfile);
            } catch (IOException e) {
                logger.info("Error in parsing cue: " + e.getMessage());
                return;
            }

            if (sheet != null) {
                List<FileData> files = sheet.getFileData();

                // only the first one
                if (files.size() > 0) {
                    FileData f = files.get(0);
                    List<TrackData> tracks = f.getTrackData();
                    Player defaultPlayer = null;
                    DLNAMediaInfo originalMedia = null;
                    ArrayList<DLNAResource> addedResources = new ArrayList<DLNAResource>();

                    for (int i = 0; i < tracks.size(); i++) {
                        TrackData track = tracks.get(i);
                        if (i > 0) {
                            double end = getTime(track.getIndices().get(0).getPosition());

                            if (addedResources.isEmpty()) {
                                // seems the first file was invalid or non existent
                                return;
                            }

                            DLNAResource prec = addedResources.get(i - 1);
                            int count = 0;

                            while (prec.isFolder() && i + count < addedResources.size()) { // not used anymore
                                prec = addedResources.get(i + count);
                                count++;
                            }

                            prec.getSplitRange().setEnd(end);
                            prec.getMedia().setDuration(prec.getSplitRange().getDuration());
                            logger.debug("Track #" + i + " split range: " + prec.getSplitRange().getStartOrZero()
                                    + " - " + prec.getSplitRange().getDuration());
                        }

                        Position start = track.getIndices().get(0).getPosition();
                        RealFile realFile = new RealFile(new File(playlistfile.getParentFile(), f.getFile()));
                        addChild(realFile);
                        addedResources.add(realFile);

                        if (i > 0 && realFile.getMedia() == null) {
                            realFile.setMedia(new DLNAMediaInfo());
                            realFile.getMedia().setMediaparsed(true);
                        }

                        realFile.resolve();

                        if (i == 0) {
                            originalMedia = realFile.getMedia();
                        }

                        realFile.getSplitRange().setStart(getTime(start));
                        realFile.setSplitTrack(i + 1);

                        // assign a splitter engine if file is natively supported by the renderer
                        if (realFile.getPlayer() == null) {
                            if (defaultPlayer == null) {
                                /*
                                   XXX why are we creating new player instances? aren't they
                                   supposed to be singletons?
                                    
                                   TODO don't hardwire the player here; leave it to the
                                   player factory to select the right player for the
                                   resource's format e.g:
                                    
                                      defaultPlayer = PlayerFactory.getPlayer(realFile);
                                */
                                if (realFile.getFormat() == null) {
                                    logger.error(
                                            "No file format known for file \"{}\", assuming it is a video for now.",
                                            realFile.getName());
                                    /*
                                       TODO (see above):
                                        
                                          r.resolveFormat(); // sets the format based on the filename
                                          defaultPlayer = PlayerFactory.getPlayer(realFile);
                                    */
                                    defaultPlayer = new MEncoderVideo(configuration);
                                } else {
                                    if (realFile.getFormat().isAudio()) {
                                        defaultPlayer = new FFmpegAudio(configuration);
                                    } else {
                                        defaultPlayer = new MEncoderVideo(configuration);
                                    }
                                }
                            }

                            realFile.setPlayer(defaultPlayer);
                        }

                        if (realFile.getMedia() != null) {
                            try {
                                realFile.setMedia((DLNAMediaInfo) originalMedia.clone());
                            } catch (CloneNotSupportedException e) {
                                logger.info("Error in cloning media info: " + e.getMessage());
                            }

                            if (realFile.getMedia() != null && realFile.getMedia().getFirstAudioTrack() != null) {
                                if (realFile.getFormat().isAudio()) {
                                    realFile.getMedia().getFirstAudioTrack().setSongname(track.getTitle());
                                } else {
                                    realFile.getMedia().getFirstAudioTrack().setSongname("Chapter #" + (i + 1));
                                }

                                realFile.getMedia().getFirstAudioTrack().setTrack(i + 1);
                                realFile.getMedia().setSize(-1);

                                if (StringUtils.isNotBlank(sheet.getTitle())) {
                                    realFile.getMedia().getFirstAudioTrack().setAlbum(sheet.getTitle());
                                }

                                if (StringUtils.isNotBlank(sheet.getPerformer())) {
                                    realFile.getMedia().getFirstAudioTrack().setArtist(sheet.getPerformer());
                                }

                                if (StringUtils.isNotBlank(track.getPerformer())) {
                                    realFile.getMedia().getFirstAudioTrack().setArtist(track.getPerformer());
                                }
                            }
                        }
                    }

                    if (tracks.size() > 0 && addedResources.size() > 0) {
                        DLNAResource lastTrack = addedResources.get(addedResources.size() - 1);
                        Time lastTrackSplitRange = lastTrack.getSplitRange();
                        DLNAMediaInfo lastTrackMedia = lastTrack.getMedia();

                        if (lastTrackSplitRange != null && lastTrackMedia != null) {
                            lastTrackSplitRange.setEnd(lastTrackMedia.getDurationInSeconds());
                            lastTrackMedia.setDuration(lastTrackSplitRange.getDuration());
                            logger.debug("Track #" + childrenNumber() + " split range: "
                                    + lastTrackSplitRange.getStartOrZero() + " - "
                                    + lastTrackSplitRange.getDuration());
                        }
                    }

                    PMS.get().storeFileInCache(playlistfile, Format.PLAYLIST);
                }
            }
        }
    }

    private double getTime(Position p) {
        return p.getMinutes() * 60 + p.getSeconds() + ((double) p.getFrames() / 100);
    }
}