I'm trying to use AVQueuePlayer to create a seamless audio loop, however, I don't know why there is a small silent pause between loops?

为君一笑 提交于 2019-12-11 06:49:44

问题


I have a simple audio file in .wav format (the audio file is cut perfectly to loop). I've tried different methods to loop it. My first attempt was simply using AVPlayer and NSNotification to detect when audioItem ended to seek time at zero and play again. However, there was clearly a gap.

I've been looking at different solutions online, and found people using AVQueuePlayer to do a switching: Looping AVPlayer seamlessly

However, when implemented, this still produces a gap.

Here's my current notification code:

weak var weakSelf = self
NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: nil, queue: nil, usingBlock: {(note: NSNotification) -> Void in

        if weakSelf?.currentQueuePlayer.currentItem == weakSelf?.currentAudioItemOne {

            weakSelf?.currentQueuePlayer.insertItem((weakSelf?.currentAudioItemTwo)!, afterItem: nil)
            weakSelf?.currentAudioItemTwo.seekToTime(kCMTimeZero)
        } else {
            weakSelf?.currentQueuePlayer.insertItem((weakSelf?.currentAudioItemOne)!, afterItem: nil)
            weakSelf?.currentAudioItemOne.seekToTime(kCMTimeZero)
        }

    })

Here's my code to set up the current QueuePlayer.

let audioPlayerItem = AVPlayerItem(URL: url)
currentAudioItemOne = audioPlayerItem


currentAudioItemTwo = audioPlayerItem

currentQueuePlayer = AVQueuePlayer()
currentQueuePlayer.insertItem(currentAudioItemOne, afterItem: nil)

currentQueuePlayer.play()

I've been working at this problem for several days now. Any leads or new things to try would be appreciated. The only thing I haven't tried so far is lower quality audio files. These .wav files are all over 1mb, and had be suspecting that the file size could be affecting the seamless looping.

EDIT:

Using AVPlayerLooper to create the 'Treadmill' effect:

        let url = URL(fileURLWithPath: path)
        let audioPlayerItem = AVPlayerItem(url: url)
        currentAudioItemOne = audioPlayerItem

        currentQueuePlayer = AVQueuePlayer()
        currentAudioPlayerLayer = AVPlayerLayer(player: currentQueuePlayer)
        currentAudioLooper = AVPlayerLooper(player: currentQueuePlayer, templateItem: currentAudioItemOne)

        currentQueuePlayer.play() 

EDIT 2:

afinfo on one of my wav files:

Num Tracks:     1
----
Data format:     2 ch,  44100 Hz, 'lpcm' (0x0000000C) 16-bit little-endian signed integer
                no channel layout.
estimated duration: 11.302336 sec
audio bytes: 1993732
audio packets: 498433
bit rate: 1411200 bits per second
packet size upper bound: 4
maximum packet size: 4
audio data file offset: 44
not optimized
source bit depth: I16
----

回答1:


You are inserting the item too late in your current solution. You need to queue up more than one initial item, so there's always a primed AVPlayerItem ready to go.

This is called the AVPlayerQueue "treadmill pattern" as better described in this WWDC 2016 session. If you're targeting iOS 10, you can use new AVPlayerLooper class which does it for you (also described in the same link). Apple has also provided a sample project which provides an example of both strategies.

Lower level solutions include queuing up the audio buffers to an AVAudioEngine instance or using an AudioQueue or mashing the buffers together yourself with an AudioUnit.



来源:https://stackoverflow.com/questions/39441621/im-trying-to-use-avqueueplayer-to-create-a-seamless-audio-loop-however-i-don

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!