Search in sources :

Example 1 with SampleDescriptionBox

use of com.coremedia.iso.boxes.SampleDescriptionBox in project tika by apache.

the class MP4Parser method parse.

public void parse(InputStream stream, ContentHandler handler, Metadata metadata, ParseContext context) throws IOException, SAXException, TikaException {
    // The MP4Parser library accepts either a File, or a byte array
    // As MP4 video files are typically large, always use a file to
    //  avoid OOMs that may occur with in-memory buffering
    TemporaryResources tmp = new TemporaryResources();
    TikaInputStream tstream = TikaInputStream.get(stream, tmp);
    try (DataSource dataSource = new DirectFileReadDataSource(tstream.getFile())) {
        try (IsoFile isoFile = new IsoFile(dataSource)) {
            tmp.addResource(isoFile);
            // Grab the file type box
            FileTypeBox fileType = getOrNull(isoFile, FileTypeBox.class);
            if (fileType != null) {
                // Identify the type
                MediaType type = MediaType.application("mp4");
                for (Map.Entry<MediaType, List<String>> e : typesMap.entrySet()) {
                    if (e.getValue().contains(fileType.getMajorBrand())) {
                        type = e.getKey();
                        break;
                    }
                }
                metadata.set(Metadata.CONTENT_TYPE, type.toString());
                if (type.getType().equals("audio")) {
                    metadata.set(XMPDM.AUDIO_COMPRESSOR, fileType.getMajorBrand().trim());
                }
            } else {
                // Some older QuickTime files lack the FileType
                metadata.set(Metadata.CONTENT_TYPE, "video/quicktime");
            }
            // Get the main MOOV box
            MovieBox moov = getOrNull(isoFile, MovieBox.class);
            if (moov == null) {
                // Bail out
                return;
            }
            XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
            xhtml.startDocument();
            // Pull out some information from the header box
            MovieHeaderBox mHeader = getOrNull(moov, MovieHeaderBox.class);
            if (mHeader != null) {
                // Get the creation and modification dates
                metadata.set(Metadata.CREATION_DATE, mHeader.getCreationTime());
                metadata.set(TikaCoreProperties.MODIFIED, mHeader.getModificationTime());
                // Get the duration
                double durationSeconds = ((double) mHeader.getDuration()) / mHeader.getTimescale();
                metadata.set(XMPDM.DURATION, DURATION_FORMAT.format(durationSeconds));
                // The timescale is normally the sampling rate
                metadata.set(XMPDM.AUDIO_SAMPLE_RATE, (int) mHeader.getTimescale());
            }
            // Get some more information from the track header
            // TODO Decide how to handle multiple tracks
            List<TrackBox> tb = moov.getBoxes(TrackBox.class);
            if (tb.size() > 0) {
                TrackBox track = tb.get(0);
                TrackHeaderBox header = track.getTrackHeaderBox();
                // Get the creation and modification dates
                metadata.set(TikaCoreProperties.CREATED, header.getCreationTime());
                metadata.set(TikaCoreProperties.MODIFIED, header.getModificationTime());
                // Get the video with and height
                metadata.set(Metadata.IMAGE_WIDTH, (int) header.getWidth());
                metadata.set(Metadata.IMAGE_LENGTH, (int) header.getHeight());
                // Get the sample information
                SampleTableBox samples = track.getSampleTableBox();
                SampleDescriptionBox sampleDesc = samples.getSampleDescriptionBox();
                if (sampleDesc != null) {
                    // Look for the first Audio Sample, if present
                    AudioSampleEntry sample = getOrNull(sampleDesc, AudioSampleEntry.class);
                    if (sample != null) {
                        XMPDM.ChannelTypePropertyConverter.convertAndSet(metadata, sample.getChannelCount());
                        //metadata.set(XMPDM.AUDIO_SAMPLE_TYPE, sample.getSampleSize());    // TODO Num -> Type mapping
                        metadata.set(XMPDM.AUDIO_SAMPLE_RATE, (int) sample.getSampleRate());
                    //metadata.set(XMPDM.AUDIO_, sample.getSamplesPerPacket());
                    //metadata.set(XMPDM.AUDIO_, sample.getBytesPerSample());
                    }
                }
            }
            // Get metadata from the User Data Box
            UserDataBox userData = getOrNull(moov, UserDataBox.class);
            if (userData != null) {
                MetaBox meta = getOrNull(userData, MetaBox.class);
                // Check for iTunes Metadata
                // See http://atomicparsley.sourceforge.net/mpeg-4files.html and
                //  http://code.google.com/p/mp4v2/wiki/iTunesMetadata for more on these
                AppleItemListBox apple = getOrNull(meta, AppleItemListBox.class);
                if (apple != null) {
                    // Title
                    AppleNameBox title = getOrNull(apple, AppleNameBox.class);
                    addMetadata(TikaCoreProperties.TITLE, metadata, title);
                    // Artist
                    AppleArtistBox artist = getOrNull(apple, AppleArtistBox.class);
                    addMetadata(TikaCoreProperties.CREATOR, metadata, artist);
                    addMetadata(XMPDM.ARTIST, metadata, artist);
                    // Album Artist
                    AppleArtist2Box artist2 = getOrNull(apple, AppleArtist2Box.class);
                    addMetadata(XMPDM.ALBUM_ARTIST, metadata, artist2);
                    // Album
                    AppleAlbumBox album = getOrNull(apple, AppleAlbumBox.class);
                    addMetadata(XMPDM.ALBUM, metadata, album);
                    // Composer
                    AppleTrackAuthorBox composer = getOrNull(apple, AppleTrackAuthorBox.class);
                    addMetadata(XMPDM.COMPOSER, metadata, composer);
                    // Genre
                    AppleGenreBox genre = getOrNull(apple, AppleGenreBox.class);
                    addMetadata(XMPDM.GENRE, metadata, genre);
                    // Year
                    AppleRecordingYear2Box year = getOrNull(apple, AppleRecordingYear2Box.class);
                    if (year != null) {
                        metadata.set(XMPDM.RELEASE_DATE, year.getValue());
                    }
                    // Track number
                    AppleTrackNumberBox trackNum = getOrNull(apple, AppleTrackNumberBox.class);
                    if (trackNum != null) {
                        metadata.set(XMPDM.TRACK_NUMBER, trackNum.getA());
                    //metadata.set(XMPDM.NUMBER_OF_TRACKS, trackNum.getB()); // TODO
                    }
                    // Disc number
                    AppleDiskNumberBox discNum = getOrNull(apple, AppleDiskNumberBox.class);
                    if (discNum != null) {
                        metadata.set(XMPDM.DISC_NUMBER, discNum.getA());
                    }
                    // Compilation
                    AppleCompilationBox compilation = getOrNull(apple, AppleCompilationBox.class);
                    if (compilation != null) {
                        metadata.set(XMPDM.COMPILATION, (int) compilation.getValue());
                    }
                    // Comment
                    AppleCommentBox comment = getOrNull(apple, AppleCommentBox.class);
                    addMetadata(XMPDM.LOG_COMMENT, metadata, comment);
                    // Encoder
                    AppleEncoderBox encoder = getOrNull(apple, AppleEncoderBox.class);
                    if (encoder != null) {
                        metadata.set(XMP.CREATOR_TOOL, encoder.getValue());
                    }
                    // As text
                    for (Box box : apple.getBoxes()) {
                        if (box instanceof Utf8AppleDataBox) {
                            xhtml.element("p", ((Utf8AppleDataBox) box).getValue());
                        }
                    }
                }
            // TODO Check for other kinds too
            }
            // All done
            xhtml.endDocument();
        }
    } finally {
        tmp.dispose();
    }
}
Also used : AudioSampleEntry(com.coremedia.iso.boxes.sampleentry.AudioSampleEntry) AppleAlbumBox(com.googlecode.mp4parser.boxes.apple.AppleAlbumBox) TikaInputStream(org.apache.tika.io.TikaInputStream) FileTypeBox(com.coremedia.iso.boxes.FileTypeBox) AppleTrackNumberBox(com.googlecode.mp4parser.boxes.apple.AppleTrackNumberBox) MetaBox(com.coremedia.iso.boxes.MetaBox) AppleCompilationBox(com.googlecode.mp4parser.boxes.apple.AppleCompilationBox) AppleArtist2Box(com.googlecode.mp4parser.boxes.apple.AppleArtist2Box) AppleRecordingYear2Box(com.googlecode.mp4parser.boxes.apple.AppleRecordingYear2Box) AppleGenreBox(com.googlecode.mp4parser.boxes.apple.AppleGenreBox) Utf8AppleDataBox(com.googlecode.mp4parser.boxes.apple.Utf8AppleDataBox) MediaType(org.apache.tika.mime.MediaType) List(java.util.List) SampleDescriptionBox(com.coremedia.iso.boxes.SampleDescriptionBox) TrackHeaderBox(com.coremedia.iso.boxes.TrackHeaderBox) IsoFile(com.coremedia.iso.IsoFile) AppleCommentBox(com.googlecode.mp4parser.boxes.apple.AppleCommentBox) UserDataBox(com.coremedia.iso.boxes.UserDataBox) MovieHeaderBox(com.coremedia.iso.boxes.MovieHeaderBox) TemporaryResources(org.apache.tika.io.TemporaryResources) AppleEncoderBox(com.googlecode.mp4parser.boxes.apple.AppleEncoderBox) AppleArtistBox(com.googlecode.mp4parser.boxes.apple.AppleArtistBox) AppleCompilationBox(com.googlecode.mp4parser.boxes.apple.AppleCompilationBox) UserDataBox(com.coremedia.iso.boxes.UserDataBox) MovieHeaderBox(com.coremedia.iso.boxes.MovieHeaderBox) AppleArtist2Box(com.googlecode.mp4parser.boxes.apple.AppleArtist2Box) AppleArtistBox(com.googlecode.mp4parser.boxes.apple.AppleArtistBox) AppleEncoderBox(com.googlecode.mp4parser.boxes.apple.AppleEncoderBox) AppleTrackNumberBox(com.googlecode.mp4parser.boxes.apple.AppleTrackNumberBox) AppleNameBox(com.googlecode.mp4parser.boxes.apple.AppleNameBox) SampleTableBox(com.coremedia.iso.boxes.SampleTableBox) TrackBox(com.coremedia.iso.boxes.TrackBox) AppleDiskNumberBox(com.googlecode.mp4parser.boxes.apple.AppleDiskNumberBox) AppleRecordingYear2Box(com.googlecode.mp4parser.boxes.apple.AppleRecordingYear2Box) AppleGenreBox(com.googlecode.mp4parser.boxes.apple.AppleGenreBox) MetaBox(com.coremedia.iso.boxes.MetaBox) MovieBox(com.coremedia.iso.boxes.MovieBox) Utf8AppleDataBox(com.googlecode.mp4parser.boxes.apple.Utf8AppleDataBox) AppleCommentBox(com.googlecode.mp4parser.boxes.apple.AppleCommentBox) Box(com.coremedia.iso.boxes.Box) SampleDescriptionBox(com.coremedia.iso.boxes.SampleDescriptionBox) FileTypeBox(com.coremedia.iso.boxes.FileTypeBox) AppleAlbumBox(com.googlecode.mp4parser.boxes.apple.AppleAlbumBox) TrackHeaderBox(com.coremedia.iso.boxes.TrackHeaderBox) AppleItemListBox(com.coremedia.iso.boxes.apple.AppleItemListBox) AppleTrackAuthorBox(com.googlecode.mp4parser.boxes.apple.AppleTrackAuthorBox) AppleDiskNumberBox(com.googlecode.mp4parser.boxes.apple.AppleDiskNumberBox) XHTMLContentHandler(org.apache.tika.sax.XHTMLContentHandler) DataSource(com.googlecode.mp4parser.DataSource) SampleTableBox(com.coremedia.iso.boxes.SampleTableBox) TrackBox(com.coremedia.iso.boxes.TrackBox) AppleTrackAuthorBox(com.googlecode.mp4parser.boxes.apple.AppleTrackAuthorBox) MovieBox(com.coremedia.iso.boxes.MovieBox) AppleItemListBox(com.coremedia.iso.boxes.apple.AppleItemListBox) Map(java.util.Map) HashMap(java.util.HashMap) AppleNameBox(com.googlecode.mp4parser.boxes.apple.AppleNameBox)

