use of net.pms.formats.Format in project UniversalMediaServer by UniversalMediaServer.
the class MapFile method discoverChildren.
@Override
public void discoverChildren(String str) {
if (discoverable == null) {
discoverable = new ArrayList<>();
} else {
return;
}
int sm = configuration.getSortMethod(getPath());
List<File> files = getFileList();
// Build a map of all files and their corresponding formats
HashSet<File> images = new HashSet<>();
HashSet<File> audioVideo = new HashSet<>();
Iterator<File> iterator = files.iterator();
while (iterator.hasNext()) {
File file = iterator.next();
if (file.isFile()) {
if (isPotentialThumbnail(file.getName())) {
if (isFolderThumbnail(file, false)) {
potentialCover = file;
iterator.remove();
} else {
images.add(file);
}
} else {
Format format = FormatFactory.getAssociatedFormat(file.getAbsolutePath());
if (format != null && (format.isAudio() || format.isVideo())) {
audioVideo.add(file);
}
}
}
}
// Remove cover/thumbnails from file list
if (images.size() > 0 && audioVideo.size() > 0) {
HashSet<File> potentialMatches = new HashSet<File>(THUMBNAIL_EXTENSIONS.size() * 2);
for (File audioVideoFile : audioVideo) {
potentialMatches = getPotentialFileThumbnails(audioVideoFile, false);
iterator = images.iterator();
while (iterator.hasNext()) {
File imageFile = iterator.next();
if (potentialMatches.contains(imageFile)) {
iterator.remove();
files.remove(imageFile);
}
}
}
}
// ATZ handling
if (files.size() > configuration.getATZLimit() && StringUtils.isEmpty(forcedName)) {
/*
* Too many files to display at once, add A-Z folders
* instead and let the filters begin
*
* Note: If we done this at the level directly above we don't do it again
* since all files start with the same letter then
*/
TreeMap<String, ArrayList<File>> map = new TreeMap<>();
for (File f : files) {
if ((!f.isFile() && !f.isDirectory()) || f.isHidden()) {
// skip these
continue;
}
if (f.isDirectory() && configuration.isHideEmptyFolders() && !FileUtil.isFolderRelevant(f, configuration)) {
LOGGER.debug("Ignoring empty/non-relevant directory: " + f.getName());
// we can re-scan the folders in this list to see if they contain something relevant
if (emptyFoldersToRescan == null) {
emptyFoldersToRescan = new ArrayList<>();
}
if (!emptyFoldersToRescan.contains(f)) {
emptyFoldersToRescan.add(f);
}
continue;
}
String filenameToSort = FileUtil.renameForSorting(f.getName());
char c = filenameToSort.toUpperCase().charAt(0);
if (!(c >= 'A' && c <= 'Z')) {
// "other char"
c = '#';
}
ArrayList<File> l = map.get(String.valueOf(c));
if (l == null) {
// new letter
l = new ArrayList<>();
}
l.add(f);
map.put(String.valueOf(c), l);
}
for (Entry<String, ArrayList<File>> entry : map.entrySet()) {
// loop over all letters, this avoids adding
// empty letters
UMSUtils.sort(entry.getValue(), sm);
MapFile mf = new MapFile(getConf(), entry.getValue());
mf.forcedName = entry.getKey();
addChild(mf);
}
return;
}
UMSUtils.sort(files, (sm == UMSUtils.SORT_RANDOM ? UMSUtils.SORT_LOC_NAT : sm));
for (File f : files) {
if (f.isDirectory()) {
// manageFile(f);
discoverable.add(f);
}
}
// For random sorting, we only randomize file entries
if (sm == UMSUtils.SORT_RANDOM) {
UMSUtils.sort(files, sm);
}
for (File f : files) {
if (f.isFile()) {
// manageFile(f);
discoverable.add(f);
}
}
}
use of net.pms.formats.Format in project UniversalMediaServer by UniversalMediaServer.
the class FormatFactoryTest method testFormatFactoryEdgeCases.
/**
* Test edge cases for {@link FormatFactory#getAssociatedExtension(String)}.
*/
@Test
public final void testFormatFactoryEdgeCases() {
// Null string
Format result = FormatFactory.getAssociatedFormat(null);
assertNull("Null string matches no format", result);
// Empty string
result = FormatFactory.getAssociatedFormat("");
assertNull("Empty string matches no extension", result);
// Unsupported extension
result = FormatFactory.getAssociatedFormat("test.bogus");
assertNull("Unsupported extension: \"test.bogus\" matches no format", result);
// Confirm the protocol (e.g. WEB) is checked before the extension
testSingleFormat("http://example.com/test.mp3", "WEB", Format.UNKNOWN);
testSingleFormat("http://example.com/test.asf?format=.wmv", "WEB", Format.UNKNOWN);
// confirm that the WEB format is assigned for arbitrary protocols
testSingleFormat("svn+ssh://example.com/example.test", "WEB", Format.UNKNOWN);
testSingleFormat("bogus://example.com/test.test", "WEB", Format.UNKNOWN);
testSingleFormat("fake://example.com/test.test", "WEB", Format.UNKNOWN);
testSingleFormat("pms://example", "WEB", Format.UNKNOWN);
}
use of net.pms.formats.Format 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);
}
use of net.pms.formats.Format in project UniversalMediaServer by UniversalMediaServer.
the class PlaylistFolder method resolveOnce.
@Override
protected void resolveOnce() {
ArrayList<Entry> entries = new ArrayList<>();
boolean m3u = false;
boolean pls = false;
try (BufferedReader br = getBufferedReader()) {
String line;
while (!m3u && !pls && (line = br.readLine()) != null) {
line = line.trim();
if (line.startsWith("#EXTM3U")) {
m3u = true;
LOGGER.debug("Reading m3u playlist: " + getName());
} else if (line.length() > 0 && line.equals("[playlist]")) {
pls = true;
LOGGER.debug("Reading PLS playlist: " + getName());
}
}
String fileName;
String title = null;
while ((line = br.readLine()) != null) {
line = line.trim();
if (pls) {
if (line.length() > 0 && !line.startsWith("#")) {
int eq = line.indexOf('=');
if (eq != -1) {
String value = line.substring(eq + 1);
String var = line.substring(0, eq).toLowerCase();
fileName = null;
title = null;
int index = 0;
if (var.startsWith("file")) {
index = Integer.valueOf(var.substring(4));
fileName = value;
} else if (var.startsWith("title")) {
index = Integer.valueOf(var.substring(5));
title = value;
}
if (index > 0) {
while (entries.size() < index) {
entries.add(null);
}
Entry entry = entries.get(index - 1);
if (entry == null) {
entry = new Entry();
entries.set(index - 1, entry);
}
if (fileName != null) {
entry.fileName = fileName;
}
if (title != null) {
entry.title = title;
}
}
}
}
} else if (m3u) {
if (line.startsWith("#EXTINF:")) {
line = line.substring(8).trim();
if (line.matches("^-?\\d+,.+")) {
title = line.substring(line.indexOf(',') + 1).trim();
} else {
title = line;
}
} else if (!line.startsWith("#") && !line.matches("^\\s*$")) {
// Non-comment and non-empty line contains the filename
fileName = line;
Entry entry = new Entry();
entry.fileName = fileName;
entry.title = title;
entries.add(entry);
title = null;
}
}
}
} catch (NumberFormatException | IOException e) {
LOGGER.error(null, e);
}
for (Entry entry : entries) {
if (entry == null) {
continue;
}
if (entry.title == null) {
entry.title = new File(entry.fileName).getName();
}
LOGGER.debug("Adding " + (pls ? "PLS " : (m3u ? "M3U " : "")) + "entry: " + entry);
String ext = "." + FileUtil.getUrlExtension(entry.fileName);
Format f = FormatFactory.getAssociatedFormat(ext);
int type = f == null ? defaultContent : f.getType();
if (!isweb && !FileUtil.isUrl(entry.fileName)) {
File en = new File(FilenameUtils.concat(getPlaylistfile().getParent(), entry.fileName));
if (en.exists()) {
addChild(type == Format.PLAYLIST ? new PlaylistFolder(en) : new RealFile(en, entry.title));
valid = true;
}
} else {
String u = FileUtil.urlJoin(uri, entry.fileName);
if (type == Format.PLAYLIST && !entry.fileName.endsWith(ext)) {
// If the filename continues past the "extension" (i.e. has a query string) it's
// likely not a nested playlist but a media item, for instance Twitch TV media urls:
// 'http://video10.iad02.hls.twitch.tv/.../index-live.m3u8?token=id=235...'
type = defaultContent;
}
DLNAResource d = type == Format.VIDEO ? new WebVideoStream(entry.title, u, null) : type == Format.AUDIO ? new WebAudioStream(entry.title, u, null) : type == Format.IMAGE ? new FeedItem(entry.title, u, null, null, Format.IMAGE) : type == Format.PLAYLIST ? getPlaylist(entry.title, u, 0) : null;
if (d != null) {
addChild(d);
valid = true;
}
}
}
if (!isweb) {
PMS.get().storeFileInCache(getPlaylistfile(), Format.PLAYLIST);
}
if (configuration.getSortMethod(getPlaylistfile()) == UMSUtils.SORT_RANDOM) {
Collections.shuffle(getChildren());
}
for (DLNAResource r : getChildren()) {
r.syncResolve();
}
}
use of net.pms.formats.Format in project UniversalMediaServer by UniversalMediaServer.
the class FormatRecognitionTest method testPlaystationVideoMkvCompatibility.
/**
* Test the compatibility of the Playstation 3 with the MPG format.
*/
@Test
public void testPlaystationVideoMkvCompatibility() {
// This test is only useful if the MediaInfo library is available
assumeTrue(mediaInfoParserIsValid);
RendererConfiguration conf = RendererConfiguration.getRendererConfigurationByName("Playstation 3");
assertNotNull("Renderer named \"Playstation 3\" found.", conf);
// Construct MKV information
DLNAMediaInfo info = new DLNAMediaInfo();
info.setContainer("mkv");
DLNAMediaAudio audio = new DLNAMediaAudio();
audio.setCodecA("ac3");
audio.getAudioProperties().setNumberOfChannels(5);
List<DLNAMediaAudio> audioCodes = new ArrayList<>();
audioCodes.add(audio);
info.setAudioTracksList(audioCodes);
info.setCodecV("mp4");
Format format = new MPG();
format.match("test.mkv");
assertEquals("PS3 is incompatible with MKV", false, conf.isCompatible(info, format, configuration));
}
Aggregations