org.apache.tika.parser.video.FLVParser Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.tika.parser.video;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.mime.MediaType;
import org.apache.tika.parser.AbstractParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.sax.XHTMLContentHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
*
* Parser for metadata contained in Flash Videos (.flv). Resources:
* http://osflash.org/flv and for AMF:
* http://download.macromedia.com/pub/labs/amf/amf0_spec_121207.pdf
*
* This parser is capable of extracting the general metadata from header as well
* as embedded metadata.
*
* Known keys for metadata (from file header):
*
* - hasVideo: true|false
*
- hasSound: true|false
*
*
* In addition to the above values also metadata that is inserted in to the
* actual stream will be picked. Usually there are keys like:
* hasKeyframes, lastkeyframetimestamp, audiocodecid, keyframes, filepositions,
* hasMetadata, audiosamplerate, videodatarate metadatadate, videocodecid,
* metadatacreator, audiosize, hasVideo, height, audiosamplesize, framerate,
* hasCuePoints width, cuePoints, lasttimestamp, canSeekToEnd, datasize,
* duration, videosize, filesize, audiodatarate, hasAudio, stereo audiodelay
*/
public class FLVParser extends AbstractParser {
/** Serial version UID */
private static final long serialVersionUID = -8718013155719197679L;
private static int TYPE_METADATA = 0x12;
private static byte MASK_AUDIO = 1;
private static byte MASK_VIDEO = 4;
private static final Set SUPPORTED_TYPES =
Collections.singleton(MediaType.video("x-flv"));
public Set getSupportedTypes(ParseContext context) {
return SUPPORTED_TYPES;
}
private long readUInt32(DataInputStream input) throws IOException {
return input.readInt() & 0xFFFFFFFFL;
}
private int readUInt24(DataInputStream input) throws IOException {
int uint = input.read()<<16;
uint += input.read()<<8;
uint += input.read();
return uint;
}
private Object readAMFData(DataInputStream input, int type)
throws IOException {
if (type == -1) {
type = input.readUnsignedByte();
}
switch (type) {
case 0:
return input.readDouble();
case 1:
return input.readUnsignedByte() == 1;
case 2:
return readAMFString(input);
case 3:
return readAMFObject(input);
case 8:
return readAMFEcmaArray(input);
case 10:
return readAMFStrictArray(input);
case 11:
final Date date = new Date((long) input.readDouble());
input.readShort(); // time zone
return date;
case 13:
return "UNDEFINED";
default:
return null;
}
}
private Object readAMFStrictArray(DataInputStream input) throws IOException {
long count = readUInt32(input);
ArrayList