4

当我在播放之前获取音频文件的持续时间时:

audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
...
[audioPlayer prepareToPlay];
duration = audioPlayer.duration;

例如,我得到的持续时间为 16.71 秒。然后在播放时每 0.2 秒采样一次,持续时间会发生变化。它每 1.2 到 1.6 秒更改为:16.71 秒、17.02 秒、17.23 秒、17.33 秒、17.38 秒、17.43 秒、17.38 秒、17.29 秒、17.31 秒,然后在最后 2.5 秒内保持在 17.51 秒。所以它会上升和下降。

我以一种更新滑块位置的方法进行采样,并显示经过的时间和总持续时间。您可以想象,在播放时看到持续时间(被 int 截断)从 16 变为 17 看起来真的很奇怪。此外,滑块位置将随着所有这些漂移而关闭。

有谁知道这是为什么?

现在我们正在讨论持续时间:有谁知道为什么在省略audio player.duration时可以返回大约是实际持续时间两倍的值?[audioPlayer prepareToPlay]

4

2 回答 2

6

avaudioplayer 的 duration 方法返回的持续时间是根据到目前为止已解码文件的多少来对文件总持续时间的最佳估计。这就是为什么随着时间的推移检查持续时间会不断完善的原因。

为了获得更好的时间,我使用了 AVAsset 的 duration 方法。它更好地解释了这里发生的事情:

https://developer.apple.com/library/mac/documentation/AVFoundation/Reference/AVAsset_Class/Reference/Reference.html#//apple_ref/occ/instp/AVAsset/duration

如果您指定 providersPreciseDurationAndTiming = YES,则 AVAsset 将在需要时对文件进行解码以确定其持续时间的准确性。如果解码时间对您来说太长,您可以禁用它。

在我的情况下,我使用 AVURLAsset 子类:

            AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:localURL options:[NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], AVURLAssetPreferPreciseDurationAndTimingKey, nil]];
            float t = CMTimeGetSeconds(asset.duration);
于 2014-07-14T15:37:24.347 回答
1

@AndyKorth 的回答是最好的!这是在斯威夫特

guard let audioPlayer = audioPlayer, let url = audioPlayer.url else { return }

let assetOpts = [AVURLAssetPreferPreciseDurationAndTimingKey: true]
let asset = AVURLAsset(url: url, options: assetOpts)

let assetDuration: Float64 = CMTimeGetSeconds(asset.duration)

// compare both
print("assetDuration: ", assetDuration)

print("audioPlayerDuration: ", Float(audioPlayer.duration))
于 2021-12-04T11:08:57.450 回答