Search in sources :

Example 1 with PmsConfiguration

use of net.pms.configuration.PmsConfiguration in project UniversalMediaServer by UniversalMediaServer.

the class DLNAResource method checkThumbnail.

/**
 * Checks if a thumbnail exists, and, if not, generates one (if possible).
 * Called from Request/RequestV2 in response to thumbnail requests e.g. HEAD /get/0$1$0$42$3/thumbnail0000%5BExample.mkv
 * Calls DLNAMediaInfo.generateThumbnail, which in turn calls DLNAMediaInfo.parse.
 *
 * @param inputFile File to check or generate the thumbnail for.
 * @param renderer The renderer profile
 */
protected void checkThumbnail(InputFile inputFile, RendererConfiguration renderer) {
    // Use device-specific pms conf, if any
    PmsConfiguration configurationSpecificToRenderer = PMS.getConfiguration(renderer);
    if (media != null && !media.isThumbready() && configurationSpecificToRenderer.isThumbnailGenerationEnabled() && (renderer == null || renderer.isThumbnails())) {
        Double seekPosition = (double) configurationSpecificToRenderer.getThumbnailSeekPos();
        if (isResume()) {
            Double resumePosition = (double) (resume.getTimeOffset() / 1000);
            if (media.getDurationInSeconds() > 0 && resumePosition < media.getDurationInSeconds()) {
                seekPosition = resumePosition;
            }
        }
        media.generateThumbnail(inputFile, getFormat(), getType(), seekPosition, isResume(), renderer);
        if (!isResume() && media.getThumb() != null && configurationSpecificToRenderer.getUseCache() && inputFile.getFile() != null) {
            PMS.get().getDatabase().updateThumbnail(inputFile.getFile().getAbsolutePath(), inputFile.getFile().lastModified(), getType(), media);
        }
    }
}
Also used : PmsConfiguration(net.pms.configuration.PmsConfiguration)

Example 2 with PmsConfiguration

use of net.pms.configuration.PmsConfiguration in project UniversalMediaServer by UniversalMediaServer.

the class DLNAResource method getDisplayName.

/**
 * Returns the DisplayName that is shown to the Renderer.
 * Extra info might be appended depending on the settings, like item duration.
 * This is based on {@link #getName()}.
 *
 * @param mediaRenderer Media Renderer for which to show information.
 * @param withSuffix Whether to include additional media info
 * @return String representing the item.
 */
private String getDisplayName(RendererConfiguration mediaRenderer, boolean withSuffix) {
    PmsConfiguration configurationSpecificToRenderer = PMS.getConfiguration(mediaRenderer);
    /**
     * Allow the use of displayNameOverride for names we do not allow
     * to be transformed.
     */
    if (displayNameOverride != null) {
        displayName = displayNameOverride;
        return displayName;
    }
    // displayName shouldn't be cached, since device configurations may differ
    // if (displayName != null) { // cached
    // return withSuffix ? (displayName + nameSuffix) : displayName;
    // }
    // this unescape trick is to solve the problem of a name containing
    // unicode stuff like \u005e
    // if it's done here it will fix this for all objects
    displayName = StringEscapeUtils.unescapeJava(getName());
    nameSuffix = "";
    String subtitleFormat;
    String subtitleLanguage;
    boolean isNamedNoEncoding = false;
    boolean subsAreValidForStreaming = media_subtitle != null && media_subtitle.isStreamable() && mediaRenderer != null && mediaRenderer.streamSubsForTranscodedVideo();
    if (this instanceof RealFile && !isFolder()) {
        RealFile rf = (RealFile) this;
        if (configurationSpecificToRenderer.isPrettifyFilenames() && getFormat() != null && getFormat().isVideo()) {
            displayName = FileUtil.getFileNamePrettified(displayName, rf.getFile(), media);
        } else if (configurationSpecificToRenderer.isHideExtensions()) {
            displayName = FileUtil.getFileNameWithoutExtension(displayName);
        }
        displayName = FullyPlayed.prefixDisplayName(displayName, rf, mediaRenderer);
    }
    if (player != null) {
        if (isNoName()) {
            displayName = "[" + player.name() + "]";
        } else {
            // Ditlew - WDTV Live don't show durations otherwise, and this is useful for finding the main title
            if (media != null && this instanceof DVDISOTitle && mediaRenderer != null && media.getDurationInSeconds() > 0 && mediaRenderer.isShowDVDTitleDuration()) {
                nameSuffix += " (" + StringUtil.convertTimeToString(media.getDurationInSeconds(), "%01d:%02d:%02.0f") + ")";
            }
            if (!configurationSpecificToRenderer.isHideEngineNames()) {
                nameSuffix += " [" + player.name() + "]";
            }
        }
    } else {
        if (isNoName()) {
            displayName = Messages.getString("DLNAResource.0");
            isNamedNoEncoding = true;
            if (subsAreValidForStreaming) {
                isNamedNoEncoding = false;
            }
        } else if (nametruncate > 0) {
            displayName = displayName.substring(0, nametruncate).trim();
        }
    }
    if (hasExternalSubtitles() && !isNamedNoEncoding && media_audio == null && media_subtitle == null && !configurationSpecificToRenderer.hideSubsInfo() && (player == null || player.isExternalSubtitlesSupported())) {
        nameSuffix += " " + Messages.getString("DLNAResource.1");
    }
    if (getMediaAudio() != null) {
        String audioLanguage = "/" + getMediaAudio().getLangFullName();
        if ("/Undetermined".equals(audioLanguage)) {
            audioLanguage = "";
        }
        String audioTrackTitle = "";
        if (getMediaAudio().getAudioTrackTitleFromMetadata() != null && !"".equals(getMediaAudio().getAudioTrackTitleFromMetadata()) && mediaRenderer != null && mediaRenderer.isShowAudioMetadata()) {
            audioTrackTitle = " (" + getMediaAudio().getAudioTrackTitleFromMetadata() + ")";
        }
        displayName = player != null ? ("[" + player.name() + "]") : "";
        nameSuffix = " {Audio: " + getMediaAudio().getAudioCodec() + audioLanguage + audioTrackTitle + "}";
    }
    if (media_subtitle != null && media_subtitle.getId() != -1 && !configurationSpecificToRenderer.hideSubsInfo()) {
        subtitleFormat = media_subtitle.getType().getDescription();
        if ("(Advanced) SubStation Alpha".equals(subtitleFormat)) {
            subtitleFormat = "SSA";
        } else if ("Blu-ray subtitles".equals(subtitleFormat)) {
            subtitleFormat = "PGS";
        }
        subtitleLanguage = "/" + media_subtitle.getLangFullName();
        if ("/Undetermined".equals(subtitleLanguage)) {
            subtitleLanguage = "";
        }
        String subtitlesTrackTitle = "";
        if (media_subtitle.getSubtitlesTrackTitleFromMetadata() != null && !"".equals(media_subtitle.getSubtitlesTrackTitleFromMetadata()) && mediaRenderer != null && mediaRenderer.isShowSubMetadata()) {
            subtitlesTrackTitle = " (" + media_subtitle.getSubtitlesTrackTitleFromMetadata() + ")";
        }
        String subsDescription = Messages.getString("DLNAResource.2") + subtitleFormat + subtitleLanguage + subtitlesTrackTitle;
        if (subsAreValidForStreaming) {
            nameSuffix += " {" + Messages.getString("DLNAResource.3") + subsDescription + "}";
        } else {
            nameSuffix += " {" + subsDescription + "}";
        }
    }
    if (isAvisynth()) {
        displayName = (player != null ? ("[" + player.name()) : "") + " + AviSynth]";
    }
    if (getSplitRange().isEndLimitAvailable()) {
        displayName = ">> " + convertTimeToString(getSplitRange().getStart(), DURATION_TIME_FORMAT);
    }
    return withSuffix ? (displayName + nameSuffix) : displayName;
}
Also used : PmsConfiguration(net.pms.configuration.PmsConfiguration)

