vinhnx / notes

my today I learn (TIL) journal, includes everything that I found interesting, not necessarily relates to programming
44 stars 2 forks source link

Switch AVPlayer(Item) streaming bitrate quality #92

Open vinhnx opened 6 years ago

vinhnx commented 6 years ago

preferredPeakBitRate

SDKs iOS 8.0+ macOS 10.10+ tvOS 9.0+

The desired limit, in bits per second, of network bandwidth consumption for this item.

Declaration

var preferredPeakBitRate: Double { get set } Discussion

Set preferredPeakBitRate to non-zero to indicate that the player should attempt to limit item playback to that bit rate, expressed in bits per second.

If network bandwidth consumption cannot be lowered to meet the preferredPeakBitRate, it will be reduced as much as possible while continuing to play the item.

References:

Wenfengcheng commented 5 years ago

@vinhnx

Yes, it worked! But there is a question, should I init a new AVPlayerItem instance with different bitrate and replace old bitrate AVPlayerItem? Then reload AVPlayer?

Waiting for your reply! Thanks,

vinhnx commented 5 years ago

@Wenfengcheng just need to set preferredPeakBitRate directly to the current AVPlayerItem instance, then the player will take care of handling the peak bitrate automatically. Don't need to create new and replace anything.

Wenfengcheng commented 5 years ago

@vinhnx Thanks for your advice! Yeah, it worked! And the whole transformation process is very fast, basically no need to show indicators.

This may be one of the most satisfying features of my recent use of avplayer.

Wenfengcheng commented 5 years ago

@vinhnx

set preferredMaximumResolution to unqie resolution also worked, such as 720p, or 360p.

The desired maximum resolution of a video that is to be downloaded. Defaults to CGSizeZero, which indicates there is no limit on the video resolution. Any other value indicates a preferred maximum video resolution. This property only applies to HTTP Live Streaming assets.

gobetti commented 5 years ago

Hi guys, thank you for this discussion, it has helped me while investigating how to take the full power out of HLS videos on iOS! I thought I could add further insight here after experimentations:

  1. preferredMaximumResolution seems to work fine only if you set it before you download the video, which is expressed in the documentation by "a video that is to be downloaded."

I was hopeful that I could change it during playback as well, but the video layer will remain with the initial presentationSize no matter the position that I seek to.

  1. preferredPeakBitRate, on the other hand, does update the size during playback. This is a log I've added, where ♻️ represents a moment that I set a given peak bitrate (at every 10 seconds), and ✅ is a KVO observer for layer.presentationSize:
2018-11-30 10:40:01.339: ✅ -> Event next(Optional((0.0, 0.0)))
2018-11-30 10:40:01.344: ♻️ -> Event next(309000.0)
2018-11-30 10:40:01.573: ✅ -> Event next(Optional((320.0, 180.0)))
2018-11-30 10:40:01.629: ✅ -> Event next(Optional((320.0, 180.0)))
2018-11-30 10:40:01.631: ✅ -> Event next(Optional((320.0, 180.0)))
2018-11-30 10:40:11.340: ♻️ -> Event next(538000.0)
2018-11-30 10:40:11.514: ✅ -> Event next(Optional((320.0, 180.0)))
2018-11-30 10:40:21.340: ♻️ -> Event next(899000.0)
2018-11-30 10:40:21.512: ✅ -> Event next(Optional((320.0, 180.0)))
2018-11-30 10:40:21.580: ✅ -> Event next(Optional((480.0, 270.0)))
2018-11-30 10:40:22.052: ✅ -> Event next(Optional((480.0, 270.0)))
2018-11-30 10:40:30.718: ✅ -> Event next(Optional((640.0, 360.0)))
2018-11-30 10:40:31.246: ✅ -> Event next(Optional((640.0, 360.0)))
2018-11-30 10:40:31.338: ♻️ -> Event next(1356000.0)
2018-11-30 10:40:31.470: ✅ -> Event next(Optional((640.0, 360.0)))
2018-11-30 10:40:34.136: ✅ -> Event next(Optional((960.0, 540.0)))
2018-11-30 10:40:34.359: ✅ -> Event next(Optional((960.0, 540.0)))
2018-11-30 10:40:41.340: ♻️ -> Event next(2354000.0)
2018-11-30 10:40:47.663: ✅ -> Event next(Optional((960.0, 540.0)))
2018-11-30 10:40:48.156: ✅ -> Event next(Optional((1280.0, 720.0)))
2018-11-30 10:40:50.707: ✅ -> Event next(Optional((1280.0, 720.0)))
2018-11-30 10:40:51.339: ♻️ -> Event next(6222000.0)
2018-11-30 10:40:52.883: ✅ -> Event next(Optional((1280.0, 720.0)))
2018-11-30 10:41:05.796: ✅ -> Event next(Optional((1920.0, 1080.0)))
2018-11-30 10:41:05.890: ✅ -> Event next(Optional((1920.0, 1080.0)))
  1. As you can see, the size doesn't change immediately after I set a new peak bitrate, perhaps because it waits for an acceptable buffer of the new bitrate to finish downloading before it replaces the already loaded buffer by the new one (you'll notice the greater the bitrate, the longer the delay between setting it and updating the actual size). I tried setting automaticallyWaitsToMinimizeStalling = false expecting it would cause the video to stall while loading the new size, but it didn't make a difference.
Wenfengcheng commented 5 years ago

@vinhnx @gobetti I found some problems when switched the resolution in actual development enviorment, the size doesn't change immediately and the only thing I can do is monitor the change of PresentationSize to determine if the switch is successful. And sometimes switching to a high bitrate is hard because of network problems. Any suggestions for this situation?

gobetti commented 5 years ago

@Wenfengcheng that seems to be the intended behavior, unfortunately. The resolution change (by setting the preferredPeakBitRate) is never immediate, and setting that value higher doesn't mean you'll get a higher resolution, because that property indicates an upper limit (as per Apple docs), not a lower limit. You'll still have the network connection as a stronger upper limit.

I'm also interested on solutions for these, mainly for the forced high bitrate. Sometimes users may prefer the video to stall than to watch at a low quality. The YouTube app seems to allow it, but I'm not sure whether they use a single HLS source for that or a separate single-resolution video file.

rnkyr commented 4 years ago

it's been a while, but I should try

did you found any way to force it to play at exact bitrate? I currently have the same behavior requirement

apieceofcode1801 commented 2 years ago

I'm having the same problem with this too, the video resolution is not changed immediately. That's not the behavior the users want to see when changing the video quality. Is there another solution for sure?