diff --git a/src/map.rs b/src/map.rs index d97d94f..1d92627 100644 --- a/src/map.rs +++ b/src/map.rs @@ -277,6 +277,13 @@ matcher_map!( "m4a", matchers::audio::is_m4a ), + // has to come before ogg + ( + MatcherType::Audio, + "audio/opus", + "opus", + matchers::audio::is_ogg_opus + ), ( MatcherType::Audio, "audio/ogg", diff --git a/src/matchers/audio.rs b/src/matchers/audio.rs index 24746d9..73cfed4 100644 --- a/src/matchers/audio.rs +++ b/src/matchers/audio.rs @@ -29,6 +29,23 @@ pub fn is_ogg(buf: &[u8]) -> bool { buf.len() > 3 && buf[0] == 0x4F && buf[1] == 0x67 && buf[2] == 0x67 && buf[3] == 0x53 } +/// Returns whether a buffer is OGG Opus data. +pub fn is_ogg_opus(buf: &[u8]) -> bool { + if !is_ogg(buf) { + return false; + } + + buf.len() > 35 + && buf[28] == 0x4F + && buf[29] == 0x70 + && buf[30] == 0x75 + && buf[31] == 0x73 + && buf[32] == 0x48 + && buf[33] == 0x65 + && buf[34] == 0x61 + && buf[35] == 0x64 +} + /// Returns whether a buffer is FLAC data. pub fn is_flac(buf: &[u8]) -> bool { buf.len() > 3 && buf[0] == 0x66 && buf[1] == 0x4C && buf[2] == 0x61 && buf[3] == 0x43 diff --git a/testdata/sample_48kbps.opus b/testdata/sample_48kbps.opus new file mode 100644 index 0000000..c8d63de Binary files /dev/null and b/testdata/sample_48kbps.opus differ diff --git a/tests/audio.rs b/tests/audio.rs index 6352fdb..b07c7c4 100644 --- a/tests/audio.rs +++ b/tests/audio.rs @@ -3,3 +3,4 @@ mod common; test_format!(Audio, "audio/mpeg", "mp3", mp3, "sample.mp3"); test_format!(Audio, "audio/x-dsf", "dsf", dsf, "sample.dsf"); test_format!(Audio, "audio/x-ape", "ape", ape, "sample.ape"); +test_format!(Audio, "audio/opus", "opus", opus, "sample_48kbps.opus");