Get MP3 ID3 meta data and song duration using AudioStreamer

I'm using Matt Gallagher's AudioStreamer to play MP3s over HTTP. I need to know the duration of the song and the ID3 tags.

Is it possible to implement this in the AudioStreamer, and how?


From his Docs:

Limited scope One point should be clarified before I continue: this class is intended for streaming audio. By streaming, I don't simply mean "an audio file transferred over HTTP". Instead, I mean a continuous HTTP source without an end that continues indefinitely (like a radio station, not a single song).

This seems to imply that getting the duration might be tough.

Here is how to get the ID3v2 tags:

Get metadata The easiest source of metadata comes from the HTTP headers. Inside the handleReadFromStream:eventType: method, use CFReadStreamCopyProperty to copy the kCFStreamPropertyHTTPResponseHeader property from the CFReadStreamRef, then you can use CFHTTPMessageCopyAllHeaderFields to copy the header fields out of the response. For many streaming audio servers, the stream name is one of these fields.

The considerably harder source of metadata are the ID3 tags. ID3v1 is always at the end of the file (so is useless when streaming). ID3v2 is located at the start so may be more accessible.

I've never read the ID3 tags but I suspect that if you cache the first few hundred kilobytes of the file somewhere as it loads, open that cache with AudioFileOpenWithCallbacks and then read the kAudioFilePropertyID3Tag with AudioFileGetProperty you may be able to read the ID3 data (if it exists). Like I said though: I've never actually done this so I don't know for certain that it would work.


MP3 streams are divided into 'frames' which are single units of data. Some streams do add a ID3 metadata block every few frames which you could theoretically scan for and read.

See here for more information: http://jicyshout.sourceforge.net/oreilly-article/java-streaming-mp3-pt2/java-streaming-mp3-pt2.html


  • Python Batch convert of FLAC files
  • Python-daemon: keep logging
  • deleteing id3 tag
  • Want to multiply, not repeat variable
  • Subset from xpath query?
  • nginx on VirtualBox Ubuntu guest serves stale content [closed]
  • How to read stringified JSON string in Java [duplicate]
  • unrecognized selector sent to instance error when a button is clicked
  • Is it possible to mirror a single queue in ActiveMQ?
  • Drop variable in panel data in R conditional based on a defined number of consecutive observations
  • Amazon s3 – 403 Forbidden with Correct Bucket Policy
  • C#, Updating a Progress Bar Using Background Worker From a Different Class
  • Should I create an object or work with an array?
  • Keep Sql Connection open for iterating many requests? Or close each step?
  • How to add new index numbers to the upsampled data while preserving the orginal indices one
  • Error in GGally: Error in unit(tic_pos.c, “mm”) : 'x' and 'units' must have leng
  • Best practice for switching iPhone views?
  • Motorola barcode scanner SDK events C#
  • Tap to record like in vine using javacv
  • How do I register classes by both interface and namespace with Windsor?
  • Flash radiobutton: how do I get the selected radiobutton?
  • Find group of records that match multiple values
  • Is there some graphical way to create my own configuration file on SonarLint?
  • Row to Column conversion in Talend
  • How do I display a dialog that asks the user multi-choice questıon using tkInter?
  • Unable to get column index with table.getColumn method using custom table Model
  • Visual Studio 2010 debugger build correctly - compiler pdb and linker pdb not in synch?
  • Oledb connection string for excel files
  • Spark fat jar to run multiple versions on YARN
  • CSS Linear-gradient formatting issue accross different browsers
  • Sails.js/waterline: Executing waterline queries in toJSON function of a model?
  • Master page gives error
  • Nant, Vault & Windows Integrated Authentication
  • Counter field in MS Access, how to generate?
  • Javascript + PHP Encryption with pidCrypt
  • Redux, normalised entities and lodash merge
  • Websockets service method fails during R startup
  • Do create extension work in single-user mode in postgres?
  • Why can't I rebase on to an ancestor of source changesets if on a different branch?
  • How do you join a server to an Active Directory (domain)?