AVPlayer won't provide info like codec, So it's hard to get its QoS for child manifest. I'm going to show how to extract codec from AVPlayer.

Nowadays many developers use different formats such as Dolby Atmos, Dolby Vision, DDP, DD, etc for the playback in AVPlayer. They are using child manifests to represent each playback variant. It is hard to capture the codec information or any other child manifest information for the analytical reports in iOS. Since it is limited to access such information from the AVPlayer, It is hard to get the QoS for each of these variants while reporting back to Analytics. So I’m going to show an easy way to extract such information from AVPlayer.

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-INDEPENDENT-SEGMENTS


#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=2168183,BANDWIDTH=2177116,CODECS="avc1.640020,mp4a.40.2",RESOLUTION=960x540,FRAME-RATE=60.000,CLOSED-CAPTIONS="cc1",AUDIO="aud1",SUBTITLES="sub1"
v5/prog_index.m3u8
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=7968416,BANDWIDTH=8001098,CODECS="avc1.64002a,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=60.000,CLOSED-CAPTIONS="cc1",AUDIO="aud1",SUBTITLES="sub1"
v9/prog_index.m3u8

Solution Outline

If we try to get codec or any child manifest parameter in Android, we can achieve this by customizing the network stack of the ExoPlayer. But in iOS, it is a bit tricky since it’s a closed source we don’t have such an option. So I started to look in another direction to see if I could get any other information that can be mapped to the child manifest. In a deeper look, I found that AVPlayer provides the current playback bandwidth through access log events which is the same as in the child manifest. That’s our first anchor point.

Then we can use the M3U8Kit library to parse the manifest and get the child manifest list and find the child manifest using bandwidth.

In short create a logic to use the current playback bandwidth as the primary key to track it back to the child manifest.

Time to write the code

There are 2 sections in this logic, one is to parse the master manifest to get the child manifest list and the other one is to identify the child manifest using the current bandwidth during playback.

Parsing the manifest

Creating the child manifest list using the M3U8Kit library as mentioned below.

Identify child manifest using bandwidth

In order to get the codec changes constantly I’m using the AVPlayer’s periodic time observer. Then in the observer’s callback, I’m using the AVPlayer’s access logs event to get the current bandwidth. Using this bandwidth I’m filtering the child manifest list to get the current manifest used for the playback. As we know the child manifest do holds the codec information, I’m fetching it as mentioned below.

A couple of key things are to be noted in this approach

  • There may be two manifest downloads, one from the player and the other from the M3U8Kit. Which may be a concern for a few.
  • The manifest creator has to make sure the bandwidth should be unique for all the child manifest in a manifest playlist since it is used as a primary key to refer back to the child manifest. Which is true in most cases.

Conclusion

This way it is possible to identify the codec or any other child manifest information from the AVPlayer. And this can be used to report the variant changes in any Analytical tools. Which will be helpful in analyzing the QoS of each variant.

Written By
Fareeth John

I’m working as a Sr. Solution Architect in Akamai Technologies. I have more than 12 years of experience in the Mobile app development industry. Worked on different technologies like VR, Augmented reality, OTT, and IoT in iOS, Android, flutter, and other cross-platform apps. Have worked on 45+ apps from scratch which are in the AppStore and PlayStore. My knowledge of mobile development including design/architecting solutions, app development, knowledge around backend systems,  cloud computing, CDN, Test Automation, CI/CD, Frida Pentesting, and finding mobile app vulnerabilities

Leave a Reply

Your email address will not be published. Required fields are marked *