简体   繁体   中英

Switch to audio-only HLS rendition when AVPlayer goes into the background

Let's say I have an HLS video in an AVPlayer and I want the audio to continue while the app gets backgrounded.

yay I was able to do that with this:

  1. add the Background Modes: Audio capabilities to the application to give my app permission to do this. Described here
  2. in AppDelegate wait for applicationDidEnterBackground and set player = nil on the AVPlayerViewController & save a reference to the player
  3. in AppDelegate wait for applicationWillEnterForeground and set player = savedPlayerReference Described here

Now, get this. Let's say my HLS master manifest has a few video + audio renditions and then one rendition that is an audio-only track. IDEALLY, when AVPlayer goes to the background and stops playing video, I want AVPlayer to use the audio-only track from the master manifest (in order to save bandwidth and not make the application demux the audio/video tracks and decode the video that is not being shown).

How can I do this? I thought it might automatically behave that way but from inspecting the network traffic it looks like when the app is backgrounded AVPlayer is staying on the last rendition and it never switches over to the audio-only rendition manifest

I figured out the answer, it feels like a bit of a hack, but it's working.

The solution is that before disconnecting, to get access to the underlying AVPlayerItem instance and set preferredPeakBitRate to a level that is expected for the audio rendition ( 300000 for example)

Something like this:

func applicationDidEnterBackground(_ application: UIApplication) {
  // set preferred bitrate to the bitrate we expect from the audio rendition
  playerViewController.player?.currentItem?.preferredPeakBitRate = 300000
  savedPlayer = playerViewController.player
  // disconnect AVPlayer from the presentation
  playerViewController.player = nil;
}

And then when the application enters back in the foreground re-setting the preferredPeakBitRate to 0 so that the video track comes back

func applicationWillEnterForeground(_ application: UIApplication) {
  // unset our preferredPeakBitRate value
  playerViewController.player?.currentItem?.preferredPeakBitRate = 0
  // re-connect AVPlayer to the presentation
  playerViewController.player = savedPlayer;
}

I should note that in other contexts (like creating a quality selector or trying to have more control over the specific video rendition), I have not seen preferredPeakBitRate work reliably.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM