我正在制作一个可播放音频的应用程序,并且已对其进行设置,以便通过MPNowPlayingInfoCenter更新锁定屏幕,但是我遇到了问题。

在看似随机的时间,尝试更新正在播放的信息时出现EXC_BAD_ACCESS错误。

这是执行此操作的代码:

- (void)updatePlayback
{
    if(!active)
        return;

    NowPlayingController* npc = [AudioController nowPlayingController];
    CMTime elapsed = player.currentTime;
    Float64 elInterval = CMTimeGetSeconds(elapsed);
    [npc setElapsed:elInterval];

    CMTime duration = player.currentItem.duration;
    Float64 durInterval = CMTimeGetSeconds(duration);
    [npc setRemaining:ceilf(durInterval - elInterval)];

    [npc setPlayPauseValue:isPlaying];
    if(durInterval > 0)
    {
        [npc setProgressValue:elInterval/durInterval];
        [npc setAudioDuration:durInterval];
    }

    _activeMetadata[MPMediaItemPropertyPlaybackDuration] = @(durInterval);
    _activeMetadata[MPNowPlayingInfoPropertyPlaybackRate] = @(isPlaying);
    _activeMetadata[MPNowPlayingInfoPropertyElapsedPlaybackTime] = @(elInterval);

    MPNowPlayingInfoCenter* npInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
    if(npInfoCenter && _activeMetadata)
    {
        if([npInfoCenter respondsToSelector:@selector(setNowPlayingInfo:)])
        {

//////////THE FOLLOWING LINE TRIGGERS EXC_BAD_ACCESS SOMETIMES////////////
            [npInfoCenter setNowPlayingInfo:_activeMetadata];
        }

    }
}

99.9%的时间有效,但是有时在将应用程序重新分配到后台或更改音频文件时,或者只是随机地,
[npInfoCenter setNowPlayingInfo:_activeMetadata];

抛出EXC_BAD_ACCESS

另外,_activeMetadata声明为:
@property (atomic, strong, retain) NSMutableDictionary* activeMetadata;

创建AVPlayer时将实例化它:
    AVAsset* asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:path]];
    AVPlayerItem* playerItem = [AVPlayerItem playerItemWithAsset:asset];
    player = [AVPlayer playerWithPlayerItem:playerItem];

    CMTime duration = player.currentItem.duration;
    NSTimeInterval durInterval = CMTimeGetSeconds(duration);
    NSLog(@"%f", durInterval);

    MPMediaItemArtwork* albumArtwork = [[MPMediaItemArtwork alloc] initWithImage:[downloader useCachedImage:CacheKeySeriesBanners withName:nil withURL:info[@"image"]]];
    NSDictionary* nowPlayingInfo = @{MPMediaItemPropertyTitle:ptString,
                                     MPMediaItemPropertyArtist:spString,
                                     MPMediaItemPropertyArtwork:albumArtwork,
                                     MPMediaItemPropertyAlbumTitle:info[@"title"],
                                     MPMediaItemPropertyPlaybackDuration:@(durInterval),
                                     MPNowPlayingInfoPropertyPlaybackRate:@(1),
                                     MPNowPlayingInfoPropertyElapsedPlaybackTime:@(0)};
    [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:nowPlayingInfo];

    _activeMetadata = [nowPlayingInfo mutableCopy];

通过CADisplayLink在每帧上调用updatePlayback

有什么想法可能导致异常吗?

最佳答案

我认为您经常调用setNowPlayingInfo。当然,它确实不会崩溃,但无需使用CADisplayLink每秒调用60次。

那你为什么这么频繁地打电话呢?如果是因为您希望进度条能够流畅地跟踪,则仍然没有必要。从MPNowPlayingInfoPropertyElapsedPlaybackTime声明中:

// The elapsed time of the now playing item, in seconds.
// Note the elapsed time will be automatically extrapolated from the previously
// provided elapsed time and playback rate, so updating this property frequently
// is not required (or recommended.)

ps。我使用m4a文件尝试了该代码,发现durInterval是NotANumber。使用正确的持续时间并仅调用一次setNowPlayingInfo,进度条就可以正常跟踪且没有崩溃。

关于ios - MPNowPlayingInfoCenter抛出EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39555416/

10-09 02:21