首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在iOS上播放一定时间的循环音频

在iOS上播放一定时间的循环音频
EN

Stack Overflow用户
提问于 2018-10-19 09:34:19
回答 1查看 894关注 0票数 2

我想知道在iOS上循环播放音频的最佳解决方案是什么。我现在在玩

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

所以我需要的是定义一个特定声音文件被重复的持续时间。F.e.我有一个8秒的mp3,我想播放它一分钟。

如果我能在它重新开始的时候褪色的话,那就更好了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-19 13:12:50

你和AVPlayerLooper走在正确的轨道上。

这是如何设置AVPlayerLooper

代码语言:javascript
复制
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:),例如:

代码语言:javascript
复制
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实例。

代码语言:javascript
复制
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

功能齐全:

代码语言:javascript
复制
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()
        }
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52889664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档