Saturday 15 February 2014

cocoa touch - iOS 8 stops streaming audio in background after 10 minutes -



cocoa touch - iOS 8 stops streaming audio in background after 10 minutes -

i have app plays streaming sound shoutcast server. works fine when app on foreground , auto-lock disabled. app able play sound in background, feature has been working fine on ios 6 , ios 7. users reporting background sound stops after 10 minutes after upgraded ios 8.

i'm able reproduce problem myself running app on ios 8. since app pretty complicated, i've made simple demo show problem. i'm using xcode 6 , base of operations sdk set ios 8. i've added audio uibackgroundmodes in info.plist. know what's wrong code below?

- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions { nsurl *streamingurl = [nsurl urlwithstring:@"http://www.radiofmgold.be/stream.php?ext=pls"]; avplayeritem *playeritem = [avplayeritem playeritemwithurl:streamingurl]; [self setplayeritem:playeritem]; avplayer *player = [avplayer playerwithplayeritem:playeritem]; [player setallowsexternalplayback:no]; [self setplayer:player]; [player play]; [[avaudiosession sharedinstance] setcategory:avaudiosessioncategoryplayback error:nil]; [[avaudiosession sharedinstance] setactive: yes error: nil]; homecoming yes; }

i experienced same problem under ios 8.0.2. remote sound source plays in mp3. seems internal error causing avaudiosession restart. can handle in different ways:

you can observe state of avplayeritem.

void* youraudiocontrolleritemstatuscontext = "youraudiocontrolleritemstatuscontext"; ... @implementation youraudiocontroller ... - (void)playstream { ... avplayeritem *item = [[avplayeritem alloc] initwithurl:streamurl]; [item addobserver:self forkeypath:@"status" options:0 context:mjaudiocontrolleritemstatuscontext]; } - (void)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary *)change context:(void *)context { if (context == youraudiocontrolleritemstatuscontext) { avplayeritem *item = object; if (item.status == avplayeritemstatusfailed) { [self recoverfromerror]; } }

this way seems not reliable since there can immense time delay until state of avplayeritem changes - if changes @ all.

i debugged through observevalueforkeypath , found out state of avplayeritem changes averrormediaserviceswerereset , has error code -11819 set.

since experienced averrormediaserviceswerereset error researched causes error - it's avaudiosession going crazy. referring technical q&a apple should register avaudiosessionmediaserviceswereresetnotifications. set somewhere in code:

[[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(audiosessionwasreset:) name:avaudiosessionmediaserviceswereresetnotification object:nil];

then add together method:

- (void)audiosessionwasreset:(nsnotification *)notification { [self recoverfromerror]; }

in recoverfromerror method seek 1 of following:

show alert describes theres problem under ios 8 , stream needs restarted restart stream setting avaudiosession active 1 time again , instantiate new avplayer instance new avplayeritem

at moment ways know how handle it. question why audiosession getting restarted.

update release of ios 8.1 seams have solved issue.

ios cocoa-touch audio ios8 avfoundation

No comments:

Post a Comment