use of net.pms.external.ExternalListener 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);
}
}
use of net.pms.external.ExternalListener in project UniversalMediaServer by UniversalMediaServer.
the class DLNAResource method startPlaying.
/**
* Plugin implementation. When this item is going to play, it will notify all the
* StartStopListener objects available.
*
* @param rendererId
* @param incomingRenderer
*
* @see StartStopListener
*/
public void startPlaying(final String rendererId, final RendererConfiguration incomingRenderer) {
final String requestId = getRequestId(rendererId);
synchronized (requestIdToRefcount) {
Integer temp = requestIdToRefcount.get(requestId);
if (temp == null) {
temp = 0;
}
final Integer refCount = temp;
requestIdToRefcount.put(requestId, refCount + 1);
if (refCount == 0) {
final DLNAResource self = this;
Runnable r = new Runnable() {
@Override
public void run() {
InetAddress rendererIp;
try {
rendererIp = InetAddress.getByName(rendererId);
RendererConfiguration renderer;
if (incomingRenderer == null) {
renderer = RendererConfiguration.getRendererConfigurationBySocketAddress(rendererIp);
} else {
renderer = incomingRenderer;
}
String rendererName = "unknown renderer";
try {
renderer.setPlayingRes(self);
rendererName = renderer.getRendererName().replaceAll("\n", "");
} catch (NullPointerException e) {
}
if (!quietPlay()) {
LOGGER.info("Started playing " + getName() + " on your " + rendererName);
LOGGER.debug("The full filename of which is: " + getSystemName() + " and the address of the renderer is: " + rendererId);
}
} catch (UnknownHostException ex) {
LOGGER.debug("" + ex);
}
startTime = System.currentTimeMillis();
for (final ExternalListener listener : ExternalFactory.getExternalListeners()) {
if (listener instanceof StartStopListener) {
// run these asynchronously for slow handlers (e.g. logging, scrobbling)
Runnable fireStartStopEvent = new Runnable() {
@Override
public void run() {
try {
((StartStopListener) listener).nowPlaying(media, self);
} catch (Throwable t) {
LOGGER.error("Notification of startPlaying event failed for StartStopListener {}", listener.getClass(), t);
}
}
};
new Thread(fireStartStopEvent, "StartPlaying Event for " + listener.name()).start();
}
}
}
};
new Thread(r, "StartPlaying Event").start();
}
}
}
use of net.pms.external.ExternalListener in project UniversalMediaServer by UniversalMediaServer.
the class DbgPacker method poll.
private void poll() {
// call the client callbacks
for (ExternalListener listener : ExternalFactory.getExternalListeners()) {
if (listener instanceof DebugPacker) {
LOGGER.debug("Found client {}", listener.name());
Object obj = ((DebugPacker) listener).dbgpack_cb();
if (obj instanceof String) {
add(((String) obj).split(","));
} else if (obj instanceof String[]) {
add((String[]) obj);
}
}
}
PmsConfiguration configuration = PMS.getConfiguration();
// check dbgpack property in UMS.conf
LOGGER.debug("Checking dbgpack property in UMS.conf");
String f = (String) configuration.getCustomProperty("dbgpack");
if (f != null) {
add(f.split(","));
}
// add confs of connected renderers
for (RendererConfiguration r : RendererConfiguration.getConnectedRenderersConfigurations()) {
add(r.getFile());
if (((DeviceConfiguration) r).isCustomized()) {
add(((DeviceConfiguration) r).getParentFile());
}
}
// add core items with the default logfile last (LinkedHashMap preserves insertion order)
String profileDirectory = configuration.getProfileDirectory();
// add virtual folders file if it exists
String vfolders = configuration.getVirtualFoldersFile(null);
if (StringUtils.isNotEmpty(vfolders)) {
add(new File(profileDirectory, vfolders));
}
add(new File(profileDirectory, "WEB.conf"));
add(new File(configuration.getProfilePath()));
if (defaultLogFile != null && !defaultLogFile.isEmpty()) {
add(new File(defaultLogFile + ".prev"));
add(new File(defaultLogFile));
}
}
use of net.pms.external.ExternalListener in project UniversalMediaServer by UniversalMediaServer.
the class Playlist method discoverChildren.
@Override
public void discoverChildren() {
if (list.size() > 0) {
final Playlist self = this;
// Save
if (!isMode(AUTOSAVE)) {
addChild(new VirtualVideoAction(Messages.getString("LooksFrame.9"), true) {
@Override
public boolean enable() {
self.save();
return true;
}
});
}
// Clear
addChild(new VirtualVideoAction(Messages.getString("TracesTab.3"), true) {
@Override
public boolean enable() {
self.clear();
return true;
}
});
}
for (DLNAResource r : list) {
// addchild might clear the masterparent
// so fetch it first and readd
ExternalListener master = r.getMasterParent();
addChild(r);
r.setMasterParent(master);
if (r.isResume()) {
// add this non resume after
DLNAResource clone = r.clone();
clone.setResume(null);
addChild(clone);
clone.setMasterParent(master);
}
}
}
use of net.pms.external.ExternalListener in project UniversalMediaServer by UniversalMediaServer.
the class RootFolder method getAdditionalFoldersAtRoot.
/**
* Returns as many folders as plugins providing root folders are loaded
* into memory (need to implement AdditionalFolder(s)AtRoot)
*/
private List<DLNAResource> getAdditionalFoldersAtRoot() {
List<DLNAResource> res = new ArrayList<>();
String[] legalPlugs = null;
String tmp = configuration.getPlugins(tags);
if (StringUtils.isNotBlank(tmp)) {
legalPlugs = tmp.split(",");
}
for (ExternalListener listener : ExternalFactory.getExternalListeners()) {
if (illegalPlugin(legalPlugs, listener.name())) {
LOGGER.debug("plugin " + listener.name() + " is not legal for render");
continue;
}
if (listener instanceof AdditionalFolderAtRoot) {
AdditionalFolderAtRoot afar = (AdditionalFolderAtRoot) listener;
try {
DLNAResource resource = afar.getChild();
LOGGER.debug("add ext list " + listener);
if (resource == null) {
continue;
}
resource.setMasterParent(listener);
for (DLNAResource r : resource.getChildren()) {
r.setMasterParent(listener);
}
res.add(resource);
} catch (Throwable t) {
LOGGER.error(String.format("Failed to append AdditionalFolderAtRoot with name=%s, class=%s", afar.name(), afar.getClass()), t);
}
} else if (listener instanceof AdditionalFoldersAtRoot) {
Iterator<DLNAResource> folders = ((AdditionalFoldersAtRoot) listener).getChildren();
while (folders.hasNext()) {
DLNAResource resource = folders.next();
resource.setMasterParent(listener);
for (DLNAResource r : resource.getChildren()) {
r.setMasterParent(listener);
}
try {
res.add(resource);
} catch (Throwable t) {
LOGGER.error(String.format("Failed to append AdditionalFolderAtRoots with class=%s for DLNAResource=%s", listener.getClass(), resource.getClass()), t);
}
}
}
}
return res;
}
Aggregations