objective c - Cannot Control Volume of AVAudioPlayer via Hardware Buttons when AudioSessionActive is NO -


i'm building turn-by-turn navigation app plays periodic, short clips of sound. sound should play regardless of whether screen locked, should mix other music playing, , should make other music duck when audio plays.

apple discusses turn-by-turn use case in detail in "wwdc 2010 session 412 audio development iphone os part 1" video @ minute 29:20. implementation works great, there 1 problem - when app running, pressing hardware volume controls adjust ringer volume, not app volume. if want change app volume, must press volume buttons while prompt playing.

apple specific in video shouldn't leave avaudiosession active, if avaudiosession inactive, volume buttons won't control volume of app.

here code i'm using set things up:

uint32 sessioncategory = kaudiosessioncategory_mediaplayback; propertyseterror = audiosessionsetproperty(kaudiosessionproperty_audiocategory, sizeof(sessioncategory), &sessioncategory);  uint32 allowmixing = true; propertyseterror = audiosessionsetproperty(kaudiosessionproperty_overridecategorymixwithothers, sizeof(allowmixing), &allowmixing);  uint32 shouldduck = true; propertyseterror = audiosessionsetproperty(kaudiosessionproperty_othermixableaudioshouldduck, sizeof(shouldduck), &shouldduck);  osstatus activationresult = audiosessionsetactive(true);  nserror* err = nil; _player = [[avaudioplayer alloc] initwithdata:audiodata error:&err]; _player.delegate = self; [_player play]; 

and set session active no @ end, apple recommends:

osstatus activationresult = audiosessionsetactive(false); nsassert(activationresult == kaudiosessionnoerror, @"error deactivating audio session"); 

is there i'm missing, or have go against recommended in video?

in case, don't want set audio session inactive. need use 2 methods, 1 set session playing sound, , other set being idle. first method sets mix+duck audio mode, , second uses background-audio-friendly mode ambient.

something this:

- (void)setactive {     uint32 mix  = 1;     uint32 duck = 1;     nserror* errret;      avaudiosession* session = [avaudiosession sharedinstance];     [session setactive:no error:&errret];      [session setcategory:avaudiosessioncategoryplayback error:&errret];     nsassert(errret == nil, @"setcategory!");      audiosessionsetproperty(kaudiosessionproperty_overridecategorymixwithothers, sizeof(mix), &mix);     audiosessionsetproperty(kaudiosessionproperty_othermixableaudioshouldduck, sizeof(duck), &duck);      [session setactive:yes error:&errret]; }  - (void)setidle {     nserror* errret;      avaudiosession* session = [avaudiosession sharedinstance];     [session setactive:no error:&errret];      [session setcategory:avaudiosessioncategoryambient error:&errret];     nsassert(errret == nil, @"setcategory!");      [session setactive:yes error:&errret]; } 

then call it:

[self setactive]; [self _playaudio:nil]; 

to clean after playing:

- (void)audioplayerdidfinishplaying:(avaudioplayer*)player                    successfully:(bool)flag { [self setidle]; 

}

to citizen, app should set audio session inactive when isn't navigating (i.e., performing main function), when is, there absolutely nothing wrong keeping audio session active , using modes peacefully coexist other apps. can duplicate apple's navigation app functionality using code above.


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -