use of net.pms.external.AdditionalResourceFolderListener in project UniversalMediaServer by UniversalMediaServer.
the class DLNAResource method addChild.
public void addChild(DLNAResource child, boolean isNew) {
// child may be null (spotted - via rootFolder.addChild() - in a misbehaving plugin
if (child == null) {
LOGGER.error("A plugin has attempted to add a null child to \"{}\"", getName());
LOGGER.debug("Error info:", new NullPointerException("Invalid DLNA resource"));
return;
}
child.parent = this;
child.masterParent = masterParent;
if (parent != null) {
defaultRenderer = parent.getDefaultRenderer();
}
if (PMS.filter(defaultRenderer, child)) {
LOGGER.debug("Resource " + child.getName() + " is filtered out for render " + defaultRenderer.getRendererName());
return;
}
if (configuration.useCode() && !PMS.get().masterCodeValid()) {
String code = PMS.get().codeDb().getCode(child);
if (StringUtils.isNotEmpty(code)) {
DLNAResource cobj = child.isCoded();
if (cobj == null || !((CodeEnter) cobj).getCode().equals(code)) {
LOGGER.debug("Resource " + child + " is coded add code folder");
CodeEnter ce = new CodeEnter(child);
ce.parent = this;
ce.defaultRenderer = this.getDefaultRenderer();
ce.setCode(code);
addChildInternal(ce);
return;
}
}
}
try {
if (child.isValid()) {
if (child.format != null) {
// Do not add unsupported media formats to the list
if (defaultRenderer != null && !defaultRenderer.supportsFormat(child.format)) {
LOGGER.trace("Ignoring file \"{}\" because it is not supported by renderer \"{}\"", child.getName(), defaultRenderer.getRendererName());
children.remove(child);
return;
}
// Hide watched videos depending user preference
if (FullyPlayed.isHideFullyPlayed(child)) {
LOGGER.trace("Ignoring video file \"{}\" because it has been watched", child.getName());
return;
}
}
LOGGER.trace("{} child \"{}\" with class \"{}\"", isNew ? "Adding new" : "Updating", child.getName(), child.getClass().getSimpleName());
if (allChildrenAreFolders && !child.isFolder()) {
allChildrenAreFolders = false;
}
child.resHash = Math.abs(child.getSystemName().hashCode() + resumeHash());
DLNAResource resumeRes = null;
boolean addResumeFile = false;
ResumeObj r = ResumeObj.create(child);
if (r != null) {
resumeRes = child.clone();
resumeRes.resume = r;
resumeRes.resHash = child.resHash;
addResumeFile = true;
}
if (child.format != null) {
// - we have media info (via parserV2, playback info, or a plugin)
if (child.format.transcodable() || child.media != null) {
if (child.media == null) {
child.media = new DLNAMediaInfo();
}
// Try to determine a player to use for transcoding.
Player playerTranscoding = null;
// First, try to match a player from recently played folder or based on the name of the DLNAResource
// or its parent. If the name ends in "[unique player id]", that player
// is preferred.
String name = getName();
if (configuration.isShowRecentlyPlayedFolder()) {
playerTranscoding = child.player;
} else {
for (Player p : PlayerFactory.getPlayers()) {
String end = "[" + p.id() + "]";
if (name.endsWith(end)) {
nametruncate = name.lastIndexOf(end);
playerTranscoding = p;
LOGGER.trace("Selecting player based on name end");
break;
} else if (parent != null && parent.getName().endsWith(end)) {
parent.nametruncate = parent.getName().lastIndexOf(end);
playerTranscoding = p;
LOGGER.trace("Selecting player based on parent name end");
break;
}
}
}
// match a player based on media information and format.
if (playerTranscoding == null || (hasExternalSubtitles() && defaultRenderer.isSubtitlesStreamingSupported())) {
playerTranscoding = child.resolvePlayer(defaultRenderer);
}
child.setPlayer(playerTranscoding);
child.setPreferredMimeType(defaultRenderer);
if (resumeRes != null) {
resumeRes.player = playerTranscoding;
}
if (!allChildrenAreFolders) {
child.setDefaultRenderer(defaultRenderer);
// Should the child be added to the #--TRANSCODE--# folder?
if ((child.format.isVideo() || child.format.isAudio()) && child.isTranscodeFolderAvailable()) {
// true: create (and append) the #--TRANSCODE--# folder to this
// folder if supported/enabled and if it doesn't already exist
VirtualFolder transcodeFolder = getTranscodeFolder(true);
if (transcodeFolder != null) {
VirtualFolder fileTranscodeFolder = new FileTranscodeVirtualFolder(child.getDisplayName(), null);
DLNAResource newChild = child.clone();
newChild.player = playerTranscoding;
newChild.media = child.media;
fileTranscodeFolder.addChildInternal(newChild);
LOGGER.trace("Adding \"{}\" to transcode folder for player: \"{}\"", child.getName(), playerTranscoding);
transcodeFolder.updateChild(fileTranscodeFolder);
}
}
if (child.format.isVideo() && child.isSubSelectable() && !(this instanceof SubSelFile)) {
VirtualFolder vf = getSubSelector(true);
if (vf != null) {
DLNAResource newChild = child.clone();
newChild.player = playerTranscoding;
newChild.media = child.media;
LOGGER.trace("Duplicate subtitle " + child.getName() + " with player: " + playerTranscoding);
vf.addChild(new SubSelFile(newChild));
}
}
if (configuration.isDynamicPls() && !child.isFolder() && defaultRenderer != null && !defaultRenderer.isNoDynPlsFolder()) {
addDynamicPls(child);
}
for (ExternalListener listener : ExternalFactory.getExternalListeners()) {
if (listener instanceof AdditionalResourceFolderListener) {
try {
((AdditionalResourceFolderListener) listener).addAdditionalFolder(this, child);
} catch (Throwable t) {
LOGGER.error("Failed to add additional folder for listener of type: \"{}\"", listener.getClass(), t);
}
}
}
} else if (!child.format.isCompatible(child.media, defaultRenderer) && !child.isFolder()) {
LOGGER.trace("Ignoring file \"{}\" because it is not compatible with renderer \"{}\"", child.getName(), defaultRenderer.getRendererName());
children.remove(child);
}
}
if (resumeRes != null && resumeRes.media != null) {
resumeRes.media.setThumbready(false);
}
/**
* Secondary format is currently only used to provide 24-bit FLAC to PS3 by
* sending it as a fake video. This can be made more reusable with a renderer
* config setting like Mux24BitFlacToVideo if we ever have another purpose
* for it, which I doubt we will have.
*/
if (child.format.getSecondaryFormat() != null && child.media != null && defaultRenderer != null && defaultRenderer.supportsFormat(child.format.getSecondaryFormat()) && defaultRenderer.isPS3()) {
DLNAResource newChild = child.clone();
newChild.setFormat(newChild.format.getSecondaryFormat());
LOGGER.trace("Detected secondary format \"{}\" for \"{}\"", newChild.format.toString(), newChild.getName());
newChild.first = child;
child.second = newChild;
if (!newChild.format.isCompatible(newChild.media, defaultRenderer)) {
Player playerTranscoding = PlayerFactory.getPlayer(newChild);
newChild.setPlayer(playerTranscoding);
LOGGER.trace("Secondary format \"{}\" will use player \"{}\" for \"{}\"", newChild.format.toString(), newChild.getPlayer().name(), newChild.getName());
}
if (child.media != null && child.media.isSecondaryFormatValid()) {
addChild(newChild);
LOGGER.trace("Adding secondary format \"{}\" for \"{}\"", newChild.format.toString(), newChild.getName());
} else {
LOGGER.trace("Ignoring secondary format \"{}\" for \"{}\": invalid format", newChild.format.toString(), newChild.getName());
}
}
}
if (addResumeFile && resumeRes != null) {
resumeRes.setDefaultRenderer(child.getDefaultRenderer());
addChildInternal(resumeRes);
}
if (isNew) {
addChildInternal(child);
}
}
} catch (Throwable t) {
LOGGER.error("Error adding child: \"{}\"", child.getName(), t);
child.parent = null;
children.remove(child);
}
}
Aggregations