Search in sources :

Example 1 with ExternalListener

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);
    }
}
Also used : VirtualFolder(net.pms.dlna.virtual.VirtualFolder) TranscodeVirtualFolder(net.pms.dlna.virtual.TranscodeVirtualFolder) AdditionalResourceFolderListener(net.pms.external.AdditionalResourceFolderListener) ExternalListener(net.pms.external.ExternalListener)

Example 2 with ExternalListener

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();
        }
    }
}
Also used : StartStopListener(net.pms.external.StartStopListener) UnknownHostException(java.net.UnknownHostException) RendererConfiguration(net.pms.configuration.RendererConfiguration) ExternalListener(net.pms.external.ExternalListener) InetAddress(java.net.InetAddress)

Example 3 with ExternalListener

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));
    }
}
Also used : PmsConfiguration(net.pms.configuration.PmsConfiguration) RendererConfiguration(net.pms.configuration.RendererConfiguration) DebugPacker(net.pms.external.DebugPacker) ExternalListener(net.pms.external.ExternalListener) DeviceConfiguration(net.pms.configuration.DeviceConfiguration) File(java.io.File)

Example 4 with ExternalListener

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);
        }
    }
}
Also used : VirtualVideoAction(net.pms.dlna.virtual.VirtualVideoAction) ExternalListener(net.pms.external.ExternalListener)

Example 5 with ExternalListener

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;
}
Also used : AdditionalFoldersAtRoot(net.pms.external.AdditionalFoldersAtRoot) ExternalListener(net.pms.external.ExternalListener) AdditionalFolderAtRoot(net.pms.external.AdditionalFolderAtRoot)

Aggregations

ExternalListener (net.pms.external.ExternalListener)8 RendererConfiguration (net.pms.configuration.RendererConfiguration)3 InetAddress (java.net.InetAddress)2 UnknownHostException (java.net.UnknownHostException)2 StartStopListener (net.pms.external.StartStopListener)2 LoggerContext (ch.qos.logback.classic.LoggerContext)1 FormLayout (com.jgoodies.forms.layout.FormLayout)1 File (java.io.File)1 BindException (java.net.BindException)1 IllegalCharsetNameException (java.nio.charset.IllegalCharsetNameException)1 UnsupportedCharsetException (java.nio.charset.UnsupportedCharsetException)1 AccessControlException (java.security.AccessControlException)1 SQLException (java.sql.SQLException)1 ImageReaderSpi (javax.imageio.spi.ImageReaderSpi)1 ImageWriterSpi (javax.imageio.spi.ImageWriterSpi)1 DeviceConfiguration (net.pms.configuration.DeviceConfiguration)1 PmsConfiguration (net.pms.configuration.PmsConfiguration)1 MediaLibrary (net.pms.dlna.virtual.MediaLibrary)1 TranscodeVirtualFolder (net.pms.dlna.virtual.TranscodeVirtualFolder)1 VirtualFolder (net.pms.dlna.virtual.VirtualFolder)1