/** * Create a copy of the provided original resource and optionally set the copy's audio track, * subtitle track and player. * * @param original The original {@link DLNAResource} to create a copy of. * @param audio The audio track to use. * @param subtitle The subtitle track to use. * @param player The player to use. * @return The copy. */ private DLNAResource createResourceWithAudioSubtitlePlayer( DLNAResource original, DLNAMediaAudio audio, DLNAMediaSubtitle subtitle, Player player) { // FIXME clone is broken. should be e.g. original.newInstance() DLNAResource copy = original.clone(); copy.setMedia(original.getMedia()); copy.setNoName(true); copy.setMediaAudio(audio); copy.setMediaSubtitle(subtitle); copy.setPlayer(player); return copy; }
@Override public void handle(HttpExchange t) throws IOException { if (RemoteUtil.deny(t)) { throw new IOException("Access denied"); } RootFolder root = parent.getRoot(RemoteUtil.userName(t), t); if (root == null) { throw new IOException("Unknown root"); } Headers h = t.getRequestHeaders(); for (String h1 : h.keySet()) { LOGGER.debug("key " + h1 + "=" + h.get(h1)); } String id = RemoteUtil.getId(path, t); id = RemoteUtil.strip(id); RendererConfiguration r = render; if (render == null) { r = root.getDefaultRenderer(); } DLNAResource dlna = root.getDLNAResource(id, r); if (dlna == null) { // another error LOGGER.debug("media unkonwn"); throw new IOException("Bad id"); } if (!dlna.isCodeValid(dlna)) { LOGGER.debug("coded object with invalid code"); throw new IOException("Bad code"); } DLNAMediaSubtitle sid = null; long len = dlna.length(); Range range = RemoteUtil.parseRange(t.getRequestHeaders(), len); String mime = root.getDefaultRenderer().getMimeType(dlna.mimeType()); // DLNAResource dlna = res.get(0); WebRender render = (WebRender) r; DLNAMediaInfo m = dlna.getMedia(); if (m == null) { m = new DLNAMediaInfo(); dlna.setMedia(m); } if (mime.equals(FormatConfiguration.MIMETYPE_AUTO) && m.getMimeType() != null) { mime = m.getMimeType(); } int code = 200; dlna.setDefaultRenderer(r); if (dlna.getFormat().isVideo()) { if (flash) { mime = "video/flash"; } else if (!RemoteUtil.directmime(mime) || RemoteUtil.transMp4(mime, m)) { mime = render != null ? render.getVideoMimeType() : RemoteUtil.transMime(); if (FileUtil.isUrl(dlna.getSystemName())) { dlna.setPlayer(new FFmpegWebVideo()); } else { dlna.setPlayer(new FFMpegVideo()); } // code = 206; } if (PMS.getConfiguration().getWebSubs() && dlna.getMediaSubtitle() != null && dlna.getMediaSubtitle().isExternal()) { // fetched on the side sid = dlna.getMediaSubtitle(); dlna.setMediaSubtitle(null); } } if (!RemoteUtil.directmime(mime) && dlna.getFormat().isAudio()) { dlna.setPlayer(new FFmpegAudio()); code = 206; } m.setMimeType(mime); LOGGER.debug("dumping media " + mime + " " + dlna); InputStream in = dlna.getInputStream(range, root.getDefaultRenderer()); Headers hdr = t.getResponseHeaders(); hdr.add("Content-Type", mime); hdr.add("Accept-Ranges", "bytes"); if (range != null) { long end = range.asByteRange().getEnd(); long start = range.asByteRange().getStart(); String rStr = start + "-" + end + "/*"; hdr.add("Content-Range", "bytes " + rStr); if (start != 0) { code = 206; } } hdr.add("Server", PMS.get().getServerName()); hdr.add("Connection", "keep-alive"); t.sendResponseHeaders(code, 0); OutputStream os = t.getResponseBody(); render.start(dlna); if (sid != null) { dlna.setMediaSubtitle(sid); } RemoteUtil.dump(in, os, render); }