Example 3 with PmsConfiguration

use of net.pms.configuration.PmsConfiguration in project UniversalMediaServer by UniversalMediaServer.

the class DLNAResource method getDlnaOrgPnFlags.

/**
 * Creates the DLNA.ORG_PN to send.
 * DLNA.ORG_PN is a string that tells the renderer what type of file to expect, like its
 * container, framerate, codecs and resolution.
 * Some renderers will not play a file if it has the wrong DLNA.ORG_PN string, while others
 * are fine with any string or even nothing.
 *
 * @param mediaRenderer
 * 			Media Renderer for which to represent this information.
 * @param localizationValue
 * @return String representation of the DLNA.ORG_PN flags
 */
@SuppressWarnings("deprecation")
private String getDlnaOrgPnFlags(RendererConfiguration mediaRenderer, int localizationValue) {
    // Use device-specific pms conf, if any
    PmsConfiguration configurationSpecificToRenderer = PMS.getConfiguration(mediaRenderer);
    String mime = getRendererMimeType(mediaRenderer);
    String dlnaOrgPnFlags = null;
    if (mediaRenderer.isDLNAOrgPNUsed() || mediaRenderer.isAccurateDLNAOrgPN()) {
        if (mediaRenderer.isPS3()) {
            if (mime.equals(DIVX_TYPEMIME)) {
                dlnaOrgPnFlags = "DLNA.ORG_PN=AVI";
            } else if (mime.equals(WMV_TYPEMIME) && media != null && media.getHeight() > 700) {
                dlnaOrgPnFlags = "DLNA.ORG_PN=WMVHIGH_PRO";
            }
        } else {
            if (mime.equals(MPEG_TYPEMIME)) {
                dlnaOrgPnFlags = "DLNA.ORG_PN=" + getMPEG_PS_PALLocalizedValue(localizationValue);
                if (player != null) {
                    // VLC Web Video (Legacy) and tsMuxeR always output MPEG-TS
                    boolean isFileMPEGTS = TsMuxeRVideo.ID.equals(player.id()) || VideoLanVideoStreaming.ID.equals(player.id());
                    // Check if the renderer settings make the current engine always output MPEG-TS
                    if (!isFileMPEGTS && mediaRenderer.isTranscodeToMPEGTS() && (MEncoderVideo.ID.equals(player.id()) || FFMpegVideo.ID.equals(player.id()) || VLCVideo.ID.equals(player.id()) || AviSynthFFmpeg.ID.equals(player.id()) || AviSynthMEncoder.ID.equals(player.id()))) {
                        isFileMPEGTS = true;
                    }
                    boolean isMuxableResult = getMedia() != null && getMedia().isMuxable(mediaRenderer);
                    // If the engine is capable of automatically muxing to MPEG-TS and the setting is enabled, it might be MPEG-TS
                    if (!isFileMPEGTS && ((configurationSpecificToRenderer.isMencoderMuxWhenCompatible() && MEncoderVideo.ID.equals(player.id())) || (configurationSpecificToRenderer.isFFmpegMuxWithTsMuxerWhenCompatible() && FFMpegVideo.ID.equals(player.id())))) {
                        /**
                         * Media renderer needs ORG_PN to be accurate.
                         * If the value does not match the media, it won't play the media.
                         * Often we can lazily predict the correct value to send, but due to
                         * MEncoder needing to mux via tsMuxeR, we need to work it all out
                         * before even sending the file list to these devices.
                         * This is very time-consuming so we should a) avoid using this
                         * chunk of code whenever possible, and b) design a better system.
                         * Ideally we would just mux to MPEG-PS instead of MPEG-TS so we could
                         * know it will always be PS, but most renderers will not accept H.264
                         * inside MPEG-PS. Another option may be to always produce MPEG-TS
                         * instead and we should check if that will be OK for all renderers.
                         *
                         * This code block comes from Player.setAudioAndSubs()
                         */
                        if (mediaRenderer.isAccurateDLNAOrgPN()) {
                            boolean finishedMatchingPreferences = false;
                            OutputParams params = new OutputParams(configurationSpecificToRenderer);
                            if (params.aid == null && media != null && media.getFirstAudioTrack() != null) {
                                // check for preferred audio
                                DLNAMediaAudio dtsTrack = null;
                                StringTokenizer st = new StringTokenizer(configurationSpecificToRenderer.getAudioLanguages(), ",");
                                while (st.hasMoreTokens()) {
                                    String lang = st.nextToken().trim();
                                    LOGGER.trace("Looking for an audio track with lang: " + lang);
                                    for (DLNAMediaAudio audio : media.getAudioTracksList()) {
                                        if (audio.matchCode(lang)) {
                                            params.aid = audio;
                                            LOGGER.trace("Matched audio track: " + audio);
                                            break;
                                        }
                                        if (dtsTrack == null && audio.isDTS()) {
                                            dtsTrack = audio;
                                        }
                                    }
                                }
                                // preferred audio not found, take a default audio track, dts first if available
                                if (dtsTrack != null) {
                                    params.aid = dtsTrack;
                                    LOGGER.trace("Found priority audio track with DTS: " + dtsTrack);
                                } else {
                                    params.aid = media.getAudioTracksList().get(0);
                                    LOGGER.trace("Chose a default audio track: " + params.aid);
                                }
                            }
                            String currentLang = null;
                            DLNAMediaSubtitle matchedSub = null;
                            if (params.aid != null) {
                                currentLang = params.aid.getLang();
                            }
                            if (params.sid != null && params.sid.getId() == -1) {
                                LOGGER.trace("Don't want subtitles!");
                                params.sid = null;
                                media_subtitle = params.sid;
                                finishedMatchingPreferences = true;
                            }
                            /**
                             * Check for live subtitles
                             */
                            if (!finishedMatchingPreferences && params.sid != null && !StringUtils.isEmpty(params.sid.getLiveSubURL())) {
                                LOGGER.debug("Live subtitles " + params.sid.getLiveSubURL());
                                try {
                                    matchedSub = params.sid;
                                    String file = OpenSubtitle.fetchSubs(matchedSub.getLiveSubURL(), matchedSub.getLiveSubFile());
                                    if (!StringUtils.isEmpty(file)) {
                                        matchedSub.setExternalFile(new File(file), null);
                                        params.sid = matchedSub;
                                        media_subtitle = params.sid;
                                        finishedMatchingPreferences = true;
                                    }
                                } catch (IOException e) {
                                }
                            }
                            if (!finishedMatchingPreferences) {
                                StringTokenizer st = new StringTokenizer(configurationSpecificToRenderer.getAudioSubLanguages(), ";");
                                /**
                                 * Check for external and internal subtitles matching the user's language
                                 * preferences
                                 */
                                boolean matchedInternalSubtitles = false;
                                boolean matchedExternalSubtitles = false;
                                while (st.hasMoreTokens()) {
                                    String pair = st.nextToken();
                                    if (pair.contains(",")) {
                                        String audio = pair.substring(0, pair.indexOf(','));
                                        String sub = pair.substring(pair.indexOf(',') + 1);
                                        audio = audio.trim();
                                        sub = sub.trim();
                                        if (currentLang != null && LOGGER.isTraceEnabled()) {
                                            LOGGER.trace("Searching for a match for language \"{}\" with audio \"{}\" and subtitle \"{}\"", currentLang, audio, sub);
                                        }
                                        if (Iso639.isCodesMatching(audio, currentLang) || (currentLang != null && audio.equals("*"))) {
                                            if (sub.equals("off")) {
                                                /**
                                                 * Ignore the "off" language for external subtitles if the user setting is enabled
                                                 * TODO: Prioritize multiple external subtitles properly instead of just taking the first one we load
                                                 */
                                                if (configurationSpecificToRenderer.isForceExternalSubtitles()) {
                                                    for (DLNAMediaSubtitle present_sub : media.getSubtitleTracksList()) {
                                                        if (present_sub.getExternalFile() != null) {
                                                            matchedSub = present_sub;
                                                            matchedExternalSubtitles = true;
                                                            LOGGER.trace("Ignoring the \"off\" language because there are external subtitles");
                                                            break;
                                                        }
                                                    }
                                                }
                                                if (!matchedExternalSubtitles) {
                                                    matchedSub = new DLNAMediaSubtitle();
                                                    matchedSub.setLang("off");
                                                }
                                            } else if (getMedia() != null) {
                                                for (DLNAMediaSubtitle present_sub : media.getSubtitleTracksList()) {
                                                    if (present_sub.matchCode(sub) || sub.equals("*")) {
                                                        if (present_sub.getExternalFile() != null) {
                                                            if (configurationSpecificToRenderer.isAutoloadExternalSubtitles()) {
                                                                // Subtitle is external and we want external subtitles, look no further
                                                                matchedSub = present_sub;
                                                                LOGGER.trace("Matched external subtitles track: {}", matchedSub);
                                                                break;
                                                            }
                                                            // Subtitle is external but we do not want external subtitles, keep searching
                                                            LOGGER.trace("External subtitles ignored because of user setting: {}", present_sub);
                                                        } else if (!matchedInternalSubtitles) {
                                                            matchedSub = present_sub;
                                                            LOGGER.trace("Matched internal subtitles track: {}", matchedSub);
                                                            if (configurationSpecificToRenderer.isAutoloadExternalSubtitles()) {
                                                                // Subtitle is internal and we will wait to see if an external one is available instead
                                                                matchedInternalSubtitles = true;
                                                            } else {
                                                                // Subtitle is internal and we will use it
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            if (matchedSub != null && !matchedInternalSubtitles) {
                                                break;
                                            }
                                        }
                                    }
                                }
                                /**
                                 * Check for external subtitles that were skipped in the above code block
                                 * because they didn't match language preferences, if there wasn't already
                                 * a match and the user settings specify it.
                                 */
                                if (matchedSub == null && configurationSpecificToRenderer.isForceExternalSubtitles()) {
                                    for (DLNAMediaSubtitle present_sub : media.getSubtitleTracksList()) {
                                        if (present_sub.getExternalFile() != null) {
                                            matchedSub = present_sub;
                                            LOGGER.trace("Matched external subtitles track that did not match language preferences: " + matchedSub);
                                            break;
                                        }
                                    }
                                }
                                /**
                                 * Disable chosen subtitles if the user has disabled all subtitles or
                                 * if the language preferences have specified the "off" language.
                                 *
                                 * TODO: Can't we save a bunch of looping by checking for isDisableSubtitles
                                 * just after the Live Subtitles check above?
                                 */
                                if (matchedSub != null && params.sid == null) {
                                    if (configurationSpecificToRenderer.isDisableSubtitles() || (matchedSub.getLang() != null && matchedSub.getLang().equals("off"))) {
                                        LOGGER.trace("Disabled the subtitles: " + matchedSub);
                                    } else {
                                        if (mediaRenderer.isExternalSubtitlesFormatSupported(matchedSub, media)) {
                                            matchedSub.setSubsStreamable(true);
                                        }
                                        params.sid = matchedSub;
                                        media_subtitle = params.sid;
                                    }
                                }
                                /**
                                 * Check for forced subtitles.
                                 */
                                if (!configurationSpecificToRenderer.isDisableSubtitles() && params.sid == null && media != null) {
                                    // Check for subtitles again
                                    File video = new File(getSystemName());
                                    FileUtil.isSubtitlesExists(video, media, false);
                                    if (configurationSpecificToRenderer.isAutoloadExternalSubtitles()) {
                                        boolean forcedSubsFound = false;
                                        // Priority to external subtitles
                                        for (DLNAMediaSubtitle sub : media.getSubtitleTracksList()) {
                                            if (matchedSub != null && matchedSub.getLang() != null && matchedSub.getLang().equals("off")) {
                                                st = new StringTokenizer(configurationSpecificToRenderer.getForcedSubtitleTags(), ",");
                                                while (sub.getSubtitlesTrackTitleFromMetadata() != null && st.hasMoreTokens()) {
                                                    String forcedTags = st.nextToken();
                                                    forcedTags = forcedTags.trim();
                                                    if (sub.getSubtitlesTrackTitleFromMetadata().toLowerCase().contains(forcedTags) && Iso639.isCodesMatching(sub.getLang(), configurationSpecificToRenderer.getForcedSubtitleLanguage())) {
                                                        LOGGER.trace("Forcing preferred subtitles: " + sub.getLang() + "/" + sub.getSubtitlesTrackTitleFromMetadata());
                                                        LOGGER.trace("Forced subtitles track: " + sub);
                                                        if (sub.getExternalFile() != null) {
                                                            LOGGER.trace("Found external forced file: " + sub.getExternalFile().getAbsolutePath());
                                                        }
                                                        if (mediaRenderer.isExternalSubtitlesFormatSupported(sub, media)) {
                                                            sub.setSubsStreamable(true);
                                                        }
                                                        params.sid = sub;
                                                        media_subtitle = params.sid;
                                                        forcedSubsFound = true;
                                                        break;
                                                    }
                                                }
                                                if (forcedSubsFound == true) {
                                                    break;
                                                }
                                            } else {
                                                LOGGER.trace("Found subtitles track: " + sub);
                                                if (sub.getExternalFile() != null) {
                                                    LOGGER.trace("Found external file: " + sub.getExternalFile().getAbsolutePath());
                                                    if (mediaRenderer.isExternalSubtitlesFormatSupported(sub, media)) {
                                                        sub.setSubsStreamable(true);
                                                    }
                                                    params.sid = sub;
                                                    media_subtitle = params.sid;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    if (matchedSub != null && matchedSub.getLang() != null && matchedSub.getLang().equals("off")) {
                                        finishedMatchingPreferences = true;
                                    }
                                    if (!finishedMatchingPreferences && params.sid == null) {
                                        st = new StringTokenizer(UMSUtils.getLangList(params.mediaRenderer), ",");
                                        while (st.hasMoreTokens()) {
                                            String lang = st.nextToken();
                                            lang = lang.trim();
                                            LOGGER.trace("Looking for a subtitle track with lang: " + lang);
                                            for (DLNAMediaSubtitle sub : media.getSubtitleTracksList()) {
                                                if (sub.matchCode(lang) && !(!configurationSpecificToRenderer.isAutoloadExternalSubtitles() && sub.getExternalFile() != null)) {
                                                    if (mediaRenderer.isExternalSubtitlesFormatSupported(sub, media)) {
                                                        sub.setSubsStreamable(true);
                                                    }
                                                    params.sid = sub;
                                                    LOGGER.trace("Matched subtitles track: " + params.sid);
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            if (media_subtitle == null) {
                                LOGGER.trace("We do not want a subtitle for " + getName());
                            } else {
                                LOGGER.trace("We do want a subtitle for " + getName());
                            }
                        }
                        /**
                         * If:
                         * - There are no subtitles
                         * - This is not a DVD track
                         * - The media is muxable
                         * - The renderer accepts media muxed to MPEG-TS
                         * then the file is MPEG-TS
                         */
                        if (media_subtitle == null && !hasExternalSubtitles() && media != null && media.getDvdtrack() == 0 && isMuxableResult && mediaRenderer.isMuxH264MpegTS()) {
                            isFileMPEGTS = true;
                        }
                    }
                    if (isFileMPEGTS) {
                        dlnaOrgPnFlags = "DLNA.ORG_PN=" + getMPEG_TS_SD_EU_ISOLocalizedValue(localizationValue);
                        if (media.isH264() && !VideoLanVideoStreaming.ID.equals(player.id()) && isMuxableResult) {
                            dlnaOrgPnFlags = "DLNA.ORG_PN=AVC_TS_HD_24_AC3_ISO";
                            if (mediaRenderer.isTranscodeToMPEGTSH264AAC()) {
                                dlnaOrgPnFlags = "DLNA.ORG_PN=AVC_TS_HP_HD_AAC";
                            }
                        }
                    }
                } else if (media != null) {
                    if (media.isMpegTS()) {
                        dlnaOrgPnFlags = "DLNA.ORG_PN=" + getMPEG_TS_EULocalizedValue(localizationValue, media.isHDVideo());
                        if (media.isH264()) {
                            dlnaOrgPnFlags = "DLNA.ORG_PN=AVC_TS_HD_50_AC3";
                            if (mediaRenderer.isTranscodeToMPEGTSH264AAC()) {
                                dlnaOrgPnFlags = "DLNA.ORG_PN=AVC_TS_HP_HD_AAC";
                            }
                        }
                    }
                }
            } else if (media != null && mime.equals("video/vnd.dlna.mpeg-tts")) {
                // patters - on Sony BDP m2ts clips aren't listed without this
                dlnaOrgPnFlags = "DLNA.ORG_PN=" + getMPEG_TS_EULocalizedValue(localizationValue, media.isHDVideo());
            } else if (media != null && mime.equals(JPEG_TYPEMIME)) {
                int width = media.getWidth();
                int height = media.getHeight();
                if (width > 1024 || height > 768) {
                    // 1024 * 768
                    dlnaOrgPnFlags = "DLNA.ORG_PN=JPEG_LRG";
                } else if (width > 640 || height > 480) {
                    // 640 * 480
                    dlnaOrgPnFlags = "DLNA.ORG_PN=JPEG_MED";
                } else if (width > 160 || height > 160) {
                    // 160 * 160
                    dlnaOrgPnFlags = "DLNA.ORG_PN=JPEG_SM";
                } else {
                    dlnaOrgPnFlags = "DLNA.ORG_PN=JPEG_TN";
                }
            } else if (mime.equals(AUDIO_MP3_TYPEMIME)) {
                dlnaOrgPnFlags = "DLNA.ORG_PN=MP3";
            } else if (mime.substring(0, 9).equals(AUDIO_LPCM_TYPEMIME) || mime.equals(AUDIO_WAV_TYPEMIME)) {
                dlnaOrgPnFlags = "DLNA.ORG_PN=LPCM";
            }
        }
        if (dlnaOrgPnFlags != null) {
            dlnaOrgPnFlags = "DLNA.ORG_PN=" + mediaRenderer.getDLNAPN(dlnaOrgPnFlags.substring(12));
        }
    }
    return dlnaOrgPnFlags;
}
Also used : PmsConfiguration(net.pms.configuration.PmsConfiguration) OutputParams(net.pms.io.OutputParams)

Example 4 with PmsConfiguration

use of net.pms.configuration.PmsConfiguration in project UniversalMediaServer by UniversalMediaServer.

the class DLNAResource method getDidlString.

/**
 * Returns an XML (DIDL) representation of the DLNA node. It gives a
 * complete representation of the item, with as many tags as available.
 * Recommendations as per UPNP specification are followed where possible.
 *
 * @param mediaRenderer
 *            Media Renderer for which to represent this information. Useful
 *            for some hacks.
 * @return String representing the item. An example would start like this:
 *         {@code <container id="0$1" childCount="1" parentID="0" restricted="1">}
 */
public final String getDidlString(RendererConfiguration mediaRenderer) {
    // Use device-specific pms conf, if any
    PmsConfiguration configurationSpecificToRenderer = PMS.getConfiguration(mediaRenderer);
    StringBuilder sb = new StringBuilder();
    boolean subsAreValidForStreaming = false;
    boolean xbox360 = mediaRenderer.isXbox360();
    // Cache this as some implementations actually call the file system
    boolean isFolder = isFolder();
    if (!isFolder) {
        if (format != null && format.isVideo()) {
            if (!configurationSpecificToRenderer.isDisableSubtitles() && (player != null && mediaRenderer.streamSubsForTranscodedVideo() || player == null) && media_subtitle != null && media_subtitle.isStreamable()) {
                subsAreValidForStreaming = true;
                LOGGER.trace("Setting subsAreValidForStreaming to true for " + media_subtitle.getExternalFile().getName());
            } else {
                LOGGER.trace("Not setting subsAreValidForStreaming and it is false for " + getName());
            }
        }
        openTag(sb, "item");
    } else {
        openTag(sb, "container");
    }
    String id = getResourceId();
    if (xbox360) {
        // Ensure the xbox 360 doesn't confuse our ids with its own virtual folder ids.
        id += "$";
    }
    addAttribute(sb, "id", id);
    if (isFolder) {
        if (!isDiscovered() && childrenNumber() == 0) {
            // When a folder has not been scanned for resources, it will automatically have zero children.
            // Some renderers like XBMC will assume a folder is empty when encountering childCount="0" and
            // will not display the folder. By returning childCount="1" these renderers will still display
            // the folder. When it is opened, its children will be discovered and childrenNumber() will be
            // set to the right value.
            addAttribute(sb, "childCount", 1);
        } else {
            addAttribute(sb, "childCount", childrenNumber());
        }
    }
    id = getParentId();
    if (xbox360 && getFakeParentId() == null) {
        // Ensure the xbox 360 doesn't confuse our ids with its own virtual folder ids.
        id += "$";
    }
    addAttribute(sb, "parentID", id);
    addAttribute(sb, "restricted", "1");
    endTag(sb);
    StringBuilder wireshark = new StringBuilder();
    final DLNAMediaAudio firstAudioTrack = media != null ? media.getFirstAudioTrack() : null;
    /**
     * Use the track title for audio files, otherwise use the filename.
     */
    String title;
    if (firstAudioTrack != null && media.isAudio() && StringUtils.isNotBlank(firstAudioTrack.getSongname())) {
        title = firstAudioTrack.getSongname();
    } else {
        // Ditlew - org
        title = (isFolder || subsAreValidForStreaming) ? getDisplayName(null, false) : mediaRenderer.getUseSameExtension(getDisplayName(mediaRenderer, false));
    }
    title = resumeStr(title);
    addXMLTagAndAttribute(sb, "dc:title", encodeXML(mediaRenderer.getDcTitle(title, nameSuffix, this)));
    wireshark.append("\"").append(title).append("\"");
    if (firstAudioTrack != null) {
        if (StringUtils.isNotBlank(firstAudioTrack.getAlbum())) {
            addXMLTagAndAttribute(sb, "upnp:album", encodeXML(firstAudioTrack.getAlbum()));
        }
        if (StringUtils.isNotBlank(firstAudioTrack.getArtist())) {
            addXMLTagAndAttribute(sb, "upnp:artist", encodeXML(firstAudioTrack.getArtist()));
            addXMLTagAndAttribute(sb, "dc:creator", encodeXML(firstAudioTrack.getArtist()));
        }
        if (StringUtils.isNotBlank(firstAudioTrack.getGenre())) {
            addXMLTagAndAttribute(sb, "upnp:genre", encodeXML(firstAudioTrack.getGenre()));
        }
        if (firstAudioTrack.getTrack() > 0) {
            addXMLTagAndAttribute(sb, "upnp:originalTrackNumber", "" + firstAudioTrack.getTrack());
        }
    }
    MediaType mediaType = media != null ? media.getMediaType() : MediaType.UNKNOWN;
    if (!isFolder && mediaType == MediaType.IMAGE) {
        appendImage(sb, mediaRenderer);
    } else if (!isFolder) {
        int indexCount = 1;
        if (mediaRenderer.isDLNALocalizationRequired()) {
            indexCount = getDLNALocalesCount();
        }
        for (int c = 0; c < indexCount; c++) {
            openTag(sb, "res");
            addAttribute(sb, "xmlns:dlna", "urn:schemas-dlna-org:metadata-1-0/");
            String dlnaOrgPnFlags = getDlnaOrgPnFlags(mediaRenderer, c);
            String tempString = "http-get:*:" + getRendererMimeType(mediaRenderer) + ":" + (dlnaOrgPnFlags != null ? (dlnaOrgPnFlags + ";") : "") + getDlnaOrgOpFlags(mediaRenderer);
            wireshark.append(' ').append(tempString);
            addAttribute(sb, "protocolInfo", tempString);
            if (subsAreValidForStreaming && mediaRenderer.offerSubtitlesByProtocolInfo() && !mediaRenderer.useClosedCaption()) {
                addAttribute(sb, "pv:subtitleFileType", media_subtitle.getType().getExtension().toUpperCase());
                wireshark.append(" pv:subtitleFileType=").append(media_subtitle.getType().getExtension().toUpperCase());
                addAttribute(sb, "pv:subtitleFileUri", getSubsURL(media_subtitle));
                wireshark.append(" pv:subtitleFileUri=").append(getSubsURL(media_subtitle));
            }
            if (getFormat() != null && getFormat().isVideo() && media != null && media.isMediaparsed()) {
                if (player == null) {
                    wireshark.append(" size=").append(media.getSize());
                    addAttribute(sb, "size", media.getSize());
                } else {
                    long transcoded_size = mediaRenderer.getTranscodedSize();
                    if (transcoded_size != 0) {
                        wireshark.append(" size=").append(transcoded_size);
                        addAttribute(sb, "size", transcoded_size);
                    }
                }
                if (media.getDuration() != null) {
                    if (getSplitRange().isEndLimitAvailable()) {
                        wireshark.append(" duration=").append(StringUtil.formatDLNADuration(getSplitRange().getDuration()));
                        addAttribute(sb, "duration", StringUtil.formatDLNADuration(getSplitRange().getDuration()));
                    } else {
                        wireshark.append(" duration=").append(media.getDurationString());
                        addAttribute(sb, "duration", media.getDurationString());
                    }
                }
                if (media.getResolution() != null) {
                    if (player != null && mediaRenderer.isKeepAspectRatio()) {
                        addAttribute(sb, "resolution", getResolutionForKeepAR(media.getWidth(), media.getHeight()));
                    } else {
                        addAttribute(sb, "resolution", media.getResolution());
                    }
                }
                addAttribute(sb, "bitrate", media.getRealVideoBitrate());
                if (firstAudioTrack != null) {
                    if (firstAudioTrack.getAudioProperties().getNumberOfChannels() > 0) {
                        addAttribute(sb, "nrAudioChannels", firstAudioTrack.getAudioProperties().getNumberOfChannels());
                    }
                    if (firstAudioTrack.getSampleFrequency() != null) {
                        addAttribute(sb, "sampleFrequency", firstAudioTrack.getSampleFrequency());
                    }
                }
            } else if (getFormat() != null && getFormat().isImage()) {
                if (media != null && media.isMediaparsed()) {
                    wireshark.append(" size=").append(media.getSize());
                    addAttribute(sb, "size", media.getSize());
                    if (media.getResolution() != null) {
                        addAttribute(sb, "resolution", media.getResolution());
                    }
                } else {
                    wireshark.append(" size=").append(length());
                    addAttribute(sb, "size", length());
                }
            } else if (getFormat() != null && getFormat().isAudio()) {
                if (media != null && media.isMediaparsed()) {
                    if (media.getBitrate() > 0) {
                        addAttribute(sb, "bitrate", media.getBitrate());
                    }
                    if (media.getDuration() != null && media.getDuration().doubleValue() != 0.0) {
                        wireshark.append(" duration=").append(StringUtil.formatDLNADuration(media.getDuration()));
                        addAttribute(sb, "duration", StringUtil.formatDLNADuration(media.getDuration()));
                    }
                    int transcodeFrequency = -1;
                    int transcodeNumberOfChannels = -1;
                    if (firstAudioTrack != null) {
                        if (player == null) {
                            if (firstAudioTrack.getSampleFrequency() != null) {
                                addAttribute(sb, "sampleFrequency", firstAudioTrack.getSampleFrequency());
                            }
                            if (firstAudioTrack.getAudioProperties().getNumberOfChannels() > 0) {
                                addAttribute(sb, "nrAudioChannels", firstAudioTrack.getAudioProperties().getNumberOfChannels());
                            }
                        } else {
                            if (configurationSpecificToRenderer.isAudioResample()) {
                                transcodeFrequency = mediaRenderer.isTranscodeAudioTo441() ? 44100 : 48000;
                                transcodeNumberOfChannels = 2;
                            } else {
                                transcodeFrequency = firstAudioTrack.getSampleRate();
                                transcodeNumberOfChannels = firstAudioTrack.getAudioProperties().getNumberOfChannels();
                            }
                            if (transcodeFrequency > 0) {
                                addAttribute(sb, "sampleFrequency", transcodeFrequency);
                            }
                            if (transcodeNumberOfChannels > 0) {
                                addAttribute(sb, "nrAudioChannels", transcodeNumberOfChannels);
                            }
                        }
                    }
                    if (player == null) {
                        if (media.getSize() != 0) {
                            wireshark.append(" size=").append(media.getSize());
                            addAttribute(sb, "size", media.getSize());
                        }
                    } else {
                        // Calculate WAV size
                        if (firstAudioTrack != null && media.getDurationInSeconds() > 0.0 && transcodeFrequency > 0 && transcodeNumberOfChannels > 0) {
                            int finalSize = (int) (media.getDurationInSeconds() * transcodeFrequency * 2 * transcodeNumberOfChannels);
                            LOGGER.trace("Calculated transcoded size for {}: {}", getSystemName(), finalSize);
                            wireshark.append(" size=").append(finalSize);
                            addAttribute(sb, "size", finalSize);
                        } else if (media.getSize() > 0) {
                            LOGGER.trace("Could not calculate transcoded size for {}, using file size: {}", getSystemName(), media.getSize());
                            wireshark.append(" size=").append(media.getSize());
                            addAttribute(sb, "size", media.getSize());
                        }
                    }
                } else {
                    wireshark.append(" size=").append(length());
                    addAttribute(sb, "size", length());
                }
            } else {
                wireshark.append(" size=").append(DLNAMediaInfo.TRANS_SIZE).append(" duration=09:59:59");
                addAttribute(sb, "size", DLNAMediaInfo.TRANS_SIZE);
                addAttribute(sb, "duration", "09:59:59");
                addAttribute(sb, "bitrate", "1000000");
            }
            endTag(sb);
            // Add transcoded format extension to the output stream URL.
            String transcodedExtension = "";
            if (player != null && media != null) {
                // Note: Can't use instanceof below because the audio classes inherit the corresponding video class
                if (media.isVideo()) {
                    if (mediaRenderer.isTranscodeToMPEGTS()) {
                        transcodedExtension = "_transcoded_to.ts";
                    } else if (mediaRenderer.isTranscodeToWMV() && !xbox360) {
                        transcodedExtension = "_transcoded_to.wmv";
                    } else {
                        transcodedExtension = "_transcoded_to.mpg";
                    }
                } else if (media.isAudio()) {
                    if (mediaRenderer.isTranscodeToMP3()) {
                        transcodedExtension = "_transcoded_to.mp3";
                    } else if (mediaRenderer.isTranscodeToWAV()) {
                        transcodedExtension = "_transcoded_to.wav";
                    } else {
                        transcodedExtension = "_transcoded_to.pcm";
                    }
                }
            }
            wireshark.append(' ').append(getFileURL()).append(transcodedExtension);
            sb.append(getFileURL()).append(transcodedExtension);
            LOGGER.trace("Network debugger: " + wireshark.toString());
            wireshark.setLength(0);
            closeTag(sb, "res");
        }
    }
    if (subsAreValidForStreaming) {
        String subsURL = getSubsURL(media_subtitle);
        if (mediaRenderer.useClosedCaption()) {
            openTag(sb, "sec:CaptionInfoEx");
            addAttribute(sb, "sec:type", "srt");
            endTag(sb);
            sb.append(subsURL);
            closeTag(sb, "sec:CaptionInfoEx");
            LOGGER.trace("Network debugger: sec:CaptionInfoEx: sec:type=srt " + subsURL);
        } else if (mediaRenderer.offerSubtitlesAsResource()) {
            openTag(sb, "res");
            String subtitlesFormat = media_subtitle.getType().getExtension();
            if (StringUtils.isBlank(subtitlesFormat)) {
                subtitlesFormat = "plain";
            }
            addAttribute(sb, "protocolInfo", "http-get:*:text/" + subtitlesFormat + ":*");
            endTag(sb);
            sb.append(subsURL);
            closeTag(sb, "res");
            LOGGER.trace("Network debugger: http-get:*:text/" + subtitlesFormat + ":*" + subsURL);
        }
    }
    if (mediaType != MediaType.IMAGE && (!isFolder || mediaRenderer.isSendFolderThumbnails() || this instanceof DVDISOFile)) {
        appendThumbnail(sb, mediaType, mediaRenderer);
    }
    if (getLastModified() > 0 && mediaRenderer.isSendDateMetadata()) {
        addXMLTagAndAttribute(sb, "dc:date", SDF_DATE.format(new Date(getLastModified())));
    }
    String uclass;
    if (first != null && media != null && !media.isSecondaryFormatValid()) {
        uclass = "dummy";
    } else if (isFolder) {
        uclass = "object.container.storageFolder";
        if (xbox360 && getFakeParentId() != null) {
            switch(getFakeParentId()) {
                case "7":
                    uclass = "object.container.album.musicAlbum";
                    break;
                case "6":
                    uclass = "object.container.person.musicArtist";
                    break;
                case "5":
                    uclass = "object.container.genre.musicGenre";
                    break;
                case "F":
                    uclass = "object.container.playlistContainer";
                    break;
            }
        }
    } else if (mediaType == MediaType.IMAGE || mediaType == MediaType.UNKNOWN && format != null && format.isImage()) {
        uclass = "object.item.imageItem.photo";
    } else if (mediaType == MediaType.AUDIO || mediaType == MediaType.UNKNOWN && format != null && format.isAudio()) {
        uclass = "object.item.audioItem.musicTrack";
    } else {
        uclass = "object.item.videoItem";
    }
    addXMLTagAndAttribute(sb, "upnp:class", uclass);
    if (isFolder) {
        closeTag(sb, "container");
    } else {
        closeTag(sb, "item");
    }
    return sb.toString();
}
Also used : PmsConfiguration(net.pms.configuration.PmsConfiguration)

Example 5 with PmsConfiguration

use of net.pms.configuration.PmsConfiguration in project UniversalMediaServer by UniversalMediaServer.

the class PMS method main.

public static void main(String[] args) {
    boolean displayProfileChooser = false;
    boolean denyHeadless = false;
    File profilePath = null;
    CacheLogger.startCaching();
    // Make sure that no other versions of JNA found on the system is used
    System.setProperty("jna.nosys", "true");
    // Set headless options if given as a system property when launching the JVM
    if (System.getProperty(CONSOLE, "").equalsIgnoreCase(Boolean.toString(true))) {
        forceHeadless();
    }
    if (System.getProperty(NOCONSOLE, "").equalsIgnoreCase(Boolean.toString(true))) {
        denyHeadless = true;
    }
    if (args.length > 0) {
        Pattern pattern = Pattern.compile(PROFILE);
        for (String arg : args) {
            switch(arg.trim().toLowerCase(Locale.ROOT)) {
                case HEADLESS:
                case CONSOLE:
                    forceHeadless();
                    break;
                case NATIVELOOK:
                    System.setProperty(NATIVELOOK, Boolean.toString(true));
                    break;
                case SCROLLBARS:
                    System.setProperty(SCROLLBARS, Boolean.toString(true));
                    break;
                case NOCONSOLE:
                    denyHeadless = true;
                    break;
                case PROFILES:
                    displayProfileChooser = true;
                    break;
                case TRACE:
                    traceMode = 2;
                    break;
                default:
                    Matcher matcher = pattern.matcher(arg);
                    if (matcher.find()) {
                        profilePath = new File(matcher.group(1));
                    }
                    break;
            }
        }
    }
    try {
        Toolkit.getDefaultToolkit();
    } catch (AWTError t) {
        LOGGER.error("Toolkit error: " + t.getClass().getName() + ": " + t.getMessage());
        forceHeadless();
    }
    if (isHeadless() && denyHeadless) {
        System.err.println("Either a graphics environment isn't available or headless " + "mode is forced, but \"noconsole\" is specified. " + PMS.NAME + " can't start, exiting.");
        System.exit(1);
    } else if (!isHeadless()) {
        LooksFrame.initializeLookAndFeel();
    }
    if (profilePath != null) {
        if (!FileUtil.isValidFileName(profilePath.getName())) {
            LOGGER.warn("Invalid file name in profile argument - using default profile");
        } else if (!profilePath.exists()) {
            LOGGER.warn("Specified profile ({}) doesn't exist - using default profile", profilePath.getAbsolutePath());
        } else {
            LOGGER.debug("Using specified profile: {}", profilePath.getAbsolutePath());
            System.setProperty("ums.profile.path", profilePath.getAbsolutePath());
        }
    } else if (!isHeadless() && displayProfileChooser) {
        ProfileChooser.display();
    }
    try {
        setConfiguration(new PmsConfiguration());
        assert getConfiguration() != null;
        /* Rename previous log file to .prev
			 * Log file location is unknown at this point, it's finally decided during loadFile() below
			 * but the file is also truncated at the same time, so we'll have to try a qualified guess
			 * for the file location.
			 */
        // Set root level from configuration here so that logging is available during renameOldLogFile();
        LoggingConfig.setRootLevel(Level.toLevel(getConfiguration().getRootLogLevel()));
        renameOldLogFile();
        // Load the (optional) LogBack config file.
        // This has to be called after 'new PmsConfiguration'
        LoggingConfig.loadFile();
        // Check TRACE mode
        if (traceMode == 2) {
            LoggingConfig.setRootLevel(Level.TRACE);
            LOGGER.debug("Forcing debug level to TRACE");
        } else {
            // Remember whether logging level was TRACE/ALL at startup
            traceMode = LoggingConfig.getRootLevel().toInt() <= Level.TRACE_INT ? 1 : 0;
        }
        // Configure syslog unless in forced trace mode
        if (traceMode != 2 && configuration.getLoggingUseSyslog()) {
            LoggingConfig.setSyslog();
        }
        // Configure log buffering
        if (traceMode != 2 && configuration.getLoggingBuffered()) {
            LoggingConfig.setBuffered(true);
        } else if (traceMode == 2) {
            // force unbuffered regardless of logback.xml if in forced trace mode
            LOGGER.debug("Forcing unbuffered verbose logging");
            LoggingConfig.setBuffered(false);
            LoggingConfig.forceVerboseFileEncoder();
        }
        // Write buffered messages to the log now that logger is configured
        CacheLogger.stopAndFlush();
        LOGGER.debug(new Date().toString());
        try {
            getConfiguration().initCred();
        } catch (IOException e) {
            LOGGER.debug("Error initializing plugin credentials: {}", e);
        }
        if (getConfiguration().isRunSingleInstance()) {
            killOld();
        }
        // Create the PMS instance returned by get()
        // Calls new() then init()
        createInstance();
    } catch (ConfigurationException t) {
        String errorMessage = String.format("Configuration error: %s: %s", t.getClass().getName(), t.getMessage());
        LOGGER.error(errorMessage);
        if (!isHeadless() && instance != null) {
            JOptionPane.showMessageDialog((SwingUtilities.getWindowAncestor((Component) instance.getFrame())), errorMessage, Messages.getString("PMS.42"), JOptionPane.ERROR_MESSAGE);
        }
    }
}
Also used : Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) PmsConfiguration(net.pms.configuration.PmsConfiguration) ConfigurationException(org.apache.commons.configuration.ConfigurationException)

Aggregations

PmsConfiguration (net.pms.configuration.PmsConfiguration)32 File (java.io.File)7 ProcessWrapperImpl (net.pms.io.ProcessWrapperImpl)7 ArrayList (java.util.ArrayList)6 OutputParams (net.pms.io.OutputParams)5 IOException (java.io.IOException)4 ProcessWrapper (net.pms.io.ProcessWrapper)4 LoggerContext (ch.qos.logback.classic.LoggerContext)3 SyslogAppender (ch.qos.logback.classic.net.SyslogAppender)3 ILoggingEvent (ch.qos.logback.classic.spi.ILoggingEvent)3 Appender (ch.qos.logback.core.Appender)3 ConsoleAppender (ch.qos.logback.core.ConsoleAppender)3 FileAppender (ch.qos.logback.core.FileAppender)3 OutputStreamAppender (ch.qos.logback.core.OutputStreamAppender)3 RendererConfiguration (net.pms.configuration.RendererConfiguration)3 PipeProcess (net.pms.io.PipeProcess)3 ThresholdFilter (ch.qos.logback.classic.filter.ThresholdFilter)2 PrintWriter (java.io.PrintWriter)2 StringTokenizer (java.util.StringTokenizer)2 DLNAMediaAudio (net.pms.dlna.DLNAMediaAudio)2