Extraiga / grabe audio de la transmisión HLS (video) mientras reproduce iOS

Estoy reproduciendo transmisiones HLS usando AVPlayer. Y también necesito grabar estas transmisiones cuando el usuario presiona el botón de grabación. El enfoque que estoy usando es grabar audio y video por separado y luego, al final, fusionar estos archivos para hacer el video final. Y tiene éxito con archivos mp4 remotos.

Pero ahora para los archivos HLS (.m3u8) puedo grabar el video usando AVAssetWriter pero tengo problemas con la grabación de audio.

Estoy usando MTAudioProccessingTap para procesar los datos de audio sin formato y escribirlos en un archivo. Seguíesta artículo. Puedo grabar audio mp4 remoto pero no funciona con transmisiones HLS. Inicialmente no pude extraer las pistas de audio de la transmisión usando AVAssetTrack * audioTrack = [activo tracksWithMediaType: AVMediaTypeAudio] [0];

Pero pude extraer las pistas de audio usando KVO para inicializar el MTAudioProcessingTap.

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
AVPlayer *player = (AVPlayer*) object;

if (player.status == AVPlayerStatusReadyToPlay)
{
    NSLog(@"Ready to play");
    self.previousAudioTrackID = 0;


        __weak typeof (self) weakself = self;

        timeObserverForTrack = [player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, 100) queue:nil usingBlock:^(CMTime time)
                {

                    @try {

                            for(AVPlayerItemTrack* track in [weakself.avPlayer.currentItem tracks]) {
                                if([track.assetTrack.mediaType isEqualToString:AVMediaTypeAudio])
                                    weakself.currentAudioPlayerItemTrack = track;

                            }

                            AVAssetTrack* audioAssetTrack = weakself.currentAudioPlayerItemTrack.assetTrack;


                            weakself.currentAudioTrackID = audioAssetTrack.trackID;

                            if(weakself.previousAudioTrackID != weakself.currentAudioTrackID) {

                                NSLog(@":::::::::::::::::::::::::: Audio track changed : %d",weakself.currentAudioTrackID);
                                weakself.previousAudioTrackID = weakself.currentAudioTrackID;
                                weakself.audioTrack = audioAssetTrack;
                                /// Use this audio track to initialize MTAudioProcessingTap
                            }
                        }
                        @catch (NSException *exception) {
                            NSLog(@"Exception Trap ::::: Audio tracks not found!");
                        }

                }];


    }
}  

También estoy haciendo un seguimiento de trackID para verificar si la pista ha cambiado.

Así es como inicializo el MTAudioProcessingTap.

-(void)beginRecordingAudioFromTrack:(AVAssetTrack *)audioTrack{
// Configure an MTAudioProcessingTap to handle things.
MTAudioProcessingTapRef tap;
MTAudioProcessingTapCallbacks callbacks;
callbacks.version = kMTAudioProcessingTapCallbacksVersion_0;
callbacks.clientInfo = (__bridge void *)(self);
callbacks.init = init;
callbacks.prepare = prepare;
callbacks.process = process;
callbacks.unprepare = unprepare;
callbacks.finalize = finalize;

OSStatus err = MTAudioProcessingTapCreate(
    kCFAllocatorDefault, 
    &callbacks, 
    kMTAudioProcessingTapCreationFlag_PostEffects, 
    &tap
);

if(err) {
    NSLog(@"Unable to create the Audio Processing Tap %d", (int)err);
    NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain
                                         code:err
                                     userInfo:nil];
    NSLog(@"Error: %@", [error description]);;
    return;
}

// Create an AudioMix and assign it to our currently playing "item", which
// is just the stream itself.


AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
AVMutableAudioMixInputParameters *inputParams = [AVMutableAudioMixInputParameters
    audioMixInputParametersWithTrack:audioTrack];

inputParams.audioTapProcessor = tap;
audioMix.inputParameters = @[inputParams];
_audioPlayer.currentItem.audioMix = audioMix;
}

Pero ahora con esta pista de audio MTAudioProcessingTap las devoluciones de llamada "Preparar" y "Procesar" nunca se llaman.

¿Es el problema con el audioTrack que estoy recibiendo a través de KVO?

Ahora realmente agradecería si alguien me puede ayudar con esto. ¿O puedo decir si estoy usando el enfoque de escritura para grabar HLS Streams?

Respuestas a la pregunta(2)

Su respuesta a la pregunta