Maintaining Good Scroll Performance When Using Avplayer

how to improve the performance of seek when using avplayer

I have found the solution.

If I use seekToTime to do the scrubbing, it's pretty slow. What I should use is a method called stepByCount from AVPlayerItem.

UICollectionView & AVPlayer Performance

First I want to say it's a bit crazy to see several players in action at the same time: it's a heavy task of rendering anyway.

As far as I know, simply scaling/re-framing the video to smaller size doesn't make it less content to render: if you have a 100x100 picture to render and you render it in a frame of 10x10, it still consumes the same amount of memory as the original picture would consume; same thing goes for videos. So, try to make your video assets having similar resolution as the frame where you would present them.

The sound quality of slow playback using AVPlayer is not good enough even when using AVAudioTimePitchAlgorithmSpectral

I've been searching and trying to learn AudioKit and Audio Unit or even considering purchasing a third party time-stretch audio processing library to fix the quality issue of slow playback for the last 3 weeks.

Now finally I found a super easy solution.

AVPlayer can slow down audio with very good quality by setting AVPlayerItem.audioTimePitchAlgorithm
to AVAudioTimePitchAlgorithm.timeDomain instead of AVAudioTimePitchAlgorithm.spectral.

The documentation says:

timeDomain is a modest quality pitch algorithm that is less computationally intensive. Suitable for voice.

This means spectral is suitable for music. timeDomain is suitable for voice.

That's why the voice files which my app uses was echoed.

And that's why Apple's Podcasts App's slowed down audio quality is very high.
It must also uses this time domain algorithm.

And that's why AudioKit, which seems to be developed for music use, plays voice audio with bad quality.

Smooth loading of videos in tableview

Thankfully, you're in luck. iOS is optimized for just these types of issues. Apple engineers have gone to great lengths to provide APIs to help you achieve buttery smooth scrolling and load your content at the same time.

Note: Solving this issue requires offloading tasks to different threads on the CPU. It can get complicated, and there's a lot to learn about it. I strongly recommend you read Apple's documentation.

First, know that the cellForRowAtIndexPath: method should generally call your data source on the main thread. Meaning the call you have to DispatchQueue.main.async is not appropriately used in this scenario.

Instead, what you'll need to do is offload your AVPlayer caching to a separate, background thread and then come back into the main thread to update the cell's layer content. Additionally, you shouldn't be doing that in cellForRowAtIndexPath:. You'll likely need to subclass a UITableViewCell and write your own loading sequence within that - that way, you can quickly init your custom cell, hand it back to cellForRowAtIndexPath: (which can then continue along merrily), and keep loading things and updating from within the cell subclass.

To setup your AVPlayer in a background thread, do this:

DispatchQueue.global(qos: .background).async {
// Background thread
// Do your AVPlayer work here

// When you need to update the UI, switch back out to the main thread
DispatchQueue.main.async {
// Main thread
// Do your UI updates here
}
}

You may want to look at the quality of service value you pass in when you create your background thread. The userInitiated QOS may be better for this specific case because the videos are being loaded as a result of a user-initiated action.

As for the actual caching of the videos. I am not too familiar with AVPlayer or AVPlayerItem, but from my understanding the more metadata (i.e. duration, tracks, etc.) you can give to AVPlayer before trying to render the video in a layer, the faster it goes (see this related StackOverflow Question).

Additionally, you'll probably want to check out the newly introduced APIs in iOS 10 that all you to pre-fetch cells in a table view. If you take advantage of the pre-fetch optimizations, you could likely load everything you need for AVPlayer in the background and well before the cells are ever requested for display in cellForRowAtIndexPath:.

Anyhow, hope you can get started from there and solve the issue. Definitely take the time to read the documentation on AVKit, GCD, and UITableView (specifically the new pre-fetching APIs).



Related Topics



Leave a reply



Submit