use of net.pms.util.UnknownFormatException in project UniversalMediaServer by UniversalMediaServer.
the class DLNAMediaInfo method parse.
/**
* Parse media without using MediaInfo.
*/
public void parse(InputFile inputFile, Format ext, int type, boolean thumbOnly, boolean resume, RendererConfiguration renderer) {
int i = 0;
while (isParsing()) {
if (i == 5) {
mediaparsed = true;
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
i++;
}
if (isMediaparsed() && !thumbOnly) {
// file could be already parsed by MediaInfo and we need only thumbnail
return;
}
if (inputFile != null) {
File file = inputFile.getFile();
if (file != null) {
size = file.length();
} else {
size = inputFile.getSize();
}
ProcessWrapperImpl pw = null;
boolean ffmpeg_parsing = true;
if (type == Format.AUDIO || ext instanceof AudioAsVideo) {
ffmpeg_parsing = false;
DLNAMediaAudio audio = new DLNAMediaAudio();
if (file != null) {
try {
AudioFile af;
if ("mp2".equals(FileUtil.getExtension(file).toLowerCase(Locale.ROOT))) {
af = AudioFileIO.readAs(file, "mp3");
} else {
af = AudioFileIO.read(file);
}
AudioHeader ah = af.getAudioHeader();
if (ah != null && !thumbOnly) {
int length = ah.getTrackLength();
int rate = ah.getSampleRateAsNumber();
if (ah.getEncodingType() != null && ah.getEncodingType().toLowerCase().contains("flac 24")) {
audio.setBitsperSample(24);
}
audio.setSampleFrequency("" + rate);
durationSec = (double) length;
bitrate = (int) ah.getBitRateAsNumber();
// set default value of channels to 2
audio.getAudioProperties().setNumberOfChannels(2);
String channels = ah.getChannels().toLowerCase(Locale.ROOT);
if (StringUtils.isNotBlank(channels)) {
if (channels.equals("1") || channels.contains("mono")) {
// parse value "1" or "Mono"
audio.getAudioProperties().setNumberOfChannels(1);
} else if (!(channels.equals("2") || channels.equals("0") || channels.contains("stereo"))) {
// No need to parse stereo as it's set as default
try {
audio.getAudioProperties().setNumberOfChannels(Integer.parseInt(channels));
} catch (IllegalArgumentException e) {
LOGGER.debug("Could not parse number of audio channels from \"{}\"", channels);
}
}
}
if (StringUtils.isNotBlank(ah.getEncodingType())) {
audio.setCodecA(ah.getEncodingType());
}
if (audio.getCodecA() != null && audio.getCodecA().contains("(windows media")) {
audio.setCodecA(audio.getCodecA().substring(0, audio.getCodecA().indexOf("(windows media")).trim());
}
}
Tag t = af.getTag();
if (t != null) {
if (t.getArtworkList().size() > 0) {
thumb = DLNAThumbnail.toThumbnail(t.getArtworkList().get(0).getBinaryData(), 640, 480, ScaleType.MAX, ImageFormat.SOURCE, false);
} else if (!configuration.getAudioThumbnailMethod().equals(CoverSupplier.NONE)) {
thumb = DLNAThumbnail.toThumbnail(CoverUtil.get().getThumbnail(t), 640, 480, ScaleType.MAX, ImageFormat.SOURCE, false);
}
if (thumb != null) {
thumbready = true;
}
if (!thumbOnly) {
audio.setAlbum(t.getFirst(FieldKey.ALBUM));
audio.setArtist(t.getFirst(FieldKey.ARTIST));
audio.setSongname(t.getFirst(FieldKey.TITLE));
String y = t.getFirst(FieldKey.YEAR);
try {
if (y.length() > 4) {
y = y.substring(0, 4);
}
audio.setYear(Integer.parseInt(((y != null && y.length() > 0) ? y : "0")));
y = t.getFirst(FieldKey.TRACK);
audio.setTrack(Integer.parseInt(((y != null && y.length() > 0) ? y : "1")));
audio.setGenre(t.getFirst(FieldKey.GENRE));
} catch (NumberFormatException | KeyNotFoundException e) {
LOGGER.debug("Error parsing unimportant metadata: " + e.getMessage());
}
}
}
} catch (CannotReadException e) {
if (e.getMessage().startsWith(ErrorMessage.NO_READER_FOR_THIS_FORMAT.getMsg().substring(0, ErrorMessage.NO_READER_FOR_THIS_FORMAT.getMsg().indexOf("{")))) {
LOGGER.debug("No audio tag support for audio file \"{}\"", file.getName());
} else {
LOGGER.error("Error reading audio tag for \"{}\": {}", file.getName(), e.getMessage());
LOGGER.trace("", e);
}
} catch (IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException | NumberFormatException | KeyNotFoundException e) {
LOGGER.debug("Error parsing audio file tag for \"{}\": {}", file.getName(), e.getMessage());
LOGGER.trace("", e);
ffmpeg_parsing = false;
}
// Set container for formats that the normal parsing fails to do from Format
if (StringUtils.isBlank(container) && ext != null) {
if (ext.getIdentifier() == Identifier.ADPCM) {
audio.setCodecA(FormatConfiguration.ADPCM);
} else if (ext.getIdentifier() == Identifier.DSD) {
audio.setCodecA(FormatConfiguration.DSD);
}
}
if (StringUtils.isNotBlank(audio.getSongname())) {
if (renderer != null && renderer.isPrependTrackNumbers() && audio.getTrack() > 0) {
audio.setSongname(audio.getTrack() + ": " + audio.getSongname());
}
} else {
audio.setSongname(file.getName());
}
if (!ffmpeg_parsing) {
audioTracks.add(audio);
}
}
if (StringUtils.isBlank(container)) {
container = audio.getCodecA();
}
}
if (type == Format.IMAGE && file != null) {
if (!thumbOnly) {
try {
ffmpeg_parsing = false;
ImagesUtil.parseImage(file, this);
imageCount++;
} catch (IOException e) {
LOGGER.debug("Error parsing image \"{}\", switching to FFmpeg: {}", file.getAbsolutePath(), e.getMessage());
LOGGER.trace("", e);
ffmpeg_parsing = true;
}
}
if (thumbOnly && configuration.isThumbnailGenerationEnabled() && configuration.getImageThumbnailsEnabled()) {
LOGGER.trace("Creating thumbnail for \"{}\"", file.getName());
// Create the thumbnail image
try {
if (imageInfo instanceof ExifInfo && ((ExifInfo) imageInfo).hasExifThumbnail() && !imageInfo.isImageIOSupported()) {
/*
* XXX Extraction of thumbnails was removed in version
* 2.10.0 of metadata-extractor because of a bug in
* related code. This section is deactivated while
* waiting for this to be made available again.
*
* Images supported by ImageIO or DCRaw aren't affected,
* so this only applied to very few images anyway.
* It could extract thumbnails for some "raw" images
* if DCRaw was disabled.
*
// ImageIO can't read the file, try to get the embedded Exif thumbnail if it's there.
Metadata metadata;
try {
metadata = ImagesUtil.getMetadata(new FileInputStream(file), imageInfo.getFormat());
} catch (ImageProcessingException e) {
metadata = null;
LOGGER.debug("Unexpected error reading metadata for \"{}\": {}", file.getName(), e.getMessage());
LOGGER.trace("", e);
}
thumb = DLNAThumbnail.toThumbnail(
ImagesUtil.getThumbnailFromMetadata(file, metadata),
320,
320,
ScaleType.MAX,
ImageFormat.SOURCE,
false
);
if (thumb == null && LOGGER.isTraceEnabled()) {
LOGGER.trace("Exif thumbnail extraction failed, no thumbnail will be generated for \"{}\"", file.getName());
}*/
} else {
// This will fail with UnknownFormatException for any image formats not supported by ImageIO
thumb = DLNAThumbnail.toThumbnail(Files.newInputStream(file.toPath()), 320, 320, ScaleType.MAX, ImageFormat.SOURCE, false);
}
thumbready = true;
} catch (EOFException e) {
LOGGER.debug("Error generating thumbnail for \"{}\": Unexpected end of file, probably corrupt file or read error.", file.getName());
} catch (UnknownFormatException e) {
LOGGER.debug("Could not generate thumbnail for \"{}\" because the format is unknown: {}", file.getName(), e.getMessage());
} catch (IOException e) {
LOGGER.debug("Error generating thumbnail for \"{}\": {}", file.getName(), e.getMessage());
LOGGER.trace("", e);
}
}
}
if (ffmpeg_parsing) {
if (!thumbOnly || (type == Format.VIDEO && !configuration.isUseMplayerForVideoThumbs())) {
pw = getFFmpegThumbnail(inputFile, resume, renderer);
}
boolean dvrms = false;
String input = "-";
if (file != null) {
input = ProcessUtil.getShortFileNameIfWideChars(file.getAbsolutePath());
dvrms = file.getAbsolutePath().toLowerCase().endsWith("dvr-ms");
}
synchronized (ffmpeg_failureLock) {
if (pw != null && !ffmpeg_failure && !thumbOnly) {
parseFFmpegInfo(pw.getResults(), input);
}
}
if (!thumbOnly && container != null && file != null && container.equals("mpegts") && isH264() && getDurationInSeconds() == 0) {
// Parse the duration
try {
int length = MpegUtil.getDurationFromMpeg(file);
if (length > 0) {
durationSec = (double) length;
}
} catch (IOException e) {
LOGGER.trace("Error retrieving length: " + e.getMessage());
}
}
if (configuration.isUseMplayerForVideoThumbs() && type == Format.VIDEO && !dvrms) {
try {
getMplayerThumbnail(inputFile, resume, renderer);
String frameName = "" + inputFile.hashCode();
frameName = configuration.getTempFolder() + "/mplayer_thumbs/" + frameName + "00000001/00000001.jpg";
frameName = frameName.replace(',', '_');
File jpg = new File(frameName);
if (jpg.exists()) {
try (InputStream is = new FileInputStream(jpg)) {
int sz = is.available();
if (sz > 0) {
byte[] bytes = new byte[sz];
is.read(bytes);
thumb = DLNAThumbnail.toThumbnail(bytes, 640, 480, ScaleType.MAX, ImageFormat.SOURCE, false);
thumbready = true;
}
}
if (!jpg.delete()) {
jpg.deleteOnExit();
}
// Try and retry
if (!jpg.getParentFile().delete() && !jpg.getParentFile().delete()) {
LOGGER.debug("Failed to delete \"" + jpg.getParentFile().getAbsolutePath() + "\"");
}
}
} catch (IOException e) {
LOGGER.debug("Caught exception", e);
}
}
if (type == Format.VIDEO && pw != null && thumb == null) {
byte[] bytes = pw.getOutputByteArray().toByteArray();
if (bytes != null && bytes.length > 0) {
try {
thumb = DLNAThumbnail.toThumbnail(bytes);
} catch (IOException e) {
LOGGER.debug("Error while decoding thumbnail: " + e.getMessage());
LOGGER.trace("", e);
}
thumbready = true;
}
}
}
postParse(type, inputFile);
mediaparsed = true;
}
}
use of net.pms.util.UnknownFormatException in project UniversalMediaServer by UniversalMediaServer.
the class ImagesUtil method parseImage.
/**
* Parses an image file and stores the results in the given
* {@link DLNAMediaInfo}. Parsing is performed using both
* <a href=https://github.com/drewnoakes/metadata-extractor>Metadata Extractor</a>
* and {@link ImageIO}. While Metadata Extractor offers more detailed
* information, {@link ImageIO} offers information that is convenient for
* image transformation with {@link ImageIO}. Parsing will be performed if
* just one of the two methods produces results, but some details will be
* missing if either one failed.
* <p><b>
* This method consumes and closes {@code inputStream}.
* </b>
* @param file the {@link File} to parse.
* @param media the {@link DLNAMediaInfo} instance to store the parsing
* results to.
* @throws IOException if an IO error occurs or no information can be parsed.
*/
public static void parseImage(File file, DLNAMediaInfo media) throws IOException {
// 1 MB
final int MAX_BUFFER = 1048576;
if (file == null) {
throw new IllegalArgumentException("parseImage: file cannot be null");
}
if (media == null) {
throw new IllegalArgumentException("parseImage: media cannot be null");
}
boolean trace = LOGGER.isTraceEnabled();
if (trace) {
LOGGER.trace("Parsing image file \"{}\"", file.getAbsolutePath());
}
long size = file.length();
ResettableInputStream inputStream = new ResettableInputStream(Files.newInputStream(file.toPath()), MAX_BUFFER);
try {
Metadata metadata = null;
FileType fileType = null;
try {
fileType = FileTypeDetector.detectFileType(inputStream);
metadata = getMetadata(inputStream, fileType);
} catch (IOException e) {
metadata = new Metadata();
LOGGER.debug("Error reading \"{}\": {}", file.getAbsolutePath(), e.getMessage());
LOGGER.trace("", e);
} catch (ImageProcessingException e) {
metadata = new Metadata();
LOGGER.debug("Error parsing {} metadata for \"{}\": {}", fileType.toString().toUpperCase(Locale.ROOT), file.getAbsolutePath(), e.getMessage());
LOGGER.trace("", e);
}
ImageFormat format = ImageFormat.toImageFormat(fileType);
if (format == null || format == ImageFormat.TIFF) {
ImageFormat tmpformat = ImageFormat.toImageFormat(metadata);
if (tmpformat != null) {
format = tmpformat;
}
}
if (inputStream.isFullResetAvailable()) {
inputStream.fullReset();
} else {
// If we can't reset it, close it and create a new
inputStream.close();
inputStream = new ResettableInputStream(Files.newInputStream(file.toPath()), MAX_BUFFER);
}
ImageInfo imageInfo = null;
try {
imageInfo = ImageIOTools.readImageInfo(inputStream, size, metadata, false);
} catch (UnknownFormatException | IIOException | ParseException e) {
if (format == null) {
throw new UnknownFormatException("Unable to recognize image format for \"" + file.getAbsolutePath() + "\" - parsing failed", e);
}
LOGGER.debug("Unable to parse \"{}\" with ImageIO because the format is unsupported, image information will be limited", file.getAbsolutePath());
LOGGER.trace("ImageIO parse failure reason: {}", e.getMessage());
// Gather basic information from the data we have
if (metadata != null) {
try {
imageInfo = ImageInfo.create(metadata, format, size, true, true);
} catch (ParseException pe) {
LOGGER.debug("Unable to parse metadata for \"{}\": {}", file.getAbsolutePath(), pe.getMessage());
LOGGER.trace("", pe);
}
}
}
if (imageInfo == null && format == null) {
throw new ParseException("Parsing of \"" + file.getAbsolutePath() + "\" failed");
}
if (format == null) {
format = imageInfo.getFormat();
} else if (imageInfo != null && imageInfo.getFormat() != null && format != imageInfo.getFormat()) {
if (imageInfo.getFormat() == ImageFormat.TIFF && format.isRaw()) {
if (format == ImageFormat.ARW && !isARW(metadata)) {
// XXX Remove this if https://github.com/drewnoakes/metadata-extractor/issues/217 is fixed
// Metadata extractor misidentifies some Photoshop created TIFFs for ARW, correct it
format = ImageFormat.toImageFormat(metadata);
if (format == null) {
format = ImageFormat.TIFF;
}
LOGGER.trace("Correcting misidentified image format ARW to {} for \"{}\"", format, file.getAbsolutePath());
} else {
/*
* ImageIO recognizes many RAW formats as TIFF because
* of their close relationship let's treat them as what
* they really are.
*/
imageInfo = ImageInfo.create(imageInfo.getWidth(), imageInfo.getHeight(), format, size, imageInfo.getBitDepth(), imageInfo.getNumComponents(), imageInfo.getColorSpace(), imageInfo.getColorSpaceType(), metadata, false, imageInfo.isImageIOSupported());
LOGGER.trace("Correcting misidentified image format TIFF to {} for \"{}\"", format.toString(), file.getAbsolutePath());
}
} else {
LOGGER.debug("Image parsing for \"{}\" was inconclusive, metadata parsing " + "detected {} format while ImageIO detected {}. Choosing {}.", file.getAbsolutePath(), format, imageInfo.getFormat(), imageInfo.getFormat());
format = imageInfo.getFormat();
}
}
media.setImageInfo(imageInfo);
if (format != null) {
media.setCodecV(format.toFormatConfiguration());
media.setContainer(format.toFormatConfiguration());
}
if (trace) {
LOGGER.trace("Parsing of image \"{}\" completed", file.getName());
}
} finally {
inputStream.close();
}
}
use of net.pms.util.UnknownFormatException in project UniversalMediaServer by UniversalMediaServer.
the class ImageIOTools method detectFileFormat.
/**
* Tries to detect the input image file format using {@link ImageIO} and
* returns the result.
* <p>
* This method does not close {@code inputStream}.
*
* @param inputStream the image whose format to detect.
* @return The {@link ImageFormat} for the input.
* @throws UnknownFormatException if the format could not be determined.
* @throws IOException if an IO error occurred.
*/
public static ImageFormat detectFileFormat(InputStream inputStream) throws IOException {
if (inputStream == null) {
throw new IllegalArgumentException("input == null!");
}
try (ImageInputStream stream = createImageInputStream(inputStream)) {
Iterator<?> iter = ImageIO.getImageReaders(stream);
if (!iter.hasNext()) {
throw new UnknownFormatException("Unable to find a suitable image reader");
}
ImageReader reader = (ImageReader) iter.next();
ImageFormat format = ImageFormat.toImageFormat(reader.getFormatName());
if (format == null) {
throw new UnknownFormatException("Unable to determine image format");
}
return format;
} catch (RuntimeException e) {
throw new ImageIORuntimeException("An error occurred while trying to detect image format: " + e.getMessage(), e);
}
}
Aggregations