/* * @(#)Ogg.java * * This file is part of webCDwriter - Network CD Writing. * * Copyright (C) 2003 Jörg P. M. Haeger * * webCDwriter is free software. See CDcreator.java for details. */ import java.io.File; import java.io.FileInputStream; import java.io.InputStream; /** * Class to get the length of ogg files. * * @version 20030220 * @author Jörg P. M. Haeger */ class Ogg { int audio_channels; int audio_sample_rate; long dataLength; long headerStart; long sampleNum; int vorbis_version; public Ogg(File file) throws Exception { this(file.getPath()); } public Ogg(String file) throws Exception { dataLength = new File(file).length(); FileInputStream inStream = new FileInputStream(file); int pos = 0; while (true) { int packet_type = 0; char[] capture_pattern1 = { 'v','o','r','b','i','s' }; for (int i = 0; i < capture_pattern1.length; i++) { int b = inStream.read(); if (b == -1) throw new Exception( "no Vorbis identification header"); pos++; if (b != capture_pattern1[i]) { packet_type = b; i = -1; } } if (packet_type == 1) break; } vorbis_version = read32Bits(inStream); if (vorbis_version > 0) throw new Exception("unknown vorbis_version " + vorbis_version); audio_channels = inStream.read(); audio_sample_rate = read32Bits(inStream); pos += 4 + 1 + 4; headerStart = dataLength - 16 * 1024; inStream.skip(headerStart - pos); int count = 0; while (true) { char[] capture_pattern = { 'O', 'g', 'g', 'S', 0 }; int i; for (i = 0; i < capture_pattern.length; i++) { int b = inStream.read(); if (b == -1) break; if (b != capture_pattern[i]) { headerStart += i + 1; i = -1; } } if (i < capture_pattern.length) break; count++; // System.out.println(count // + " OggS at " + firstHeaderStart); int header_type_flag = inStream.read(); if (header_type_flag == -1) break; long absolute_granule_position = 0; for (i = 0; i < 8; i++) { long b = inStream.read(); if (b == -1) break; absolute_granule_position |= b << (8 * i); } if (i < 8) break; if ((header_type_flag & 0x06) != 0) { /* System.out.print("OggS " + count + " at " + headerStart); if ((header_type_flag & 0x01) != 0) System.out.print(": continued"); if ((header_type_flag & 0x02) != 0) System.out.print(": first"); if ((header_type_flag & 0x04) != 0) System.out.print(": last"); System.out.println(" " + absolute_granule_position); */ sampleNum = absolute_granule_position; } } } long getSeconds() { if (audio_sample_rate > 0) return sampleNum / audio_sample_rate; else return 0; } public static void main(String[] args) throws Exception { new Ogg(args[0]).showInfo(); } public int read32Bits(InputStream inStream) throws Exception { int n = 0; for (int i = 0; i < 4; i++) { int b = inStream.read(); if (b == -1) throw new Exception("Unexpected end of input stream"); n |= b << (8 * i); } return n; } public void showInfo() { System.out.println("audio_channels = " + audio_channels); System.out.println("audio_sample_rate = " + audio_sample_rate); System.out.println("dataLength = " + dataLength); System.out.println("seconds = " + getSeconds()); System.out.println("headerStart = " + headerStart); System.out.println("vorbis_version = " + vorbis_version); } }