You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
App Description:
There is an iOS App which plays video on demand(VOD), which is of hls(.m3u8) type. In each session multiple VODs can be played.
VODs urls can is retrieved and cached when accessed for the first time.
sample VOD url: http://sample.vodobox.com/planete_interdite/planete_interdite_alternate.m3u8
sequence of network calls which goes while playing this url through AVPlayer is as follows:
Master playlist file request goes first.
Individual playlist file for various video qualities is received in the first response which further contains individual segments urls
Individual segment url requests are made and video starts playing
Scenario:
In every App session there are set of VODs urls are which are played frequently and are already known. To play any video we are initialising AVPlayer with AVUrlAsset with those urls.
Observation:
AVPlayer takes time to initialise and play the first segment based on network bandwidth due to the sequence of calls mentioned above.
Requirement:
Since we already knew that user will play this url beforehand, we want to minimise the startup time i.e. time between AVPlayer initialisation and first frame rendered.
Approach:
We wanted to cache the first few segments(let's say first 3 segments) along with the master file for a particular VOD, so that whenever user initiates a playback we already had enough resource cached at our end to render the first frame of the video. note: we only want to cache the first few segments not the complete segments, rest of the segments network call can be made while the video is being played. This will ensure the video started playing very minimal load time.
To Achieve this kind of partial cacheing, we tried to use:
AVAssetDownloadURLSession
created a aggregate download task aggregateAssetDownloadTask(with URLAsset: AVURLAsset ....)
in the delegate func urlSession(_ session: URLSession, aggregateAssetDownloadTask: AVAggregateAssetDownloadTask, willDownloadTo location: URL) we received the download location
in the delegate func urlSession(_ session: URLSession, aggregateAssetDownloadTask: AVAggregateAssetDownloadTask, didLoad timeRange: CMTimeRange, totalTimeRangesLoaded loadedTimeRanges: [NSValue], timeRangeExpectedToLoad expectedTimeRange: CMTimeRange, for mediaSelection: AVMediaSelection), we monitored the download progress and cancelled the task with 5% progress completion mark.
Used this download location in AVURLAsset, to play the video and video was getting played also.
Problem With Above approach:
Once this partially downloaded url is provided to the AVPlayer it plays but while playing it also download the rest of the segment, this complete downloaded of the content was not required because for multiple VODs this can trigger device out of memory. Moreover the VODs sizes can be large i.e. > 4GB
This downloaded file location contains file of type .movpkg, the size of the file is visible in App settings for individual content. To remove that entry we tried to move this .movpkg file to documents directory but that didn't work because location of the partially downloaded video was a private directory and moving the content to different directory always failed.
Please suggest some improvements in our approach to achieve this kind of partial cacheing of hls contents. Also is there any another possible ways to cache the hls contents partially in general.
App Description:
There is an iOS App which plays video on demand(VOD), which is of hls(.m3u8) type. In each session multiple VODs can be played.
VODs urls can is retrieved and cached when accessed for the first time.
sample VOD url: http://sample.vodobox.com/planete_interdite/planete_interdite_alternate.m3u8
sequence of network calls which goes while playing this url through AVPlayer is as follows:
Scenario:
In every App session there are set of VODs urls are which are played frequently and are already known. To play any video we are initialising AVPlayer with AVUrlAsset with those urls.
Observation:
AVPlayer takes time to initialise and play the first segment based on network bandwidth due to the sequence of calls mentioned above.
Requirement:
Since we already knew that user will play this url beforehand, we want to minimise the startup time i.e. time between AVPlayer initialisation and first frame rendered.
Approach:
We wanted to cache the first few segments(let's say first 3 segments) along with the master file for a particular VOD, so that whenever user initiates a playback we already had enough resource cached at our end to render the first frame of the video. note: we only want to cache the first few segments not the complete segments, rest of the segments network call can be made while the video is being played. This will ensure the video started playing very minimal load time.
To Achieve this kind of partial cacheing, we tried to use:
Problem With Above approach:
Please suggest some improvements in our approach to achieve this kind of partial cacheing of hls contents. Also is there any another possible ways to cache the hls contents partially in general.
Sample project: https://github.com/Rokimkar/HLSStreamPreCache
The text was updated successfully, but these errors were encountered: