001/*
002 * (C) Copyright 2006-2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Vladimir Pasquier <vpasquier@nuxeo.com>
018 *
019 */
020package org.nuxeo.ecm.platform.audio.extension;
021
022import java.io.File;
023import java.io.IOException;
024import java.io.InputStream;
025import java.util.Iterator;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
030import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
031import org.jaudiotagger.audio.mp3.MP3File;
032import org.jaudiotagger.tag.TagException;
033import org.jaudiotagger.tag.id3.AbstractID3v2Frame;
034import org.jaudiotagger.tag.id3.framebody.FrameBodyAPIC;
035import org.nuxeo.common.utils.FileUtils;
036import org.nuxeo.ecm.core.api.Blob;
037import org.nuxeo.ecm.core.api.Blobs;
038import org.nuxeo.ecm.core.api.CoreSession;
039import org.nuxeo.ecm.core.api.DocumentModel;
040import org.nuxeo.ecm.core.api.NuxeoException;
041import org.nuxeo.ecm.core.api.PropertyException;
042import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
043import org.nuxeo.ecm.core.api.thumbnail.ThumbnailFactory;
044import org.nuxeo.ecm.platform.types.adapter.TypeInfo;
045
046/**
047 * Audio thumbnail factory
048 *
049 * @since 5.7
050 */
051public class ThumbnailAudioFactory implements ThumbnailFactory {
052
053    private static final Log log = LogFactory.getLog(ThumbnailAudioFactory.class);
054
055    @Override
056    public Blob getThumbnail(DocumentModel doc, CoreSession session) {
057        if (!doc.hasFacet("Audio")) {
058            throw new NuxeoException("Document is not audio type");
059        }
060        Blob thumbnailBlob = null;
061        try {
062            if (doc.hasFacet(AudioThumbnailConstants.THUMBNAIL_FACET)) {
063                thumbnailBlob = (Blob) doc.getPropertyValue(AudioThumbnailConstants.THUMBNAIL_PROPERTY_NAME);
064            }
065        } catch (PropertyException e) {
066            log.warn("Could not fetch the thumbnail blob", e);
067        }
068        if (thumbnailBlob == null) {
069            TypeInfo docType = doc.getAdapter(TypeInfo.class);
070            try {
071                return Blobs.createBlob(FileUtils.getResourceFileFromContext("nuxeo.war" + File.separator
072                        + docType.getBigIcon()));
073            } catch (IOException e) {
074                throw new NuxeoException(e);
075            }
076        }
077        return thumbnailBlob;
078    }
079
080    @Override
081    @SuppressWarnings("rawtypes")
082    public Blob computeThumbnail(DocumentModel doc, CoreSession session) {
083        Blob thumbnailBlob = null;
084        BlobHolder bh = doc.getAdapter(BlobHolder.class);
085        Blob fileBlob;
086        try {
087            // Get the cover art of the audio file if ID3v2 exist
088            try (InputStream in = bh.getBlob().getStream()) {
089                fileBlob = Blobs.createBlob(in);
090            }
091            MP3File file = new MP3File(fileBlob.getFile());
092            if (file.hasID3v2Tag()) {
093                Iterator it = file.getID3v2Tag().getFrameOfType("APIC");
094                if (it != null && it.hasNext()) {
095                    AbstractID3v2Frame frame = (AbstractID3v2Frame) it.next();
096                    FrameBodyAPIC framePic = (FrameBodyAPIC) frame.getBody();
097                    thumbnailBlob = Blobs.createBlob(framePic.getImageData());
098                }
099            }
100        } catch (IOException | TagException | InvalidAudioFrameException | ReadOnlyFileException e) {
101            log.warn("Unable to get the audio file cover art", e);
102        }
103        return thumbnailBlob;
104    }
105}