Search in sources :

Example 1 with WebRender

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

the class RemoteMediaHandler method handle.

@Override
public void handle(HttpExchange httpExchange) throws IOException {
    if (RemoteUtil.deny(httpExchange)) {
        throw new IOException("Access denied");
    }
    RootFolder root = parent.getRoot(RemoteUtil.userName(httpExchange), httpExchange);
    if (root == null) {
        throw new IOException("Unknown root");
    }
    Headers h = httpExchange.getRequestHeaders();
    for (String h1 : h.keySet()) {
        LOGGER.debug("key " + h1 + "=" + h.get(h1));
    }
    String id = RemoteUtil.getId(path, httpExchange);
    id = RemoteUtil.strip(id);
    RendererConfiguration defaultRenderer = renderer;
    if (renderer == null) {
        defaultRenderer = root.getDefaultRenderer();
    }
    DLNAResource resource = root.getDLNAResource(id, defaultRenderer);
    if (resource == null) {
        // another error
        LOGGER.debug("media unkonwn");
        throw new IOException("Bad id");
    }
    if (!resource.isCodeValid(resource)) {
        LOGGER.debug("coded object with invalid code");
        throw new IOException("Bad code");
    }
    DLNAMediaSubtitle sid = null;
    String mimeType = root.getDefaultRenderer().getMimeType(resource.mimeType(), resource.getMedia());
    // DLNAResource dlna = res.get(0);
    WebRender renderer = (WebRender) defaultRenderer;
    DLNAMediaInfo media = resource.getMedia();
    if (media == null) {
        media = new DLNAMediaInfo();
        resource.setMedia(media);
    }
    if (mimeType.equals(FormatConfiguration.MIMETYPE_AUTO) && media.getMimeType() != null) {
        mimeType = media.getMimeType();
    }
    int code = 200;
    resource.setDefaultRenderer(defaultRenderer);
    if (resource.getFormat().isVideo()) {
        if (flash) {
            mimeType = "video/flash";
        } else if (!RemoteUtil.directmime(mimeType) || RemoteUtil.transMp4(mimeType, media)) {
            mimeType = renderer != null ? renderer.getVideoMimeType() : RemoteUtil.transMime();
            if (FileUtil.isUrl(resource.getSystemName())) {
                resource.setPlayer(new FFmpegWebVideo());
            } else if (!(resource instanceof DVDISOTitle)) {
                resource.setPlayer(new FFMpegVideo());
            }
        // code = 206;
        }
        if (PMS.getConfiguration().getWebSubs() && resource.getMediaSubtitle() != null && resource.getMediaSubtitle().isExternal()) {
            // fetched on the side
            sid = resource.getMediaSubtitle();
            resource.setMediaSubtitle(null);
        }
    }
    if (!RemoteUtil.directmime(mimeType) && resource.getFormat().isAudio()) {
        resource.setPlayer(new FFmpegAudio());
        code = 206;
    }
    media.setMimeType(mimeType);
    Range.Byte range = RemoteUtil.parseRange(httpExchange.getRequestHeaders(), resource.length());
    LOGGER.debug("Sending {} with mime type {} to {}", resource, mimeType, renderer);
    InputStream in = resource.getInputStream(range, root.getDefaultRenderer());
    if (range.getEnd() == 0) {
        // For web resources actual length may be unknown until we open the stream
        range.setEnd(resource.length());
    }
    Headers headers = httpExchange.getResponseHeaders();
    headers.add("Content-Type", mimeType);
    headers.add("Accept-Ranges", "bytes");
    long end = range.getEnd();
    long start = range.getStart();
    String rStr = start + "-" + end + "/*";
    headers.add("Content-Range", "bytes " + rStr);
    if (start != 0) {
        code = 206;
    }
    headers.add("Server", PMS.get().getServerName());
    headers.add("Connection", "keep-alive");
    httpExchange.sendResponseHeaders(code, 0);
    OutputStream os = httpExchange.getResponseBody();
    if (renderer != null) {
        renderer.start(resource);
    }
    if (sid != null) {
        resource.setMediaSubtitle(sid);
    }
    RemoteUtil.dump(in, os, renderer);
}
Also used : WebRender(net.pms.configuration.WebRender) Headers(com.sun.net.httpserver.Headers) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) FFMpegVideo(net.pms.encoders.FFMpegVideo) IOException(java.io.IOException) FFmpegAudio(net.pms.encoders.FFmpegAudio) RendererConfiguration(net.pms.configuration.RendererConfiguration) FFmpegWebVideo(net.pms.encoders.FFmpegWebVideo)

