Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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.opencastproject.metadata.mpeg7;
import org.opencastproject.util.XmlSafeParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
/**
* Parser implementation for mpeg-7 files. Note that this implementation does by far not cover the full mpeg-7 standard
* but only deals with those parts relevant to Opencast, mainly temporal decompositions.
*/
public class Mpeg7Parser extends DefaultHandler {
/** the logging facility */
private static final Logger logger = LoggerFactory.getLogger(Mpeg7Parser.class.getName());
/** The current parser state */
enum ParserState {
Document, MultimediaContent, Segment, VideoText
};
/**
* Number formatter, used to deal with relevance values in a locale
* independent way
*/
private static DecimalFormatSymbols standardSymbols = new DecimalFormatSymbols(Locale.US);
/** The manifest */
private Mpeg7CatalogImpl mpeg7Doc = null;
/** The element content */
private StringBuffer tagContent = new StringBuffer();
/** The multimedia content */
private MultimediaContentType multimediaContent = null;
/** Current multimedia content type (audio, video, audiovisual) */
private MultimediaContentType.Type contentType = null;
/** The multimedia content identifier */
private String contentId = null;
/** The media locator */
private MediaLocator mediaLocator = null;
/** The content media time point (will usually refer to 0:00:00) */
private MediaTimePoint contentTimePoint = null;
/** The time point (relative to the content time point) */
private MediaTimePoint mediaTimePoint = null;
/** The duration */
private MediaDuration mediaDuration = null;
/** The media time and duration */
private MediaTime mediaTime = null;
/** The temporal decomposition container */
private TemporalDecomposition> temporalDecomposition = null;
/** The temporal segment */
private Segment segment = null;
/** The spatio temporal decomposition container */
private SpatioTemporalDecomposition spatioTemporalDecomposition = null;
/** The text annoation */
private TextAnnotation textAnnotation = null;
/** The videotext element */
private VideoText videoText = null;
/** The videotext text */
private Textual textual = null;
/** The current parser state */
private Mpeg7Parser.ParserState state = ParserState.Document;
/** Flag to check if this is not just an arbitrary xml document */
private boolean isMpeg7 = false;
private DecimalFormat floatFormat = new DecimalFormat();
/**
* Creates a new parser for mpeg-7 files.
*/
public Mpeg7Parser() {
floatFormat.setDecimalFormatSymbols(standardSymbols);
}
public Mpeg7Parser(Mpeg7CatalogImpl catalog) {
this.mpeg7Doc = catalog;
floatFormat.setDecimalFormatSymbols(standardSymbols);
}
/**
* Parses the mpeg-7 catalog file and returns its object representation.
*
* @param is
* the input stream containing the catalog
* @return the catalog representation
* @throws ParserConfigurationException
* if setting up the parser failed
* @throws SAXException
* if an error occured while parsing the document
* @throws IOException
* if the file cannot be accessed in a proper way
* @throws IllegalArgumentException
* if the provided file does not contain mpeg-7 data
*/
public Mpeg7CatalogImpl parse(InputStream is) throws ParserConfigurationException, SAXException, IOException {
if (mpeg7Doc == null)
mpeg7Doc = new Mpeg7CatalogImpl();
SAXParserFactory factory = XmlSafeParser.newSAXParserFactory();
// REPLAY does not use a DTD here
factory.setValidating(false);
factory.setNamespaceAware(true);
SAXParser parser = factory.newSAXParser();
parser.parse(is, this);
// Did we parse an mpeg-7 document?
if (!isMpeg7)
throw new IllegalArgumentException("Content of input stream is not mpeg-7");
return mpeg7Doc;
}
/**
* Read type attribute from track or catalog element.
*
* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String,
* org.xml.sax.Attributes)
*/
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
tagContent = new StringBuffer();
// Make sure this is an mpeg-7 catalog
// TODO: Improve this test, add namespace awareness
if (!isMpeg7 && "Mpeg7".equals(name))
isMpeg7 = true;
// Handle parser state
if ("MultimediaContent".equals(localName)) {
state = ParserState.MultimediaContent;
}
// Content type
if ("Audio".equals(localName) || "Video".equals(localName) || "AudioVisual".equals(localName)) {
contentType = MultimediaContentType.Type.valueOf(localName);
contentId = attributes.getValue("id");
if (MultimediaContentType.Type.Audio.equals(contentType))
multimediaContent = mpeg7Doc.addAudioContent(contentId, mediaTime, mediaLocator);
else if (MultimediaContentType.Type.Video.equals(contentType))
multimediaContent = mpeg7Doc.addVideoContent(contentId, mediaTime, mediaLocator);
else if (MultimediaContentType.Type.AudioVisual.equals(contentType))
multimediaContent = mpeg7Doc.addAudioVisualContent(contentId, mediaTime, mediaLocator);
}
// Temporal decomposition
if ("TemporalDecomposition".equals(localName)) {
String hasGap = attributes.getValue("gap");
String isOverlapping = attributes.getValue("overlap");
String criteria = attributes.getValue("criteria");
if (!"temporal".equals(criteria))
throw new IllegalStateException("Decompositions other than temporal are not supported");
temporalDecomposition = multimediaContent.getTemporalDecomposition();
temporalDecomposition.setGap("true".equals(hasGap));
temporalDecomposition.setOverlapping("overlap".equals(isOverlapping));
}
// Segment
if ("AudioSegment".equals(localName) || "VideoSegment".equals(localName) || "AudioVisualSegment".equals(localName)) {
String segmentId = attributes.getValue("id");
segment = temporalDecomposition.createSegment(segmentId);
state = ParserState.Segment;
}
// TextAnnotation
if ("TextAnnotation".equals(localName)) {
String language = attributes.getValue("xml:lang");
float confidence = -1.0f;
float relevance = -1.0f;
try {
confidence = floatFormat.parse(attributes.getValue("confidence")).floatValue();
} catch (Exception e) {
confidence = -1.0f;
}
try {
relevance = floatFormat.parse(attributes.getValue("relevance")).floatValue();
} catch (Exception e) {
relevance = -1.0f;
}
textAnnotation = segment.createTextAnnotation(confidence, relevance, language);
}
// Spatiotemporal decomposition
if ("SpatioTemporalDecomposition".equals(localName)) {
String hasGap = attributes.getValue("gap");
String isOverlapping = attributes.getValue("overlap");
if (!(segment instanceof VideoSegment))
throw new IllegalStateException("Can't have a spatio temporal decomposition outside of a video segment");
boolean gap = "true".equalsIgnoreCase(attributes.getValue("gap"));
boolean overlap = "true".equalsIgnoreCase(attributes.getValue("overlap"));
spatioTemporalDecomposition = ((VideoSegment) segment).createSpatioTemporalDecomposition(gap, overlap);
spatioTemporalDecomposition.setGap("true".equals(hasGap));
spatioTemporalDecomposition.setOverlapping("overlap".equals(isOverlapping));
}
// Video Text
if ("VideoText".equals(localName)) {
String id = attributes.getValue("id");
videoText = new VideoTextImpl(id);
state = ParserState.VideoText;
}
// Textual
if ("Text".equals(localName)) {
String language = attributes.getValue("xml:lang");
textual = new TextualImpl();
textual.setLanguage(language);
}
}
/**
* @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
super.endElement(uri, localName, name);
// Handle parser state
if ("MultimediaContent".equals(localName))
state = ParserState.Document;
else if ("AudioSegment".equals(localName) || "VideoSegment".equals(localName)
|| "AudioVisualSegment".equals(localName))
state = ParserState.MultimediaContent;
// Media locator uri
if ("MediaUri".equals(localName)) {
MediaLocatorImpl locator = new MediaLocatorImpl();
URI mediaUri = URI.create(getTagContent());
locator.setMediaURI(mediaUri);
if (ParserState.MultimediaContent.equals(state)) {
multimediaContent.setMediaLocator(locator);
}
}
// Media/Segment time
if ("MediaTime".equals(localName)) {
if (ParserState.MultimediaContent.equals(state)) {
mediaTime = new MediaTimeImpl(mediaTimePoint, mediaDuration);
multimediaContent.setMediaTime(mediaTime);
} else if (ParserState.Segment.equals(state)) {
mediaTime = new MediaTimeImpl(mediaTimePoint, mediaDuration);
segment.setMediaTime(mediaTime);
} else if (ParserState.VideoText.equals(state)) {
SpatioTemporalLocator spatioTemporalLocator = new SpatioTemporalLocatorImpl(mediaTime);
videoText.setSpatioTemporalLocator(spatioTemporalLocator);
}
}
// Media/Segment time point
if ("MediaTimePoint".equals(localName)) {
mediaTimePoint = MediaTimePointImpl.parseTimePoint(getTagContent());
if (ParserState.MultimediaContent.equals(state)) {
contentTimePoint = mediaTimePoint;
}
}
// Media/Segment time point
if ("MediaRelTimePoint".equals(localName)) {
MediaRelTimePointImpl tp = MediaRelTimePointImpl.parseTimePoint(getTagContent());
mediaTimePoint = tp;
if (ParserState.MultimediaContent.equals(state))
contentTimePoint = tp;
else if (ParserState.Segment.equals(state)) {
tp.setReferenceTimePoint(contentTimePoint);
}
}
// Media/Segment duration
if ("MediaDuration".equals(localName)) {
mediaDuration = MediaDurationImpl.parseDuration(getTagContent());
}
// Keyword
if ("Keyword".equals(localName)) {
KeywordAnnotation keyword = new KeywordAnnotationImpl(tagContent.toString());
textAnnotation.addKeywordAnnotation(keyword);
}
// Free text
if ("FreeTextAnnotation".equals(localName)) {
FreeTextAnnotation freeText = new FreeTextAnnotationImpl(tagContent.toString());
textAnnotation.addFreeTextAnnotation(freeText);
}
// Video Text
if ("VideoText".equals(localName)) {
spatioTemporalDecomposition.addVideoText(videoText);
}
// SpatioTemporalLocator
if ("SpatioTemporalLocator".equals(localName)) {
videoText.setSpatioTemporalLocator(new SpatioTemporalLocatorImpl(mediaTime));
}
// Videotext text
if ("Text".equals(localName)) {
textual.setText(tagContent.toString());
videoText.setText(textual);
}
// Videotext bouding box
if ("Box".equals(localName)) {
String[] coords = tagContent.toString().trim().split(" ");
if (coords.length != 4)
throw new IllegalStateException("Box coordinates '" + tagContent + "' is malformatted");
int[] coordsL = new int[4];
for (int i = 0; i < 4; i++)
try {
coordsL[i] = (int) floatFormat.parse(coords[i]).floatValue();
} catch (ParseException e) {
throw new SAXException(e);
}
videoText.setBoundary(new Rectangle(coordsL[0], coordsL[1], (coordsL[2] - coordsL[0]), coordsL[3] - coordsL[1]));
}
}
/**
* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
tagContent.append(ch, start, length);
}
/**
* Returns the element content.
*
* @return the element content
*/
private String getTagContent() {
String str = tagContent.toString().trim();
return str;
}
/**
* @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
*/
@Override
public void error(SAXParseException e) throws SAXException {
logger.warn("Error while parsing mpeg-7 catalog: " + e.getMessage());
super.error(e);
}
/**
* @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
*/
@Override
public void fatalError(SAXParseException e) throws SAXException {
logger.warn("Fatal error while parsing mpeg-7 catalog: " + e.getMessage());
super.fatalError(e);
}
/**
* @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
*/
@Override
public void warning(SAXParseException e) throws SAXException {
logger.warn("Warning while parsing mpeg-7 catalog: " + e.getMessage());
super.warning(e);
}
}