/**
* 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.inspection.ffmpeg;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.opencastproject.util.MimeType.mimeType;
import static org.opencastproject.util.data.Option.none;
import static org.opencastproject.util.data.Option.some;
import static org.opencastproject.util.data.functions.Misc.chuck;
import org.opencastproject.inspection.api.util.Options;
import org.opencastproject.mediapackage.AudioStream;
import org.opencastproject.mediapackage.Track;
import org.opencastproject.mediapackage.TrackSupport;
import org.opencastproject.mediapackage.VideoStream;
import org.opencastproject.util.Checksum;
import org.opencastproject.util.ChecksumType;
import org.opencastproject.util.IoSupport;
import org.opencastproject.util.MimeType;
import org.opencastproject.util.StreamHelper;
import org.opencastproject.util.data.Option;
import org.opencastproject.workspace.api.Workspace;
import org.apache.tika.parser.audio.AudioParser;
import org.easymock.EasyMock;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
public class MediaInspectionServiceImplTest {
private static final Logger logger = LoggerFactory.getLogger(MediaInspectionServiceImplTest.class);
/** True to run the tests */
private static Option<String> ffprobePath;
@BeforeClass
public static void setupClass() {
StreamHelper stdout = null;
StreamHelper stderr = null;
Process p = null;
try {
// ffprobe requires a track in order to return a status code of 0, indicating that it is working as expected
URI uriTrack = MediaInspectionServiceImpl.class.getResource("/test.mp4").toURI();
File f = new File(uriTrack);
p = new ProcessBuilder(FFmpegAnalyzer.FFPROBE_BINARY_DEFAULT, f.getAbsolutePath()).start();
stdout = new StreamHelper(p.getInputStream());
stderr = new StreamHelper(p.getErrorStream());
int exitCode = p.waitFor();
stdout.stopReading();
stderr.stopReading();
if (exitCode != 0) {
throw new IllegalStateException("process returned " + exitCode);
}
ffprobePath = some(FFmpegAnalyzer.FFPROBE_BINARY_DEFAULT);
} catch (Throwable t) {
logger.warn("Skipping media inspection tests due to unsatisfied FFmpeg (ffprobe) installation: " + t.getMessage());
ffprobePath = none();
} finally {
IoSupport.closeQuietly(stdout);
IoSupport.closeQuietly(stderr);
IoSupport.closeQuietly(p);
}
}
/** Setup test. */
@Ignore
private Option<MediaInspector> init(URI resource) throws Exception {
for (String binary : ffprobePath) {
final File f = new File(resource);
Workspace workspace = EasyMock.createNiceMock(Workspace.class);
EasyMock.expect(workspace.get(resource)).andReturn(f);
EasyMock.expect(workspace.get(resource)).andReturn(f);
EasyMock.expect(workspace.get(resource)).andReturn(f);
EasyMock.replay(workspace);
return some(new MediaInspector(workspace, new AudioParser(), binary));
}
return none();
}
private URI getResource(String resource) {
try {
return MediaInspectionServiceImpl.class.getResource(resource).toURI();
} catch (URISyntaxException e) {
return chuck(e);
}
}
@Test
public void testInspection() throws Exception {
final URI trackUri = getResource("/test.mp4");
for (MediaInspector mi : init(trackUri)) {
Track track = mi.inspectTrack(trackUri, Options.NO_OPTION);
// test the returned values
Checksum cs = Checksum.create(ChecksumType.fromString("md5"), "cc72b7a4f1a68b84fba6f0fb895da395");
assertEquals(cs, track.getChecksum());
assertEquals("video", track.getMimeType().getType());
assertEquals("mp4", track.getMimeType().getSubtype());
assertNotNull(track.getDuration());
assertTrue(track.getDuration() > 0);
}
}
@Test
public void testInspectionEmptyContainer() throws Exception {
final URI trackUri = getResource("/nostreams.mp4");
for (MediaInspector mi : init(trackUri)) {
final Track track = mi.inspectTrack(trackUri, Options.NO_OPTION);
assertEquals(0, track.getStreams().length);
assertEquals("mp4", track.getMimeType().getSubtype());
assertEquals(null, track.getDuration());
}
}
@Test
public void testEnrichment() throws Exception {
final URI trackUri = getResource("/test.mp4");
for (MediaInspector mi : init(trackUri)) {
Track track = mi.inspectTrack(trackUri, Options.NO_OPTION);
// make changes to metadata
Checksum cs = track.getChecksum();
track.setChecksum(null);
MimeType mt = mimeType("video", "flash");
track.setMimeType(mt);
// test the enrich scenario
Track newTrack = (Track) mi.enrich(track, false, Options.NO_OPTION);
VideoStream[] videoStreams = TrackSupport.byType(newTrack.getStreams(), VideoStream.class);
assertTrue(videoStreams[0].getFrameCount().longValue() > 0);
AudioStream[] audioStreams = TrackSupport.byType(newTrack.getStreams(), AudioStream.class);
assertTrue(audioStreams[0].getFrameCount().longValue() > 0);
assertEquals(newTrack.getChecksum(), cs);
assertEquals(newTrack.getMimeType(), mt);
assertNotNull(newTrack.getDuration());
assertTrue(newTrack.getDuration() > 0);
// test the override scenario
newTrack = (Track) mi.enrich(track, true, Options.NO_OPTION);
assertEquals(newTrack.getChecksum(), cs);
assertNotSame(newTrack.getMimeType(), mt);
assertTrue(newTrack.getDuration() > 0);
}
for (MediaInspector mi : init(trackUri)) {
Track track = mi.inspectTrack(trackUri, Options.NO_OPTION);
// make changes to metadata
Checksum cs = track.getChecksum();
track.setChecksum(null);
MimeType mt = mimeType("video", "flash");
track.setMimeType(mt);
// test the enrich scenario
Track newTrack = (Track) mi.enrich(track, false, Options.NO_OPTION);
VideoStream[] videoStreams = TrackSupport.byType(newTrack.getStreams(), VideoStream.class);
assertTrue(videoStreams[0].getFrameCount().longValue() > 0);
AudioStream[] audioStreams = TrackSupport.byType(newTrack.getStreams(), AudioStream.class);
assertTrue(audioStreams[0].getFrameCount().longValue() > 0);
assertEquals(newTrack.getChecksum(), cs);
assertEquals(newTrack.getMimeType(), mt);
assertNotNull(newTrack.getDuration());
assertTrue(newTrack.getDuration() > 0);
// test the override scenario
newTrack = (Track) mi.enrich(track, true, Options.NO_OPTION);
assertEquals(newTrack.getChecksum(), cs);
assertNotSame(newTrack.getMimeType(), mt);
assertTrue(newTrack.getDuration() > 0);
}
}
@Test
public void testEnrichmentEmptyContainer() throws Exception {
final URI trackUri = getResource("/nostreams.mp4");
for (MediaInspector mi : init(trackUri)) {
Track track = mi.inspectTrack(trackUri, Options.NO_OPTION);
// make changes to metadata
Checksum cs = track.getChecksum();
track.setChecksum(null);
MimeType mt = mimeType("video", "flash");
track.setMimeType(mt);
// test the enrich scenario
Track newTrack = (Track) mi.enrich(track, false, Options.NO_OPTION);
assertEquals(newTrack.getChecksum(), cs);
assertEquals(newTrack.getMimeType(), mt);
assertNull(newTrack.getDuration());
// test the override scenario
newTrack = (Track) mi.enrich(track, true, Options.NO_OPTION);
assertEquals(newTrack.getChecksum(), cs);
assertNotSame(newTrack.getMimeType(), mt);
assertNull(newTrack.getDuration());
}
}
}