Example 2 with WebRender

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

the class RemotePlayHandler method mkPage.

private String mkPage(String id, HttpExchange t) throws IOException {
    HashMap<String, Object> vars = new HashMap<>();
    vars.put("serverName", configuration.getServerDisplayName());
    LOGGER.debug("Make play page " + id);
    RootFolder root = parent.getRoot(RemoteUtil.userName(t), t);
    if (root == null) {
        LOGGER.debug("root not found");
        throw new IOException("Unknown root");
    }
    WebRender renderer = (WebRender) root.getDefaultRenderer();
    renderer.setBrowserInfo(RemoteUtil.getCookie("UMSINFO", t), t.getRequestHeaders().getFirst("User-agent"));
    // List<DLNAResource> res = root.getDLNAResources(id, false, 0, 0, renderer);
    DLNAResource r = root.getDLNAResource(id, renderer);
    if (r == null) {
        LOGGER.debug("Bad web play id: " + id);
        throw new IOException("Bad Id");
    }
    if (!r.isCodeValid(r)) {
        LOGGER.debug("coded object with invalid code");
        throw new IOException("Bad code");
    }
    if (r instanceof VirtualVideoAction) {
        // waste of resource to play dummy video
        if (((VirtualVideoAction) r).enable()) {
            renderer.notify(renderer.INFO, r.getName() + " enabled");
        } else {
            renderer.notify(renderer.INFO, r.getName() + " disabled");
        }
        return returnPage();
    }
    Format format = r.getFormat();
    boolean isImage = format.isImage();
    boolean isVideo = format.isVideo();
    boolean isAudio = format.isAudio();
    String query = t.getRequestURI().getQuery();
    boolean forceFlash = StringUtils.isNotEmpty(RemoteUtil.getQueryVars(query, "flash"));
    boolean forcehtml5 = StringUtils.isNotEmpty(RemoteUtil.getQueryVars(query, "html5"));
    boolean flowplayer = isVideo && (forceFlash || (!forcehtml5 && configuration.getWebFlash()));
    // hack here to ensure we got a root folder to use for recently played etc.
    root.getDefaultRenderer().setRootFolder(root);
    String id1 = URLEncoder.encode(id, "UTF-8");
    String name = StringEscapeUtils.escapeHtml(r.resumeName());
    String mime = root.getDefaultRenderer().getMimeType(r.mimeType(), r.getMedia());
    String mediaType = isVideo ? "video" : isAudio ? "audio" : isImage ? "image" : "";
    String auto = "autoplay";
    @SuppressWarnings("unused") String coverImage = "";
    if (isVideo) {
        if (mime.equals(FormatConfiguration.MIMETYPE_AUTO)) {
            if (r.getMedia() != null && r.getMedia().getMimeType() != null) {
                mime = r.getMedia().getMimeType();
            }
        }
        if (!flowplayer) {
            if (!RemoteUtil.directmime(mime) || RemoteUtil.transMp4(mime, r.getMedia()) || r.isResume()) {
                WebRender render = (WebRender) r.getDefaultRenderer();
                mime = render != null ? render.getVideoMimeType() : RemoteUtil.transMime();
            }
        }
    }
    vars.put("isVideo", isVideo);
    vars.put("name", name);
    vars.put("id1", id1);
    vars.put("autoContinue", configuration.getWebAutoCont(format));
    if (configuration.isDynamicPls()) {
        if (r.getParent() instanceof Playlist) {
            vars.put("plsOp", "del");
            vars.put("plsSign", "-");
            vars.put("plsAttr", RemoteUtil.getMsgString("Web.4", t));
        } else {
            vars.put("plsOp", "add");
            vars.put("plsSign", "+");
            vars.put("plsAttr", RemoteUtil.getMsgString("Web.5", t));
        }
    }
    addNextByType(r, vars);
    if (isImage) {
        // do this like this to simplify the code
        // skip all player crap since img tag works well
        int delay = configuration.getWebImgSlideDelay() * 1000;
        if (delay > 0 && configuration.getWebAutoCont(format)) {
            vars.put("delay", delay);
        }
    } else {
        vars.put("mediaType", mediaType);
        vars.put("auto", auto);
        vars.put("mime", mime);
        if (flowplayer) {
            if (RemoteUtil.directmime(mime) && !RemoteUtil.transMp4(mime, r.getMedia()) && !r.isResume() && !forceFlash) {
                vars.put("src", true);
            }
        } else {
            vars.put("width", renderer.getVideoWidth());
            vars.put("height", renderer.getVideoHeight());
        }
    }
    if (configuration.useWebControl()) {
        vars.put("push", true);
    }
    if (isVideo && configuration.getWebSubs()) {
        // only if subs are requested as <track> tags
        // otherwise we'll transcode them in
        boolean isFFmpegFontConfig = configuration.isFFmpegFontConfig();
        if (isFFmpegFontConfig) {
            // do not apply fontconfig to flowplayer subs
            configuration.setFFmpegFontConfig(false);
        }
        OutputParams p = new OutputParams(configuration);
        p.sid = r.getMediaSubtitle();
        Player.setAudioAndSubs(r.getName(), r.getMedia(), p);
        if (p.sid != null && p.sid.getType().isText()) {
            try {
                File subFile = SubtitleUtils.getSubtitles(r, r.getMedia(), p, configuration, SubtitleType.WEBVTT);
                LOGGER.debug("subFile " + subFile);
                if (subFile != null) {
                    vars.put("sub", parent.getResources().add(subFile));
                }
            } catch (Exception e) {
                LOGGER.debug("error when doing sub file " + e);
            }
        }
        // return back original fontconfig value
        configuration.setFFmpegFontConfig(isFFmpegFontConfig);
    }
    return parent.getResources().getTemplate(isImage ? "image.html" : flowplayer ? "flow.html" : "play.html").execute(vars);
}
Also used : WebRender(net.pms.configuration.WebRender) HashMap(java.util.HashMap) IOException(java.io.IOException) IOException(java.io.IOException) DLNAResource(net.pms.dlna.DLNAResource) Playlist(net.pms.dlna.Playlist) Format(net.pms.formats.Format) VirtualVideoAction(net.pms.dlna.virtual.VirtualVideoAction) RootFolder(net.pms.dlna.RootFolder) OutputParams(net.pms.io.OutputParams) File(java.io.File)

