use of org.opencastproject.metadata.mpeg7.Video in project opencast by opencast.
the class TextAnalysisWorkflowOperationHandler method loadSegmentCatalogs.
/**
* Extracts the catalogs from the media package that match the requirements of flavor and tags specified in the
* operation handler.
*
* @param mediaPackage
* the media package
* @param operation
* the workflow operation
* @return a map of catalog elements and their mpeg-7 representations
* @throws IOException
* if there is a problem reading the mpeg7
*/
protected Map<Catalog, Mpeg7Catalog> loadSegmentCatalogs(MediaPackage mediaPackage, WorkflowOperationInstance operation) throws IOException {
HashMap<Catalog, Mpeg7Catalog> catalogs = new HashMap<Catalog, Mpeg7Catalog>();
String sourceFlavor = StringUtils.trimToNull(operation.getConfiguration("source-flavor"));
List<String> sourceTagSet = asList(operation.getConfiguration("source-tags"));
Catalog[] catalogsWithTags = mediaPackage.getCatalogsByTags(sourceTagSet);
for (Catalog mediaPackageCatalog : catalogsWithTags) {
if (!MediaPackageElements.SEGMENTS.equals(mediaPackageCatalog.getFlavor())) {
continue;
}
if (sourceFlavor != null) {
if (mediaPackageCatalog.getReference() == null)
continue;
Track t = mediaPackage.getTrack(mediaPackageCatalog.getReference().getIdentifier());
if (t == null || !t.getFlavor().matches(MediaPackageElementFlavor.parseFlavor(sourceFlavor)))
continue;
}
// Make sure the catalog features at least one of the required tags
if (!mediaPackageCatalog.containsTag(sourceTagSet))
continue;
Mpeg7Catalog mpeg7 = loadMpeg7Catalog(mediaPackageCatalog);
// Make sure there is video content
if (mpeg7.videoContent() == null || !mpeg7.videoContent().hasNext()) {
logger.debug("Mpeg-7 segments catalog {} does not contain any video content", mpeg7);
continue;
}
// Make sure there is a temporal decomposition
Video videoContent = mpeg7.videoContent().next();
TemporalDecomposition<? extends Segment> decomposition = videoContent.getTemporalDecomposition();
if (decomposition == null || !decomposition.hasSegments()) {
logger.debug("Mpeg-7 catalog {} does not contain a temporal decomposition", mpeg7);
continue;
}
catalogs.put(mediaPackageCatalog, mpeg7);
}
return catalogs;
}
use of org.opencastproject.metadata.mpeg7.Video in project opencast by opencast.
the class TextAnalyzerServiceImpl method analyze.
/**
* Returns the video text element for the given image.
*
* @param imageFile
* the image
* @param id
* the video text id
* @return the video text found on the image
* @throws TextAnalyzerException
* if accessing the image fails
*/
protected VideoText[] analyze(File imageFile, String id) throws TextAnalyzerException {
/* Call the text extractor implementation to extract the text from the
* provided image file */
List<VideoText> videoTexts = new ArrayList<VideoText>();
TextFrame textFrame = null;
try {
textFrame = textExtractor.extract(imageFile);
} catch (IOException e) {
logger.warn("Error reading image file {}: {}", imageFile, e.getMessage());
throw new TextAnalyzerException(e);
} catch (TextExtractorException e) {
logger.warn("Error extracting text from {}: {}", imageFile, e.getMessage());
throw new TextAnalyzerException(e);
}
/* Get detected text as raw string */
int i = 1;
for (TextLine line : textFrame.getLines()) {
if (line.getText() != null) {
VideoText videoText = new VideoTextImpl(id + "-" + i++);
videoText.setBoundary(line.getBoundaries());
Textual text = dictionaryService.cleanUpText(line.getText());
if (text != null) {
videoText.setText(text);
videoTexts.add(videoText);
}
}
}
return videoTexts.toArray(new VideoText[videoTexts.size()]);
}
use of org.opencastproject.metadata.mpeg7.Video in project opencast by opencast.
the class VideoSegmenterServiceImpl method uniformSegmentation.
/**
* Creates a uniform segmentation for a given track, with prefNumber as the number of segments
* which will all have the same length
*
* @param track the track that is segmented
* @param segmentsNew will be set to list of new segments (pass null if not required)
* @param prefNumber number of generated segments
* @return Mpeg7Catalog that can later be saved in a Catalog as endresult
*/
protected Mpeg7Catalog uniformSegmentation(Track track, LinkedList<Segment> segmentsNew, int prefNumber) {
if (segmentsNew == null) {
segmentsNew = new LinkedList<Segment>();
}
MediaTime contentTime = new MediaRelTimeImpl(0, track.getDuration());
MediaLocator contentLocator = new MediaLocatorImpl(track.getURI());
Mpeg7Catalog mpeg7 = mpeg7CatalogService.newInstance();
Video videoContent = mpeg7.addVideoContent("videosegment", contentTime, contentLocator);
long segmentDuration = track.getDuration() / prefNumber;
long currentSegStart = 0;
// create "prefNumber"-many segments that all have the same length
for (int i = 1; i < prefNumber; i++) {
Segment s = videoContent.getTemporalDecomposition().createSegment("segment-" + i);
s.setMediaTime(new MediaRelTimeImpl(currentSegStart, segmentDuration));
segmentsNew.add(s);
currentSegStart += segmentDuration;
}
// add last segment separately to make sure the last segment ends exactly at the end of the track
Segment s = videoContent.getTemporalDecomposition().createSegment("segment-" + prefNumber);
s.setMediaTime(new MediaRelTimeImpl(currentSegStart, track.getDuration() - currentSegStart));
segmentsNew.add(s);
return mpeg7;
}
use of org.opencastproject.metadata.mpeg7.Video in project opencast by opencast.
the class VideoSegmenterServiceImpl method filterSegmentation.
/**
* Merges small subsequent segments (with high difference) into a bigger one
*
* @param segments list of segments to be filtered
* @param track the track that is segmented
* @param segmentsNew will be set to list of new segments (pass null if not required)
* @param mergeThresh minimum duration for a segment in milliseconds
* @return Mpeg7Catalog that can later be saved in a Catalog as endresult
*/
protected Mpeg7Catalog filterSegmentation(LinkedList<Segment> segments, Track track, LinkedList<Segment> segmentsNew, int mergeThresh) {
if (segmentsNew == null) {
segmentsNew = new LinkedList<Segment>();
}
boolean merging = false;
MediaTime contentTime = new MediaRelTimeImpl(0, track.getDuration());
MediaLocator contentLocator = new MediaLocatorImpl(track.getURI());
Mpeg7Catalog mpeg7 = mpeg7CatalogService.newInstance();
Video videoContent = mpeg7.addVideoContent("videosegment", contentTime, contentLocator);
int segmentcount = 1;
MediaTimePoint currentSegStart = new MediaTimePointImpl();
for (Segment o : segments) {
// if the current segment is shorter than merge treshold start merging
if (o.getMediaTime().getMediaDuration().getDurationInMilliseconds() <= mergeThresh) {
// start merging and save beginning of new segment that will be generated
if (!merging) {
currentSegStart = o.getMediaTime().getMediaTimePoint();
merging = true;
}
// current segment is longer than merge threshold
} else {
long currentSegDuration = o.getMediaTime().getMediaDuration().getDurationInMilliseconds();
long currentSegEnd = o.getMediaTime().getMediaTimePoint().getTimeInMilliseconds() + currentSegDuration;
if (merging) {
long newDuration = o.getMediaTime().getMediaTimePoint().getTimeInMilliseconds() - currentSegStart.getTimeInMilliseconds();
// save new segment that merges all previously skipped short segments
if (newDuration >= mergeThresh) {
Segment s = videoContent.getTemporalDecomposition().createSegment("segment-" + segmentcount++);
s.setMediaTime(new MediaRelTimeImpl(currentSegStart.getTimeInMilliseconds(), newDuration));
segmentsNew.add(s);
// copy the following long segment to new list
Segment s2 = videoContent.getTemporalDecomposition().createSegment("segment-" + segmentcount++);
s2.setMediaTime(o.getMediaTime());
segmentsNew.add(s2);
// if too short split new segment in middle and merge halves to
// previous and following segments
} else {
long followingStartOld = o.getMediaTime().getMediaTimePoint().getTimeInMilliseconds();
long newSplit = (currentSegStart.getTimeInMilliseconds() + followingStartOld) / 2;
long followingEnd = followingStartOld + o.getMediaTime().getMediaDuration().getDurationInMilliseconds();
long followingDuration = followingEnd - newSplit;
// if at beginning, don't split, just merge to first large segment
if (segmentsNew.isEmpty()) {
Segment s = videoContent.getTemporalDecomposition().createSegment("segment-" + segmentcount++);
s.setMediaTime(new MediaRelTimeImpl(0, followingEnd));
segmentsNew.add(s);
} else {
long previousStart = segmentsNew.getLast().getMediaTime().getMediaTimePoint().getTimeInMilliseconds();
// adjust end time of previous segment to split time
segmentsNew.getLast().setMediaTime(new MediaRelTimeImpl(previousStart, newSplit - previousStart));
// create new segment starting at split time
Segment s = videoContent.getTemporalDecomposition().createSegment("segment-" + segmentcount++);
s.setMediaTime(new MediaRelTimeImpl(newSplit, followingDuration));
segmentsNew.add(s);
}
}
merging = false;
// copy segments that are long enough to new list (with corrected number)
} else {
Segment s = videoContent.getTemporalDecomposition().createSegment("segment-" + segmentcount++);
s.setMediaTime(o.getMediaTime());
segmentsNew.add(s);
}
}
}
// if there is an unfinished merging process after going through all segments
if (merging && !segmentsNew.isEmpty()) {
long newDuration = track.getDuration() - currentSegStart.getTimeInMilliseconds();
// if merged segment is long enough, create new segment
if (newDuration >= mergeThresh) {
Segment s = videoContent.getTemporalDecomposition().createSegment("segment-" + segmentcount);
s.setMediaTime(new MediaRelTimeImpl(currentSegStart.getTimeInMilliseconds(), newDuration));
segmentsNew.add(s);
// if not long enough, merge with previous segment
} else {
newDuration = track.getDuration() - segmentsNew.getLast().getMediaTime().getMediaTimePoint().getTimeInMilliseconds();
segmentsNew.getLast().setMediaTime(new MediaRelTimeImpl(segmentsNew.getLast().getMediaTime().getMediaTimePoint().getTimeInMilliseconds(), newDuration));
}
}
// segment spanning the whole video
if (segmentsNew.isEmpty()) {
Segment s = videoContent.getTemporalDecomposition().createSegment("segment-" + segmentcount);
s.setMediaTime(new MediaRelTimeImpl(0, track.getDuration()));
segmentsNew.add(s);
}
return mpeg7;
}
use of org.opencastproject.metadata.mpeg7.Video in project opencast by opencast.
the class VideoSegmenterTest method setUp.
/**
* Setup for the video segmenter service, including creation of a mock workspace.
*
* @throws Exception
* if setup fails
*/
@Before
public void setUp() throws Exception {
mpeg7Service = new Mpeg7CatalogService();
Workspace workspace = EasyMock.createNiceMock(Workspace.class);
EasyMock.expect(workspace.get((URI) EasyMock.anyObject())).andReturn(new File(track.getURI()));
tempFile = testFolder.newFile(getClass().getName() + ".xml");
EasyMock.expect(workspace.putInCollection((String) EasyMock.anyObject(), (String) EasyMock.anyObject(), (InputStream) EasyMock.anyObject())).andAnswer(new IAnswer<URI>() {
@Override
public URI answer() throws Throwable {
InputStream in = (InputStream) EasyMock.getCurrentArguments()[2];
IOUtils.copy(in, new FileOutputStream(tempFile));
return tempFile.toURI();
}
});
EasyMock.replay(workspace);
mpeg7Service1 = new Mpeg7CatalogService();
Workspace workspace1 = EasyMock.createNiceMock(Workspace.class);
EasyMock.expect(workspace1.get((URI) EasyMock.anyObject())).andReturn(new File(track1.getURI()));
tempFile1 = testFolder.newFile(getClass().getName() + "-1.xml");
EasyMock.expect(workspace1.putInCollection((String) EasyMock.anyObject(), (String) EasyMock.anyObject(), (InputStream) EasyMock.anyObject())).andAnswer(new IAnswer<URI>() {
@Override
public URI answer() throws Throwable {
InputStream in = (InputStream) EasyMock.getCurrentArguments()[2];
IOUtils.copy(in, new FileOutputStream(tempFile1));
return tempFile1.toURI();
}
});
EasyMock.replay(workspace1);
User anonymous = new JaxbUser("anonymous", "test", new DefaultOrganization(), new JaxbRole(DefaultOrganization.DEFAULT_ORGANIZATION_ANONYMOUS, new DefaultOrganization()));
UserDirectoryService userDirectoryService = EasyMock.createMock(UserDirectoryService.class);
EasyMock.expect(userDirectoryService.loadUser((String) EasyMock.anyObject())).andReturn(anonymous).anyTimes();
EasyMock.replay(userDirectoryService);
Organization organization = new DefaultOrganization();
OrganizationDirectoryService organizationDirectoryService = EasyMock.createMock(OrganizationDirectoryService.class);
EasyMock.expect(organizationDirectoryService.getOrganization((String) EasyMock.anyObject())).andReturn(organization).anyTimes();
EasyMock.replay(organizationDirectoryService);
SecurityService securityService = EasyMock.createNiceMock(SecurityService.class);
EasyMock.expect(securityService.getUser()).andReturn(anonymous).anyTimes();
EasyMock.expect(securityService.getOrganization()).andReturn(organization).anyTimes();
EasyMock.replay(securityService);
vsegmenter = new VideoSegmenterServiceImpl();
serviceRegistry = new ServiceRegistryInMemoryImpl(vsegmenter, securityService, userDirectoryService, organizationDirectoryService, EasyMock.createNiceMock(IncidentService.class));
vsegmenter.setServiceRegistry(serviceRegistry);
vsegmenter.setMpeg7CatalogService(mpeg7Service);
vsegmenter.setWorkspace(workspace);
vsegmenter.setSecurityService(securityService);
vsegmenter.setUserDirectoryService(userDirectoryService);
vsegmenter.setOrganizationDirectoryService(organizationDirectoryService);
vsegmenter1 = new VideoSegmenterServiceImpl();
serviceRegistry1 = new ServiceRegistryInMemoryImpl(vsegmenter1, securityService, userDirectoryService, organizationDirectoryService, EasyMock.createNiceMock(IncidentService.class));
vsegmenter1.setServiceRegistry(serviceRegistry1);
vsegmenter1.setMpeg7CatalogService(mpeg7Service1);
vsegmenter1.setWorkspace(workspace1);
vsegmenter1.setSecurityService(securityService);
vsegmenter1.setUserDirectoryService(userDirectoryService);
vsegmenter1.setOrganizationDirectoryService(organizationDirectoryService);
// set parameters for segmentation because the default parameters are not suitable for too short videos
vsegmenter.prefNumber = 2;
vsegmenter.stabilityThreshold = 2;
vsegmenter.absoluteMin = 1;
vsegmenter1.stabilityThreshold = 2;
vsegmenter1.changesThreshold = 0.025f;
vsegmenter1.prefNumber = 5;
vsegmenter1.maxCycles = 5;
vsegmenter1.maxError = 0.2f;
vsegmenter1.absoluteMin = 1;
}
Aggregations