Aggregations

IsoFile (com.coremedia.iso.IsoFile)1 Box (com.coremedia.iso.boxes.Box)1 FileTypeBox (com.coremedia.iso.boxes.FileTypeBox)1 MetaBox (com.coremedia.iso.boxes.MetaBox)1 MovieBox (com.coremedia.iso.boxes.MovieBox)1 MovieHeaderBox (com.coremedia.iso.boxes.MovieHeaderBox)1 SampleDescriptionBox (com.coremedia.iso.boxes.SampleDescriptionBox)1 SampleTableBox (com.coremedia.iso.boxes.SampleTableBox)1 TrackBox (com.coremedia.iso.boxes.TrackBox)1 TrackHeaderBox (com.coremedia.iso.boxes.TrackHeaderBox)1 UserDataBox (com.coremedia.iso.boxes.UserDataBox)1 AppleItemListBox (com.coremedia.iso.boxes.apple.AppleItemListBox)1 AudioSampleEntry (com.coremedia.iso.boxes.sampleentry.AudioSampleEntry)1 DataSource (com.googlecode.mp4parser.DataSource)1 AppleAlbumBox (com.googlecode.mp4parser.boxes.apple.AppleAlbumBox)1 AppleArtist2Box (com.googlecode.mp4parser.boxes.apple.AppleArtist2Box)1 AppleArtistBox (com.googlecode.mp4parser.boxes.apple.AppleArtistBox)1 AppleCommentBox (com.googlecode.mp4parser.boxes.apple.AppleCommentBox)1 AppleCompilationBox (com.googlecode.mp4parser.boxes.apple.AppleCompilationBox)1 AppleDiskNumberBox (com.googlecode.mp4parser.boxes.apple.AppleDiskNumberBox)1