Example 3 with WebRender

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

the class RemoteUtil method matchRenderer.

public static WebRender matchRenderer(String user, HttpExchange t) {
    int browser = WebRender.getBrowser(t.getRequestHeaders().getFirst("User-agent"));
    String confName = WebRender.getBrowserName(browser);
    RendererConfiguration r = RendererConfiguration.find(confName, t.getRemoteAddress().getAddress());
    return ((r instanceof WebRender) && (StringUtils.isBlank(user) || user.equals(((WebRender) r).getUser()))) ? (WebRender) r : null;
}
Also used : WebRender(net.pms.configuration.WebRender) RendererConfiguration(net.pms.configuration.RendererConfiguration)

Example 4 with WebRender

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

the class RemoteWeb method getRoot.

public RootFolder getRoot(String user, boolean create, HttpExchange t) {
    String groupTag = getTag(user);
    String cookie = RemoteUtil.getCookie("UMS", t);
    RootFolder root;
    synchronized (roots) {
        root = roots.get(cookie);
        if (root == null) {
            // Double-check for cookie errors
            WebRender valid = RemoteUtil.matchRenderer(user, t);
            if (valid != null) {
                // A browser of the same type and user is already connected at
                // this ip but for some reason we didn't get a cookie match.
                RootFolder validRoot = valid.getRootFolder();
                // Do a reverse lookup to see if it's been registered
                for (Map.Entry<String, RootFolder> entry : roots.entrySet()) {
                    if (entry.getValue() == validRoot) {
                        // Found
                        root = validRoot;
                        cookie = entry.getKey();
                        LOGGER.debug("Allowing browser connection without cookie match: {}: {}", valid.getRendererName(), t.getRemoteAddress().getAddress());
                        break;
                    }
                }
            }
        }
        if (!create || (root != null)) {
            t.getResponseHeaders().add("Set-Cookie", "UMS=" + cookie + ";Path=/");
            return root;
        }
        ArrayList<String> tag = new ArrayList<>();
        tag.add(user);
        if (!groupTag.equals(user)) {
            tag.add(groupTag);
        }
        tag.add(t.getRemoteAddress().getHostString());
        tag.add("web");
        root = new RootFolder(tag);
        try {
            WebRender render = new WebRender(user);
            root.setDefaultRenderer(render);
            render.setRootFolder(root);
            render.associateIP(t.getRemoteAddress().getAddress());
            render.associatePort(t.getRemoteAddress().getPort());
            if (configuration.useWebSubLang()) {
                render.setSubLang(StringUtils.join(RemoteUtil.getLangs(t), ","));
            }
            // render.setUA(t.getRequestHeaders().getFirst("User-agent"));
            render.setBrowserInfo(RemoteUtil.getCookie("UMSINFO", t), t.getRequestHeaders().getFirst("User-agent"));
            PMS.get().setRendererFound(render);
        } catch (ConfigurationException e) {
            root.setDefaultRenderer(RendererConfiguration.getDefaultConf());
        }
        // root.setDefaultRenderer(RendererConfiguration.getRendererConfigurationByName("web"));
        root.discoverChildren();
        cookie = UUID.randomUUID().toString();
        t.getResponseHeaders().add("Set-Cookie", "UMS=" + cookie + ";Path=/");
        roots.put(cookie, root);
    }
    return root;
}
Also used : WebRender(net.pms.configuration.WebRender) ConfigurationException(org.apache.commons.configuration.ConfigurationException) ArrayList(java.util.ArrayList) RootFolder(net.pms.dlna.RootFolder) HashMap(java.util.HashMap) Map(java.util.Map)

