001/*
002 * Copyright (c) 2006-2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Vladimir Pasquier <vpasquier@nuxeo.com>
011 *
012 */
013package org.nuxeo.ecm.platform.audio.extension;
014
015import java.io.File;
016import java.io.IOException;
017import java.io.InputStream;
018import java.util.Iterator;
019
020import org.apache.commons.logging.Log;
021import org.apache.commons.logging.LogFactory;
022import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
023import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
024import org.jaudiotagger.audio.mp3.MP3File;
025import org.jaudiotagger.tag.TagException;
026import org.jaudiotagger.tag.id3.AbstractID3v2Frame;
027import org.jaudiotagger.tag.id3.framebody.FrameBodyAPIC;
028import org.nuxeo.common.utils.FileUtils;
029import org.nuxeo.ecm.core.api.Blob;
030import org.nuxeo.ecm.core.api.Blobs;
031import org.nuxeo.ecm.core.api.CoreSession;
032import org.nuxeo.ecm.core.api.DocumentModel;
033import org.nuxeo.ecm.core.api.NuxeoException;
034import org.nuxeo.ecm.core.api.PropertyException;
035import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
036import org.nuxeo.ecm.core.api.thumbnail.ThumbnailFactory;
037import org.nuxeo.ecm.platform.types.adapter.TypeInfo;
038
039/**
040 * Audio thumbnail factory
041 *
042 * @since 5.7
043 */
044public class ThumbnailAudioFactory implements ThumbnailFactory {
045
046    private static final Log log = LogFactory.getLog(ThumbnailAudioFactory.class);
047
048    @Override
049    public Blob getThumbnail(DocumentModel doc, CoreSession session) {
050        if (!doc.hasFacet("Audio")) {
051            throw new NuxeoException("Document is not audio type");
052        }
053        Blob thumbnailBlob = null;
054        try {
055            if (doc.hasFacet(AudioThumbnailConstants.THUMBNAIL_FACET)) {
056                thumbnailBlob = (Blob) doc.getPropertyValue(AudioThumbnailConstants.THUMBNAIL_PROPERTY_NAME);
057            }
058        } catch (PropertyException e) {
059            log.warn("Could not fetch the thumbnail blob", e);
060        }
061        if (thumbnailBlob == null) {
062            TypeInfo docType = doc.getAdapter(TypeInfo.class);
063            try {
064                return Blobs.createBlob(FileUtils.getResourceFileFromContext("nuxeo.war" + File.separator
065                        + docType.getBigIcon()));
066            } catch (IOException e) {
067                throw new NuxeoException(e);
068            }
069        }
070        return thumbnailBlob;
071    }
072
073    @Override
074    @SuppressWarnings("rawtypes")
075    public Blob computeThumbnail(DocumentModel doc, CoreSession session) {
076        Blob thumbnailBlob = null;
077        BlobHolder bh = doc.getAdapter(BlobHolder.class);
078        Blob fileBlob;
079        try {
080            // Get the cover art of the audio file if ID3v2 exist
081            try (InputStream in = bh.getBlob().getStream()) {
082                fileBlob = Blobs.createBlob(in);
083            }
084            MP3File file = new MP3File(fileBlob.getFile());
085            if (file.hasID3v2Tag()) {
086                Iterator it = file.getID3v2Tag().getFrameOfType("APIC");
087                if (it != null && it.hasNext()) {
088                    AbstractID3v2Frame frame = (AbstractID3v2Frame) it.next();
089                    FrameBodyAPIC framePic = (FrameBodyAPIC) frame.getBody();
090                    thumbnailBlob = Blobs.createBlob(framePic.getImageData());
091                }
092            }
093        } catch (IOException | TagException | InvalidAudioFrameException | ReadOnlyFileException e) {
094            log.warn("Unable to get the audio file cover art", e);
095        }
096        return thumbnailBlob;
097    }
098}