Audible Audio: Difference between revisions

From MultimediaWiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 8: Line 8:
* [http://en.wikipedia.org/wiki/Audible.com Wikipedia entry]
* [http://en.wikipedia.org/wiki/Audible.com Wikipedia entry]


==== Parsing metadata ====
=== File format ===


This following Ruby code works for parsing the metadata on the only sample available. This table starts at 0xb8.
The file is built up of 5 parts:
* general header
* text based metadata
* some codec related header
* offset table
* data
 
==== General header ====
 
First 4 bytes is the file size including these four bytes.
 
==== Text based metadata ====
 
  number_of_entires (32)
  skip (8)
 
  key_length (32)
  value_length (32)
  key (key_length)
  value (value_length+1)
 
==== Offset table ====
  number_of_entries (32)
 
  type (32) [0 - meta?, 1 - meta?, 2 - audio packets, 3 - meta?, 4 - meta?]
  offset (32) [must be relative, as the first entry in the list is always 0]
 
==== Parsing the file ====
 
This following Ruby code works for parsing the known parts:


   video = File.new(ARGV[0])
   video = File.new(ARGV[0])
   video.read(184) # skip header
   puts "File size: #{video.read(4).unpack('N')[0].ti_i}"
  video.read(0xb4) # skip header
   sizes = video.read(4).unpack('N')
   sizes = video.read(4).unpack('N')
   puts "Number of entires: #{sizes[0].to_i}"
   puts "Number of entires: #{sizes[0].to_i}"
Line 22: Line 52:
     value = video.read(sizes[0].to_i+1)
     value = video.read(sizes[0].to_i+1)
     puts "#{x} key(#{sizes[0].to_i})=#{key} value(#{sizes[0].to_i)=#{value}"
     puts "#{x} key(#{sizes[0].to_i})=#{key} value(#{sizes[0].to_i)=#{value}"
  }
  video.read(0x6f) # skip
  sizes = video.read(4).unpack('N')
  puts "Number of packet table entries: #{sizes[0].to_i}"
  (1..sizes[0].to_i).each {
    sizes = video.read(8).unpack('NN')
    puts "type=#{sizes[0].to_i} offset=#{sizes[1].to_i}"
   }
   }


Line 33: Line 70:
Probably a seek table starts at 0x5f8:
Probably a seek table starts at 0x5f8:


  type(32) [1 - meta?, 2 - audio packets, 3 - meta?, 4 - meta?]
  offset(32) [must be relative, as the first entry in the list is always 0]


[[Category: Container Formats]]
[[Category: Container Formats]]

Revision as of 17:06, 19 August 2009

Proprietary container format from audible.com. There is no published specification. It may contain one of five different encodings which are numbered 1 thru 5. 1-3 are rumored to be ACELP.net at varying bitrates. #4 is MP3. #5 is some unknown Sony format.

File format

The file is built up of 5 parts:

  • general header
  • text based metadata
  • some codec related header
  • offset table
  • data

General header

First 4 bytes is the file size including these four bytes.

Text based metadata

 number_of_entires (32)
 skip (8)
 
 key_length (32)
 value_length (32)
 key (key_length)
 value (value_length+1)

Offset table

 number_of_entries (32)
 type (32) [0 - meta?, 1 - meta?, 2 - audio packets, 3 - meta?, 4 - meta?]
 offset (32) [must be relative, as the first entry in the list is always 0]

Parsing the file

This following Ruby code works for parsing the known parts:

 video = File.new(ARGV[0])
 puts "File size: #{video.read(4).unpack('N')[0].ti_i}"
 video.read(0xb4) # skip header
 sizes = video.read(4).unpack('N')
 puts "Number of entires: #{sizes[0].to_i}"
 video.read(1) # skip
 (1..sizes[0].to_i).each { |x|
   sizes = video.read(8).unpack('NN')
   key = video.read(sizes[0].to_i)
   value = video.read(sizes[0].to_i+1)
   puts "#{x} key(#{sizes[0].to_i})=#{key} value(#{sizes[0].to_i)=#{value}"
 }
 video.read(0x6f) # skip
 sizes = video.read(4).unpack('N')
 puts "Number of packet table entries: #{sizes[0].to_i}"
 (1..sizes[0].to_i).each {
   sizes = video.read(8).unpack('NN')
   puts "type=#{sizes[0].to_i} offset=#{sizes[1].to_i}"
 }

Sample output (stripped):

 13 key(5)=codec value(7)=acelp85
 16 key(10)=HeaderSeed value(10)=1158166611
 18 key(9)=HeaderKey value(43)=3759801365 1641076194 2988088058 4282540117
 19 key(15)=EncryptedBlocks value(5)=39333

Probably a seek table starts at 0x5f8: