在iOS上循环特定持续时间的音频

在iOS上循环特定持续时间的音频,ios,avplayer,avaudioplayer,avplayerlooper,Ios,Avplayer,Avaudioplayer,Avplayerlooper,我想知道什么是在iOS上按规定的持续时间循环音频的最佳解决方案。 我现在正在玩游戏 AVAudioPlayer(我可以定义重复计数,但不能定义结束时间) AVPlayer(我可以定义forwardPlaybackEndTimebot而不是循环计数) AVPlayerLooper(我还没有完全理解) 所以我需要定义一个持续时间,在这个持续时间内,某个声音文件被重复。我有一个8秒的mp3,想播放一分钟 如果我能在它重新开始时跨越淡入淡出,那将是一件非常棒的事情。你的方法是正确的 这是如何设置AV

我想知道什么是在iOS上按规定的持续时间循环音频的最佳解决方案。 我现在正在玩游戏

  • AVAudioPlayer
    (我可以定义重复计数,但不能定义结束时间)
  • AVPlayer
    (我可以定义
    forwardPlaybackEndTime
    bot而不是循环计数)
  • AVPlayerLooper
    (我还没有完全理解)
所以我需要定义一个持续时间,在这个持续时间内,某个声音文件被重复。我有一个8秒的mp3,想播放一分钟


如果我能在它重新开始时跨越淡入淡出,那将是一件非常棒的事情。

你的方法是正确的

这是如何设置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()
}
要在设定的时间后停止循环,可以使用 例如:

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()
        }
    }
}

你好你有没有试过使用
定时器
?因为我的应用程序应该在后台工作,我想定时器不是一个理想的解决方案?!?我想知道是否有更优雅的…是的,也许不是这个案子的好主意。在
AVAudioPlayer
中,您有一个
numberOfLoops
属性。因此,如果你的mp3持续时间为8秒,你应该运行60/8=7.5倍的声音才能播放1分钟。你看过Cocoapod吗?我认为这个Pod很有用,你有一个
numberOfLoops
属性和一个
currentTime
属性,还有两个方法(
fadeIn
fadeOut
)。它似乎是你的案子的完美吊舱。