Initial work on detecting video and audio files.
This commit is contained in:
parent
984c74b63f
commit
1e02c6b88b
4 changed files with 124 additions and 0 deletions
94
src/org/forkalsrud/album/exif/OggIdentifier.java
Normal file
94
src/org/forkalsrud/album/exif/OggIdentifier.java
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.forkalsrud.album.exif;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author knut
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OggIdentifier {
|
||||||
|
|
||||||
|
static Codec getIdentifier(File f) throws IOException {
|
||||||
|
|
||||||
|
return getIdentifier(new FileInputStream(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Codec getIdentifier(InputStream is) throws IOException {
|
||||||
|
|
||||||
|
byte[] header = new byte[1024];
|
||||||
|
int len = is.read(header);
|
||||||
|
|
||||||
|
if (len < 100) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the OggS magic marker is there
|
||||||
|
for (int i = 0; i < MAGIC.length; i++) {
|
||||||
|
if (header[i] != MAGIC[i]) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Codec c : CODECS) {
|
||||||
|
if (c.matches(header, 28)) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte[] MAGIC = "OggS".getBytes();
|
||||||
|
|
||||||
|
static class Codec {
|
||||||
|
byte[] magic;
|
||||||
|
String mimeType;
|
||||||
|
|
||||||
|
public String getMimeType() {
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Codec(String mimeType, char... magic) {
|
||||||
|
this.magic = new byte[magic.length];
|
||||||
|
for (int i = 0; i < magic.length; i++) {
|
||||||
|
this.magic[i] = (byte)magic[i];
|
||||||
|
}
|
||||||
|
this.mimeType = mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matches(byte[] src, int offset) {
|
||||||
|
|
||||||
|
for (int i = 0; i < magic.length; i++) {
|
||||||
|
if (src[offset + i] != magic[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Codec[] CODECS = new Codec[] {
|
||||||
|
new Codec("video/ogg; codecs=dirac", 'B', 'B', 'C', 'D', '\0'),
|
||||||
|
new Codec("video/ogg; codecs=flac", (char)177, 'F', 'L', 'A', 'C'),
|
||||||
|
new Codec("video/ogg; codecs=theora", (char)0x80, 't', 'h', 'e', 'o', 'r', 'a'),
|
||||||
|
new Codec("audio/ogg; codecs=vorbis", (char)0x01, 'v', 'o', 'r', 'b', 'i', 's'),
|
||||||
|
new Codec("application/ogg; codecs=celt", 'C', 'E', 'L', 'T', ' ', ' ', ' ', ' '),
|
||||||
|
new Codec("application/ogg; codecs=cmml", 'C', 'M', 'M', 'L', '\0', '\0', '\0', '\0'),
|
||||||
|
new Codec("application/ogg; codecs=jng", (char)213, 'J', 'N', 'G', '\r', '\n', ' ', '\n'),
|
||||||
|
new Codec("application/ogg; codecs=kate", (char)0x80, 'k', 'a', 't', 'e', '\0', '\0', '\0'),
|
||||||
|
new Codec("application/ogg; codecs=midi", 'O', 'g', 'g', 'm', 'i', 'd', 'i', '\0'),
|
||||||
|
new Codec("application/ogg; codecs=mng", (char)212, 'M', 'N', 'G', '\r', '\n', ' ', '\n'),
|
||||||
|
new Codec("audio/ogg; codecs=pcm", 'P', 'C', 'M', ' ', ' ', ' ', ' ', ' '),
|
||||||
|
new Codec("application/ogg; codecs=png", (char)212, 'P', 'N', 'G', '\r', '\n', ' ', '\n'),
|
||||||
|
new Codec("audio/ogg; codecs=speex", 'S', 'p', 'e', 'e', 'x', ' ', ' ', ' '),
|
||||||
|
new Codec("video/ogg; codecs=yuv4mpeg", 'Y', 'U', 'V', '4', 'M', 'P', 'E', 'G'),
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
30
src/org/forkalsrud/album/exif/OggIdentifierTest.java
Normal file
30
src/org/forkalsrud/album/exif/OggIdentifierTest.java
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
package org.forkalsrud.album.exif;
|
||||||
|
|
||||||
|
import org.forkalsrud.album.exif.OggIdentifier.Codec;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
public class OggIdentifierTest extends TestCase {
|
||||||
|
|
||||||
|
public void testVideoIdentifier() throws Exception {
|
||||||
|
|
||||||
|
Codec codec = OggIdentifier.getIdentifier(getClass().getResourceAsStream("videoheader.ogg"));
|
||||||
|
assertNotNull(codec);
|
||||||
|
assertEquals("video/ogg; codecs=theora", codec.getMimeType());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testAudioIdentifier() throws Exception {
|
||||||
|
|
||||||
|
Codec codec = OggIdentifier.getIdentifier(getClass().getResourceAsStream("musicheader.ogg"));
|
||||||
|
assertNotNull(codec);
|
||||||
|
assertEquals("audio/ogg; codecs=vorbis", codec.getMimeType());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testInvalidIdentifier() throws Exception {
|
||||||
|
|
||||||
|
Codec codec = OggIdentifier.getIdentifier(getClass().getResourceAsStream("OggIdentifierTest.class"));
|
||||||
|
assertNull(codec);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
src/org/forkalsrud/album/exif/musicheader.ogg
Normal file
BIN
src/org/forkalsrud/album/exif/musicheader.ogg
Normal file
Binary file not shown.
BIN
src/org/forkalsrud/album/exif/videoheader.ogg
Normal file
BIN
src/org/forkalsrud/album/exif/videoheader.ogg
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue