Tuesday, February 16, 2010

Radio App Example iPhone

I was working on an application to play audio stream from an online radio. Here is some hints for the developers who want to do similar types of work.

Initially we have two major task:
1. Read stream data.
2. Play the stream data.

From apple developer documentation:

http://developer.apple.com/iphone/library/codinghowtos/AudioAndVideo/index.html#STREAMING

How do I play streamed audio?

To play streamed audio, you connect to a network stream using the CFNetwork interfaces from Core Foundation, such as those in CFHTTPMessage. You then parse the network packets into audio packets using Audio File Stream Services (AudioToolbox/AudioFileStream.h). Finally, you play the audio packets using Audio Queue Services (AudioToolbox/AudioQueue.h). You can also use Audio File Stream Services to parse audio packets from an on-disk file.

Task 1: Working with HTTP stream

Read "CFNetwork Programming Guide" specially the "Communicating with HTTP Servers" part.

Use the callback
if (CFReadStreamSetClient(myReadStream, registeredEvents, myCallBack, &myContext) {...}


A sample callback:
static void myCallBack
(CFReadStreamRef stream, CFStreamEventType type, void *clientCallBackInfo) {
if(type == kCFStreamEventHasBytesAvailable) {
UInt8 buffer[2048];
CFIndex bytesRead = CFReadStreamRead(stream, buffer, sizeof(buffer));

if (bytesRead > 0) {
//nothing
}
else if (bytesRead) {
NSString* to_add = [NSString stringWithCString: (char*)buffer length: bytesRead];
NSLog(@"%@", to_add);
}
}
}


Run the application. If you can see the HTML tag in your debug console, then your network stream reading is working fine.


Task 2: Working with audio

Read "Audio File Stream Services Reference" to get basic idea about the streaming audio.

Check the "AudioFileStreamExample" from:
http://developer.apple.com/Mac/library/samplecode/AudioFileStreamExample/index.html

Merge the "AudioFileStreamParseBytes" with the "myCallBack" method.

Download Sample Code:
http://www.mymacbd.com/forum/viewtopic.php?id=26

16 comments:

angoula said...

hello, very nice tutorial, but do you have an active link to download your sample. Because I still can't make my apps stream music.
So if you could give us a working link to your sample.

Thanks in advnce.

Hermann

salahuddin66 said...

Download the 2nd example from:

http://www.mymacbd.com/forum/viewtopic.php?id=26

Karthik Janagiraman said...

REally helpfull tutorial , hats off man ! keep up the good work

lake said...

hii wud u plz tell me how to get the song title from this code

lake said...

Hii Nice tut........


Wud u tell me how to display song title here using this code.....

salahuddin66 said...

You need to create another HTTP request to get the stream related information.
Have a look in the following URL:
http://www.sluniverse.com/php/vb/script … tream.html
Example: http://aac.fusionchicago.com:8006/7.html
// 7.html gives the following in the body
// 0 -> current listeners
// 1 -> status
// 2 -> listener peak
// 3 -> max listeners
// 4 -> reported listeners
// 5 -> bitrate
// 6 -> song

Parse these information.... very simple...
You may also interested to run this in a loop like the http audio stream.

Please let me know if you have any other better idea ?

salahuddin66 said...

The full URL is:
http://www.sluniverse.com/php/vb/scripting/32062-script-read-song-information-stream.html

lake said...

hai salahdin,

i am new to iphone development. plz put some code here ......!!!

lake said...

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:myURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];

[[NSURLConnection alloc] initWithRequest:request delegate:self];

i use this code for grabbing site contents but it jzt returns null value from the url http://launch.fusionchicago.com:8004/

plz giv me a nice answer.....

Tim said...

Does anyone know latency one should expect with this method of audio transfer?

I need the absolute lowest latency possible in my application and secondly need the ability to switch streams quickly as the user changes channels.

salahuddin66 said...

for lower latency, simply change the following in iRadioAudioExampleViewController.m


#define kNumAQBufs 3 // number of audio queue buffers we allocate
#define kAQBufSize 128*1024 // number of bytes in each audio queue buffer
#define kAQMaxPacketDescs 512 // number of packet descriptions in our array

DIGITAL LIFE said...

Hi Salahuddin do you have any updated example for the latest sdk? Would truly love to see this updated, there are tons of us looking for something like this on the apple forums. If you update this I can link to your site and send you all of them as traffic..we desperately need help and you seem like the only one genuinely offering actual useful information and you would certainly benefit from the huge traffic an update would produce.

mamaz said...

Hi,
Your work is brilliant. I've modified your code and integrate it to our app. Thank you so much for the tutorial.
God bless you, Mate
-mamaz

mamaz said...

Hi,
Your work is brilliant!! I have modified and integrate your code to our app.
God bless you mate.

-mamaz

sandeep said...

Hello,
Thanks for this wonderful post. Have you tried recording audio?
Thanks

salahuddin66 said...

!!! Updated version for Xcode 4.2 !!!

Check http://www.mymacbd.com/forum/post572.html#p572