Skip to content

Instantly share code, notes, and snippets.

@IARI
Created March 15, 2019 23:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IARI/914ba94cd4cb3acd91697ee6776804db to your computer and use it in GitHub Desktop.
Save IARI/914ba94cd4cb3acd91697ee6776804db to your computer and use it in GitHub Desktop.
get the length of a vorbis/ogg file
//4 bytes for "OggS", 2 unused bytes, 8 bytes for length
private const val OGG_OFFSET = 8 + 2 + 4
private val OGGS_BYTES = "OggS".map(Char::toByte).toByteArray()
private val VORBIS_BYTES = "vorbis".map(Char::toByte).toByteArray()
fun ByteArray.slice(start: Int, len: Int) = copyOfRange(start, start + len)
@Throws(IOException::class)
fun calculateOggDuration(oggFile: File): Pair<Int, Int> {
var rate = -1
var length = -1
val size = oggFile.length().toInt()
val t = ByteArray(size)
oggFile.inputStream().use { stream ->
stream.read(t)
val endIndex = size - OGG_OFFSET - 1
for (i in endIndex downTo 0) {
if (OGGS_BYTES contentEquals t.sliceArray(i..(i + 3))) {
length = t
.slice(i + 6, 8)
.let(ByteBuffer::wrap)
.order(ByteOrder.LITTLE_ENDIAN)
.getInt(0)
break
}
}
for (i in 0..endIndex) {
if (VORBIS_BYTES contentEquals t.sliceArray(i..(i + 5))) {
rate = t
.slice(i + 11, 4)
.let(ByteBuffer::wrap)
.order(ByteOrder.LITTLE_ENDIAN)
.getInt(0)
break
}
}
}
return length to rate
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment