在iOS上循环播放音频一段时间

时间:2018-10-19 09:34:19

标签: ios avplayer avaudioplayer avplayerlooper

我想知道在iOS上定义时间段内循环音频的最佳解决方案是什么。 我目前在玩

  • AVAudioPlayer(我可以在其中定义重复计数,但不能定义结束时间)
  • AVPlayer(在这里我可以定义forwardPlaybackEndTime机器人,而不是循环计数)
  • AVPlayerLooper(我尚未完全理解)

因此,我需要定义一个重复某些声音文件的持续时间。 F.e.我有一个8秒的mp3,想播放一分钟。

如果我能再次淡入淡出,suuuuper也会很棒。

1 个答案:

答案 0 :(得分:2)

使用AVPlayerLooper使您处在正确的轨道上。

这是设置AVPlayerLooper

的方式
var playerLooper: AVPlayerLooper!
var player: AVQueuePlayer!

func play(_ url: URL) {
    let asset = AVAsset(url: url)
    let playerItem = AVPlayerItem(asset: asset)

    player = AVQueuePlayer(playerItem: playerItem)
    playerLooper = AVPlayerLooper(player: player, templateItem: playerItem)

    player.play()
}

要在设置的时间后停止循环,可以使用addBoundaryTimeObserver(forTimes:queue:using:) 例如:

let assetDuration = CMTimeGetSeconds(asset.duration)
let maxDuration = 60.0 // Define max duration
let maxLoops = floor(maxDuration / assetDuration)
let lastLoopDuration = maxDuration - (assetDuration * maxLoops)
let boundaryTime = CMTimeMakeWithSeconds(lastLoopDuration, preferredTimescale: 1)
let boundaryTimeValue = NSValue(time: boundaryTime)

player.addBoundaryTimeObserver(forTimes: [boundaryTimeValue], queue: DispatchQueue.main) { [weak self] in
    if self?.playerLooper.loopCount == Int(maxLoops) {
        self?.player.pause()
    }
}

要淡入/淡出,必须在使用audioMix实例之前将AVPlayerItem属性设置为您的let introRange = CMTimeRangeMake(start: CMTimeMakeWithSeconds(0, preferredTimescale: 1), duration: CMTimeMakeWithSeconds(1, preferredTimescale: 1)) let endingSecond = CMTimeRangeMake(start: CMTimeMakeWithSeconds(assetDuration - 1, preferredTimescale: 1), duration: CMTimeMakeWithSeconds(1, preferredTimescale: 1)) let inputParams = AVMutableAudioMixInputParameters(track: asset.tracks.first! as AVAssetTrack) inputParams.setVolumeRamp(fromStartVolume: 0, toEndVolume: 1, timeRange: introRange) inputParams.setVolumeRamp(fromStartVolume: 1, toEndVolume: 0, timeRange: endingSecond) let audioMix = AVMutableAudioMix() audioMix.inputParameters = [inputParams] playerItem.audioMix = audioMix 实例。

func play(_ url: URL) {
    let asset = AVAsset(url: url)
    let playerItem = AVPlayerItem(asset: asset)

    let assetDuration = CMTimeGetSeconds(asset.duration)

    let introRange = CMTimeRangeMake(start: CMTimeMakeWithSeconds(0, preferredTimescale: 1), duration: CMTimeMakeWithSeconds(1, preferredTimescale: 1))
    let endingSecond = CMTimeRangeMake(start: CMTimeMakeWithSeconds(assetDuration - 1, preferredTimescale: 1), duration: CMTimeMakeWithSeconds(1, preferredTimescale: 1))

    let inputParams = AVMutableAudioMixInputParameters(track: asset.tracks.first! as AVAssetTrack)
    inputParams.setVolumeRamp(fromStartVolume: 0, toEndVolume: 1, timeRange: introRange)
    inputParams.setVolumeRamp(fromStartVolume: 1, toEndVolume: 0, timeRange: endingSecond)

    let audioMix = AVMutableAudioMix()
    audioMix.inputParameters = [inputParams]
    playerItem.audioMix = audioMix

    player = AVQueuePlayer(playerItem: playerItem)
    playerLooper = AVPlayerLooper(player: player, templateItem: playerItem)
    player.play()

    let maxDuration = 60.0 // Define max duration
    let maxLoops = floor(maxDuration / assetDuration)
    let lastLoopDuration = maxDuration - (assetDuration * maxLoops)
    let boundaryTime = CMTimeMakeWithSeconds(lastLoopDuration, preferredTimescale: 1)
    let boundaryTimeValue = NSValue(time: boundaryTime)

    player.addBoundaryTimeObserver(forTimes: [boundaryTimeValue], queue: DispatchQueue.main) { [weak self] in
        if self?.playerLooper.loopCount == Int(maxLoops) {
            self?.player.pause()
        }
    }
}

完整功能:

[ManuallyDrop<Box<T>>]