Extrait/Enregistrer de l'Audio à partir de HLS flux (vidéo) lors de la lecture iOS

Je joue les flux HLS à l'aide de AVPlayer. Et j'ai aussi besoin d'enregistrer ces flux utilisateur appuie sur le bouton d'enregistrement.
L'approche que j'utilise est d'enregistrer audio et vidéo séparément, puis à la fin de fusionner ces fichiers pour faire de la vidéo finale. Et C'est réussi avec les distance les fichiers mp4.

Mais maintenant, pour la HLS (.m3u8) les fichiers que je suis capable d'enregistrer la vidéo à l'aide de AVAssetWriter, mais ayant des problèmes avec l'enregistrement audio.

Je suis en utilisant MTAudioProccessingTap pour traiter les raw des données audio et de les écrire dans un fichier. J'ai suivi cette article. Je suis capable d'enregistrer à distance mp4 audio, mais sa ne fonctionne pas avec les flux HLS.
Au départ, je n'étais pas capable d'extraire les pistes audio à partir du flux à l'aide de AVAssetTrack *audioTrack = [actif tracksWithMediaType:AVMediaTypeAudio][0];

Mais j'ai réussi à extraire le audioTracks à l'aide de KVO pour initialiser le 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!");
                        }

                }];


    }
}  

Je suis également garder la trace de trackID pour vérifier si la piste est changé.

C'est comment j'ai initialiser le 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;
}

Mais Maintenant, avec cette piste audio MTAudioProcessingTap rappels de "Préparer" et "Processus" ne sont jamais appelés.

Est le problème avec le audioTrack je suis passer à travers KVO?

Maintenant je serais vraiment reconnaissant si quelqu'un peut m'aider avec cela. Ou peut dire suis-je à l'aide de l'écriture approche pour enregistrer les Flux HLS?

Avez-vous réussi à créer un fichier mp4 à l'aide de fichier m3u8 ?
J'ai posté la bonne réponse. veuillez vérifier.
Merci beaucoup Sajad.
u peut partager un code pour l'enregistrement en direct et en streaming svp

OriginalL'auteur Sajad Khan | 2015-07-29