Thursday, June 24, 2010

RadioKit SDK demo project now includes support for iOS 4 background audio play

I've update the RadioKit SDK demo XCode project so it now also demonstrates how to perform background audio play and audio control under iOS 4.

Source code for the sample project can be found here:

http://stormyprods.com/products/radiokit.php

The key point to adding support for background audio play under iOS 4 is to add a new entry to your app's info.plist file. You must add a new key called UIBackgroundModes and add the value audio.

If you want you app to also support remote control of the background audio (either via headphone controls or the audio controls on the background app taskbar) you must also add support for remoteControlReceivedWithEvent:. You can see how this was done in the sample MainViewController.m file in the RadioKitDemo XCode project.

Please note: background play is not supported under the simulator. This is a limitation with the simulator, not the sample XCode project.

If you are unfamiliar with the RadioKit SDK, you can read more about it here. It is a static library which greatly simplifies the process of handling streaming audio on the iPhone and iPad including support for pause, rewind and fast forward of the live audio stream. It is licensed on a per-project basis with single project licenses priced at $100 (US dollars). There are no royalty fees. Volume discount pricing is also available.

17 comments:

Clinton said...

I am sure you are working hard on it, but I would sure *love* to see your radio apps (I am a Radio Paradise fan, myself) updated to support backgrounding on iOS 4.

Keep up the great work!

Best wishes,
Clint

Mostly Torn said...

Tunemark Radio has already been updated. Radio Paradise is under review with Apple right now and should been approved in the next week or so.

Ash said...

Hi, I'm interested in using RadioKit, but there's a bug (or possible feature request). When audio is put into the background on iOS 4, it plays until an interruption (such as a phone call). However, after the interruption ends, the audio doesn't automatically resume playing. Would this be easy for you to fix?

Mostly Torn said...

Hi Ash,

I've spent a lot of time on this one.

Unfortunately, there is no way to have the app automatically resume play after taking a phone call. There is no notification sent to the app when the call is ended, and since the app was interrupted and was no longer playing audio, per Apple's policy, it has been suspended.

The Pandora app behaves the same way.

The app will automatically recover if the call is declined, as Apple does send a notification in such a case, but if the call is accepted, then it will stop playing.

Until Apple provides a notification for background apps when they can resume, there is nothing to be done to handle such a case.

Currently, it is up to the user to double-tap the home button and resume the audio play by hand.

Mostly Torn said...

Also, I think this might be intentional behavior by Apple.

If your app is interrupted by a phone call, you might be traveling from one location to another during your call, and you might not want an audio app that was suspended X minutes ago to automatically start playing again.

Ash said...

Hi Mostly Torn!
(Sorry I don't know your real name...)

Thank you for replying so quickly.

The NPR app is one example where the audio resumes playing when interrupted in the background (or foreground), as does the built in iPod app.

However, this problem manifests itself further.. even if RadioKit remains in the foreground, an audio interruption like an answered phonecall, the library doesn't restart the audio that was playing.

I've been looking at some other examples; one that is pretty common is that users are disposing of the existing AudioQueue when the kAudioSessionBeginInterruption is received (and they are storing state (position in a mp3 for example)

On the end of an interruption when the kAudioSessionEndInterruption is received in the callback handler, they are recreating the stream (or in the case of a mp3, starting playback at the previous position).

I'm not convinced that's the nicest way to do things; as there might be a way to suspend the audioqueue; but I just don't know enough about this stuff to be certain.

Anyway, I'm stlll looking for a solution. If you can implement something cleanly, we would gladly use your library.

All the best

Mostly Torn said...

Hi Ash,

There are some events that are handled by the application, not the RadioKit SDK, in order to handle audio interruptions.

With iOS 4, when an app is in the foreground and gets interrupted, the app is put in the background. Because of this, I leave it up to the app to handle the background notification event.

I had considered adding the event monitoring to the RadioKit SDK, however it seems to be a case where some designs might want the audio to be restarted and some designs might now.

It's easy enough to handle in the app background handling logic. When the app receives the notification, you just restart the RadioKit playback.

I could add it as an optional handler in the RadioKit (which can be turned on via a property) if it is something you would find helpful to have encapsulated within the RadioKit.

I'm curious how the NPR app automatically resumes hen it is in the background. I had done a lot of testing looking for different notifications and best I could tell there never was one sent to the app when the phone call finally ended. I had been looking for the background task notifications as well as the kAudioSessionEndInterruption and neither of those events occurred.

The must be some other event I'm not aware of, since obviously it is possible since that app is doing it.

Surprisingly, while the NPR app does handle that situation properly, they didn't implement support for the iPod audio controls while in the background.


(My name is Brian, by the way - it's listed on the right sidebar of the blog. If you need to email me directly, you can do so via the "contact us" link at the top of the page.)

Cheers,
Brian

Mostly Torn said...

Woops! Regarding the contact link - it's on the top of the stormyprods.com web page, not this blog.

Mostly Torn said...

I've found a work-around to the notifications not being received when in the background. I've updated the RadioKit SDK with improved code.

Swapnil Shinde said...

Hi Mostly,

Does your SDK support interactive streaming as well? I would like to explore if this can be used for an interactive streaming app (eg: Rhapsody or imeem) rather than a radio app like Pandora.

Please let me know

Anonymous said...

Is this project still supported? I've emailed twice over the past 8 days and thus far received no response.

Mostly Torn said...

Dear Anonymous,

Yes, this project is still very active.

What is your question? I generally respond to all RadioKit questions within a day. Perhaps my spam filter blocked the email.

Best regards,
Brian

Steve McL said...

Hi. I wanted to know a couple things:

1) What types of servers for on-demand streaming is supported?
2) With on-demand streams (MP3s), can someone "bookmark" a point/time in the stream so they can come back later and resume from that point? I have longer-form content which would require this.
3) Do you do custom apps on a work-for-hire basis?

Mostly Torn said...

Hello Steve,

Here are the answers to your questions:

1) For on demand streaming, any server which supports the HTTP range command should work. Using the range command will allow the SDK to query the audio file at arbitrary offsets.

2) As for bookmarking the streams and resuming, that is possible, but it would be more of a feature handled by your own app's custom code - not something handled directly by the RadioKit SDK.

3) Yes, I do custom app development. I've sent you an email separately with pricing information.

Anonymous said...

Brian,

I am also up against the problem of no kAudioSessionEndInterruption when app is in the background. I saw your earlier post "I've found a work-around to the notifications not being received when in the background. I've updated the RadioKit SDK with improved code.".

Must I switch from an interrupt listener to a AVAudioSessionDelegate and implement endInterruptionWithFlags (I suspect this also will not be called)?

Care to share your workaround?

Thanks,
Owen

Mostly Torn said...

Hi Owen,

The workaround I did was to call beginBackgroundTaskWithExpirationHandler: when the application was interrupted and then endBackgroundTask: on resume. If you do this, then the audio session end interruption is called.

The limitation is if the interruption lasts more than 10 minutes, then your background task will be ended and you won't be notified when the interruption ends.

Brian

Anonymous said...

Love your work! Thanks for prompt reply.

Owen


All content copyright © 2009  Brian Stormont, unless otherwise noted.   All rights reserved.