Search in sources :

Example 6 with UnknownFormatException

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;
    }
}
Also used : AudioHeader(org.jaudiotagger.audio.AudioHeader) InvalidAudioFrameException(org.jaudiotagger.audio.exceptions.InvalidAudioFrameException) ReadOnlyFileException(org.jaudiotagger.audio.exceptions.ReadOnlyFileException) ProcessWrapperImpl(net.pms.io.ProcessWrapperImpl) CannotReadException(org.jaudiotagger.audio.exceptions.CannotReadException) AudioFile(org.jaudiotagger.audio.AudioFile) TagException(org.jaudiotagger.tag.TagException) AudioAsVideo(net.pms.formats.AudioAsVideo) ExifInfo(net.pms.image.ExifInfo) UnknownFormatException(net.pms.util.UnknownFormatException) Tag(org.jaudiotagger.tag.Tag) AudioFile(org.jaudiotagger.audio.AudioFile) KeyNotFoundException(org.jaudiotagger.tag.KeyNotFoundException)

Example 7 with UnknownFormatException

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();
    }
}
Also used : ImageProcessingException(com.drew.imaging.ImageProcessingException) Metadata(com.drew.metadata.Metadata) IIOException(javax.imageio.IIOException) IIOException(javax.imageio.IIOException) FileType(com.drew.imaging.FileType) UnknownFormatException(net.pms.util.UnknownFormatException) ParseException(net.pms.util.ParseException) ResettableInputStream(net.pms.util.ResettableInputStream)

Example 8 with UnknownFormatException

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);
    }
}
Also used : ImageIORuntimeException(net.pms.image.ImageIORuntimeException) ImageIORuntimeException(net.pms.image.ImageIORuntimeException) ImageInputStream(javax.imageio.stream.ImageInputStream) UnknownFormatException(net.pms.util.UnknownFormatException) ImageReader(javax.imageio.ImageReader)

Aggregations

UnknownFormatException (net.pms.util.UnknownFormatException)8 IIOException (javax.imageio.IIOException)3 ImageReader (javax.imageio.ImageReader)3 ImageIORuntimeException (net.pms.image.ImageIORuntimeException)3 ImageProcessingException (com.drew.imaging.ImageProcessingException)2 Metadata (com.drew.metadata.Metadata)2 BufferedImage (java.awt.image.BufferedImage)2 IOException (java.io.IOException)2 ImageInputStream (javax.imageio.stream.ImageInputStream)2 ParseException (net.pms.util.ParseException)2 FileType (com.drew.imaging.FileType)1 Rectangle (java.awt.Rectangle)1 ColorConvertOp (java.awt.image.ColorConvertOp)1 ColorModel (java.awt.image.ColorModel)1 EOFException (java.io.EOFException)1 File (java.io.File)1 Matcher (java.util.regex.Matcher)1 ImageReadParam (javax.imageio.ImageReadParam)1 ImageTypeSpecifier (javax.imageio.ImageTypeSpecifier)1 Canvas (net.coobird.thumbnailator.filters.Canvas)1