ios - AVPlayer/AVAudioMix fade-in effect clicks in the beginning -
i'm trying implement fade-in effect based on avplayer + avaudiomix + avaudiomixinputparameters. works except when playing audio first time after starting app there click in beginning. subsequent plays work perfect though, first-time glitch pretty stable , reproducible.
my play button enabled after avplayeritem's status
set ready, it's impossible fire play method while player not ready. in fact doesn't matter how long wait after loading audio file , constructing objects.
this happens on os x, haven't tested on ios (yet).
note test need audio file starts sound , not silence. here stripped down code without gui part (testfadein
entry point):
static avplayer* player; static void* playeritemstatusobservercontext = &playeritemstatusobservercontext; - (void)testfadein { avurlasset* asset = [avurlasset.alloc initwithurl:[nsurl fileurlwithpath:@"helicopter.m4a"] options:@{avurlassetpreferprecisedurationandtimingkey: @yes}]; avplayeritem* item = [avplayeritem playeritemwithasset:asset]; player = [avplayer playerwithplayeritem:item]; [item addobserver:self forkeypath:@"status" options:nskeyvalueobservingoptioninitial | nskeyvalueobservingoptionnew context:playeritemstatusobservercontext]; } - (void)observevalueforkeypath:(nsstring*)keypath ofobject:(id)object change:(nsdictionary*)change context:(void*)context { if (context == playeritemstatusobservercontext) { avplayerstatus status = (avplayerstatus)[[change objectforkey:nskeyvaluechangenewkey] integervalue]; if (status == avplayerstatusreadytoplay) { [self applyfadein]; [self performselector:@selector(play:) withobject:nil afterdelay:1.0]; } } } - (void)applyfadein { assert(player.currentitem.tracks.firstobject); avmutableaudiomixinputparameters* fadein = [avmutableaudiomixinputparameters audiomixinputparameterswithtrack:player.currentitem.tracks.firstobject]; [fadein setvolume:0 attime:kcmtimezero]; [fadein setvolume:1 attime:cmtimemake(2, 1)]; nsmutablearray* paramsarray = [nsmutablearray new]; [paramsarray addobject:fadein]; avmutableaudiomix* audiomix = [avmutableaudiomix audiomix]; audiomix.inputparameters = paramsarray; player.currentitem.audiomix = audiomix; } - (void)play:(id)unused { [player play]; }
click! wrong this?
edit:
an obvious workaround use @ moment is: when player reports it's ready, short 100ms playback volume=0, restore currenttime , volume , report main app player ready. way there no clicks. interestingly, less 100ms still gives click.
this seems issue that's being cached avfoundation after first playback. it's neither tracks, available when set fade in params, nor seek status.
Comments
Post a Comment