Extrair / gravar áudio do fluxo HLS (vídeo) durante a reprodução do iOS

Estou reproduzindo fluxos HLS usando o AVPlayer. E também preciso gravar esses fluxos à medida que o usuário pressiona o botão de gravação. A abordagem que estou usando é gravar áudio e vídeo separadamente e, no final, mesclar esses arquivos para criar o vídeo final. E é bem sucedido com arquivos mp4 remotos.

Mas agora, para os arquivos HLS (.m3u8), eu posso gravar o vídeo usando o AVAssetWriter, mas tendo problemas com a gravação de áudio.

Estou usando o MTAudioProccessingTap para processar os dados de áudio brutos e gravá-los em um arquivo. eu seguiesta artigo. Eu sou capaz de gravar áudio mp4 remoto, mas não está funcionando com fluxos HLS. Inicialmente, não consegui extrair as faixas de áudio do fluxo usando AVAssetTrack * audioTrack = [asset tracksWithMediaType: AVMediaTypeAudio] [0];

Mas consegui extrair os audioTracks usando o KVO para inicializar o 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!");
                        }

                }];


    }
}  

Também acompanho o trackID para verificar se o track foi alterado.

É assim que eu inicializo o 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;
}

Mas agora, com esta faixa de áudio, os retornos de chamada MTAudioProcessingTap "Prepare" e "Process" nunca são chamados.

O problema com o audioTrack que estou recebendo pelo KVO?

Agora eu realmente aprecio se alguém puder me ajudar com isso. Ou posso dizer que estou usando a abordagem de gravação para gravar fluxos HLS?

questionAnswers(2)

yourAnswerToTheQuestion