在 iOS 上循环播放一段音频

Posted

技术标签:

【中文标题】在 iOS 上循环播放一段音频【英文标题】:Loop audio for certain duration on iOS 【发布时间】:2018-10-19 09:34:19 【问题描述】:

我想知道在 ios 上在定义的持续时间内循环播放音频的最佳解决方案是什么。 我目前正在玩

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

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

如果我可以在重新开始时交叉淡入淡出,那也是非常棒的。

【问题讨论】:

您好!你试过Timer吗? 因为我的应用程序在后台运行时也应该可以工作,我猜 Timer 不是一个理想的解决方案?!?我想知道是否有更优雅的东西...... 是的,对于这种情况可能不是一个好主意。在 AVAudioPlayer 中,您有一个 numberOfLoops 属性。因此,如果您的 mp3 的持续时间为 8 秒,您应该运行 60 / 8 = 7.5 倍的声音来播放 1 分钟。 你研究过 CocoaPods 吗?我认为这个 Pod 会很有帮助 cocoapods.org/pods/AudioPlayerSwift,你有一个 numberOfLoops 属性和一个 currentTime 属性以及两个方法(fadeInfadeOut)。它似乎是适合您情况的完美 Pod。 【参考方案1】:

您与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()
        
    

【讨论】:

以上是关于在 iOS 上循环播放一段音频的主要内容,如果未能解决你的问题,请参考以下文章

js中怎么让音频重复播放

哪些音频类型可以在 iOS 中无间隙地循环播放?

如何使用jQuery无限循环播放音频文件

Phonegap / Cordova 在后台 IOS 一段时间后停止音频

如何在 iOS 应用程序中连续循环播放声音文件?

iOS音频播放录音视频播放拍照视频录制