在ios上解码hls流中的音频样本?

在ios上解码hls流中的音频样本?,ios,m3u8,http-live-streaming,Ios,M3u8,Http Live Streaming,我试图在iOS设备上解码来自远程HLS(m3u8)流的音频样本,以便进一步处理数据,例如记录到文件中。 作为参考流使用 通过使用AVURLAsset和AVPlayer,我可以在CALayer上预览视频。 我还可以使用AVPlayerItemVideoOutput获得原始视频数据(CVPixelBuffer)。通过iOS设备的扬声器也可以听到音频 这是我目前正在为AVURLAsset和AVPlayer使用的代码: NSURL* url = [NSURL URLWithString:@"http:/

我试图在iOS设备上解码来自远程HLS(m3u8)流的音频样本,以便进一步处理数据,例如记录到文件中。 作为参考流使用

通过使用AVURLAsset和AVPlayer,我可以在CALayer上预览视频。 我还可以使用AVPlayerItemVideoOutput获得原始视频数据(CVPixelBuffer)。通过iOS设备的扬声器也可以听到音频

这是我目前正在为AVURLAsset和AVPlayer使用的代码:

NSURL* url = [NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
NSString *tracksKey = @"tracks";

[asset loadValuesAsynchronouslyForKeys:@[tracksKey] completionHandler: ^{

    dispatch_async(dispatch_get_main_queue(), ^{

        NSError* error = nil;
        AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error];

        if (status == AVKeyValueStatusLoaded) {
            NSDictionary *settings = @
            {
                (id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA),
                @"IOSurfaceOpenGLESTextureCompatibility": @YES,
                @"IOSurfaceOpenGLESFBOCompatibility": @YES,
            };
            AVPlayerItemVideoOutput* output = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:settings];
            AVPlayerItem* playerItem = [AVPlayerItem playerItemWithAsset:asset];
            [playerItem addOutput:output];
            AVPlayer* player = [AVPlayer playerWithPlayerItem:playerItem];
            [player setVolume: 0.0];    // no preview audio
            self.playerItem = playerItem;
            self.player = player;
            self.playerItemVideoOutput = output;

            AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer: player];
            [self.preview.layer addSublayer: playerLayer];
            [playerLayer setFrame: self.preview.bounds];
            [playerLayer setVideoGravity: AVLayerVideoGravityResizeAspectFill];

            [self setPlayerLayer: playerLayer];

            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemNewAccessLogEntry:) name:AVPlayerItemNewAccessLogEntryNotification object:self.playerItem];

            [_player addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:&PlayerStatusContext];
            [_playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:&PlayerItemStatusContext];
            [_playerItem addObserver:self forKeyPath:@"tracks" options:0 context:nil];
        }
    });
}];

-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (self.player.status == AVPlayerStatusReadyToPlay && context == &PlayerStatusContext) {
        [self.player play];
    }
}
要获取HLS流的原始视频数据,我使用:

CVPixelBufferRef buffer = [self.playerItemVideoOutput copyPixelBufferForItemTime:self.playerItem.currentTime itemTimeForDisplay:nil];

if (!buffer) {
    return;
}
CMSampleBufferRef newSampleBuffer = NULL;
CMSampleTimingInfo timingInfo = kCMTimingInfoInvalid;
timingInfo.duration = CMTimeMake(33, 1000);
int64_t ts = timestamp * 1000.0;
timingInfo.decodeTimeStamp = CMTimeMake(ts, 1000);
timingInfo.presentationTimeStamp = timingInfo.decodeTimeStamp;

CMVideoFormatDescriptionRef videoInfo = NULL;
CMVideoFormatDescriptionCreateForImageBuffer(
                                                 NULL, buffer, &videoInfo);
CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault,
                                       buffer,
                                       true,
                                       NULL,
                                       NULL,
                                       videoInfo,
                                       &timingInfo,
                                       &newSampleBuffer);

// do something here with sample buffer...

CFRelease(buffer);
CFRelease(newSampleBuffer);
现在我也想访问原始音频数据,但到目前为止运气不佳。 我尝试使用MTAudioProcessingTap,如下所述:

不幸的是,我无法让它正常工作。我成功访问了AVPlayerItem的底层assetTrack,但从未调用MTAudioProcessingTap的回调方法“prepare”和“process”。我不确定我是否走对了这条路

AVPlayer通过扬声器播放流的音频,因此在内部音频似乎可以作为原始音频数据使用。是否可以访问原始音频数据?如果AVPlayer无法实现,是否有其他方法


如果可能的话,我不想使用ffmpeg,因为iOS设备的硬件解码器应该用于流的解码。

您好,欢迎使用Stack Overflow。为了帮助您,我们需要您向我们提供更多信息(例如解决方案的外观,以及您编写的任何相关代码),并与我们分享您在该主题上已经完成的研究(因此我们不会重复您的工作)。我们确实希望您自己设计和编写此文件(我们不会为您完成工作),因此希望您在来寻求我们的帮助之前,至少尝试过使其正常工作。谢谢您的指点。我添加了更详细的描述。你解决了这个问题吗?