Извлечение / запись аудио из потока HLS (видео) во время игры на iOS

Я играю потоки HLS, используя AVPlayer. И мне также нужно записывать эти потоки, когда пользователь нажимает кнопку записи. Подход, который я использую, заключается в том, чтобы записывать аудио и видео отдельно, а затем в конце объединить эти файлы, чтобы сделать окончательное видео. И это успешно с удаленными файлами mp4.

Но теперь для файлов HLS (.m3u8) я могу записывать видео с помощью AVAssetWriter, но возникают проблемы с записью звука.

Я использую MTAudioProccessingTap для обработки необработанных аудиоданных и записи их в файл. Я последовал заэтот статья. Я могу записать удаленный MP4 аудио, но он не работает с потоками HLS. Первоначально я не мог извлечь аудиодорожки из потока, используя AVAssetTrack * audioTrack = [asset trackWithMediaType: AVMediaTypeAudio] [0];

Но я смог извлечь audioTracks, используя KVO для инициализации 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!");
                        }

                }];


    }
}  

Я также отслеживаю trackID, чтобы проверить, изменился ли трек.

Вот как я инициализирую 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;
}

Но теперь с этой звуковой дорожкой MTAudioProcessingTap обратные вызовы «Подготовка» и «Обработка» никогда не вызываются.

Проблема с audioTrack, который я получаю через KVO?

Теперь я был бы очень признателен, если бы кто-нибудь мне помог с этим. Или можете сказать, я использую подход записи для записи потоков HLS?

Ответы на вопрос(2)

Ваш ответ на вопрос