How to intercept HLS Playlist chunk request for CDN token implementation

Hello,

We are using HLS for our streaming iOS and tvOS applications. We have DRM protection on our applications but we want add another secure layer which is CDN token.

We want to add that CDN token data on header or query parameters. Any of two are applicable at our CDN side. There is a problem at client side. We want to send that token knowledge and refresh at given a time.

We add token data using at initial state

let asset = AVURLAsset(url: url, options: ["AVURLAssetHTTPHeaderFieldsKey": headers])

and add interceptor with asset.resourceLoader.setDelegate. It works seamlessly.

We use AVAssetResourceLoaderDelegate and we can intercept just master playlist and playlists via

func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool 

and we can refresh CDN token data at only playlists. That token data can be at query params or header. It does not matter.

For example,

#EXTM3U
#EXT-X-VERSION:3
#EXTINF:10.0
https://chunk1?cdntoken=A.ts
#EXTINF:10.0
https://chunk2?cdntoken=A.ts
#EXTINF:10.0
https://chunk3?cdntoken=A.ts
#EXTINF:10.0

assume that it is our .m3u8 file for given live video playlist. It has three chunks with cdn token data in query params. If we give that chunks to AVPlayer. It is going to play chunks in order.

  1. When we change new cdn token at query params, it effects our chunk Urls and our player stalls. It is because our cdn adds new cdn token knowledge to chunk's Url. It means that our new .m3u8 is going to be like that for next playlist;
#EXT-X-VERSION:3
#EXTINF:10.0
https://chunk4?cdntoken=B.ts
#EXTINF:10.0
https://chunk5?cdntoken=B.ts
#EXTINF:10.0
https://chunk6?cdntoken=B.ts
#EXTINF:10.0

Cdn token data is converted to B from A at cdn side and it sends new playlist like that. That's why, our player is going to stall. Is there any way not to player stall with edited chunk url?

  1. When we change new cdn token at header. It does not change chunks url like at the first question but AVPlayer does not allow to intercept chunk Urls which means that before callin https://chunk1?cdntoken=A.ts url, i want to intercept and add new cdn token data to header. Is there any way to intercept chunk Urls like intercepting playlist?

Thanks for answers in advance

Replies

My understanding is you are not allowed to change the URL of any segment.

That is, if the playlist at time T has told me 'https://chunk4?cdntoken=A.ts' then the playlist at time T+1 must also say 'https://chunk4?cdntoken=A.ts'

If at time T we were not told about chunk5 then at time T+1 you can add whatever token you want to chunk5.

If the playlists have no overlap, that's a problem.

  • Actually I do not change the URL of any segment. CDN provides playlists and we give these playlists to AVPlayer. We do not do any modification on playlist. We just intercept playlist request and add new token data to playlist's query parameters at given time. CDN edites chunk URLs with new token after interceptor request . So that, playlist URLs change at new playlist. That's why, it stalls. Is there any way to not to stall player after major changes chunk URLs like i mention above? Thanks.

Add a Comment

We do not change the URL of any segments. CDN changes via our playlist request. I want to explain in depth. Assume that;

#EXTM3U
#EXT-X-VERSION:7
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="mp4a.40.2",URI="7-audio_ts.m3u8?cdnToken=A"
#EXT-X-STREAM-INF:BANDWIDTH=1020800,CODECS="mp4a.40.2",RESOLUTION=768x432,FRAME-RATE=25.000,AUDIO="mp4a.40.2"
0-video_768_432_ts.m3u8?cdnToken=A
#EXT-X-STREAM-INF:BANDWIDTH=1680800,CODECS="mp4a.40.2",RESOLUTION=960x540,FRAME-RATE=25.000,AUDIO="mp4a.40.2"
1-video_960_540_ts.m3u8?cdnToken=A

It is our Master playlist which has one sound and two video profiles. AVPlayer starts to request at 0-video_768_432_ts.m3u8?cdnToken=A video profile which has our token knowledge in query parameters. AVPlayer gets response playlist which we assume the first playlist;

#EXT-X-VERSION:3
#EXTINF:10.0
https://chunk1?cdntoken=A.ts
#EXTINF:10.0
https://chunk2?cdntoken=A.ts
#EXTINF:10.0
https://chunk3?cdntoken=A.ts
#EXTINF:10.0

It plays 30 seconds because it has three chunks and each chunk 10 seconds long for that playlist. It gets another playlist from our CDN while player is working. Playlist will has chunk URLs in order like chunk4, chunk5, chunk6 etc. with old token which is A when get response from CDN. We can intercept playlists request via AVAssetResourceLoaderDelegate. So that, we can change 0-video_768_432_ts.m3u8?cdnToken=A playlist request like 0-video_768_432_ts.m3u8?cdnToken=B at a given time. That request can be changed after 1 minutes. CDN generates Chunk urls with cdnToken=B and because of new URL request.

Second Playlist;

#EXT-X-VERSION:3
#EXTINF:10.0
https://chunk4?cdntoken=A.ts
#EXTINF:10.0
https://chunk5?cdntoken=A.ts
#EXTINF:10.0
https://chunk6?cdntoken=A.ts
#EXTINF:10.0

Third Playlist;

#EXT-X-VERSION:3
#EXTINF:10.0
https://chunk7?cdntoken=B.ts
#EXTINF:10.0
https://chunk8?cdntoken=B.ts
#EXTINF:10.0
https://chunk9?cdntoken=B.ts
#EXTINF:10.0

As you can see the first and second playlists has old token but third playlist has new token at chunk URLs due to we call the third playlist with 0-video_768_432_ts.m3u8?cdnToken=B. It causes stalling. We want to handle that stalling. Is there any way to do it? Or Is there any another solution for that problem?

Hey, @unal-ozturk. Could you find a solution for this? I'm working on something similar and I have no idea where to start. Let me know if could find a solution or maybe I can email you. Thank you.