Example 5 with WebRender

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

the class PlayerControlHandler method getRenderers.

public String getRenderers(InetAddress client) {
    Logical player = selectedPlayers.get(client);
    RendererConfiguration selected = player != null ? player.renderer : getDefaultRenderer();
    ArrayList<String> json = new ArrayList<>();
    for (RendererConfiguration r : RendererConfiguration.getConnectedControlPlayers()) {
        json.add(String.format("[\"%s\",%d,\"%s\"]", (r instanceof WebRender) ? r.uuid : r, r == selected ? 1 : 0, r.uuid));
    }
    return "\"renderers\":[" + StringUtils.join(json, ",") + "]";
}
Also used : WebRender(net.pms.configuration.WebRender) RendererConfiguration(net.pms.configuration.RendererConfiguration) Logical(net.pms.util.BasicPlayer.Logical)

Aggregations

WebRender (net.pms.configuration.WebRender)7 IOException (java.io.IOException)4 RootFolder (net.pms.dlna.RootFolder)4 RendererConfiguration (net.pms.configuration.RendererConfiguration)3 DLNAResource (net.pms.dlna.DLNAResource)3 Headers (com.sun.net.httpserver.Headers)2 InputStream (java.io.InputStream)2 OutputStream (java.io.OutputStream)2 HashMap (java.util.HashMap)2 Playlist (net.pms.dlna.Playlist)2 OutputParams (net.pms.io.OutputParams)2 BufferedOutputStream (java.io.BufferedOutputStream)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 File (java.io.File)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 Range (net.pms.dlna.Range)1 VirtualVideoAction (net.pms.dlna.virtual.VirtualVideoAction)1 FFMpegVideo (net.pms.encoders.FFMpegVideo)1 FFmpegAudio (net.pms.encoders.FFmpegAudio)1