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);
}
}
}
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;
}
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;
}
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();
}
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);
}
}
}
Aggregations