How do I update the metadata of an AVURLAsset after downloading via AVAssetDownloadTask/Session?

965 Views Asked by At

I am implementing offline playback of some HLS/m3u8 streams. Everything is working as intended using AVAssetDownloadURLSession, using it to make AVAssetDownloadTasks given an AVURLAsset from a stream url.

I would like to save some custom information in the asset's metadata property before or after the download is complete, but it is read only. I have tried using AVAssetExportSession, AVAssetWriter, etc. but none have worked due to (I think) the special way the OS manages the HLS offline playback files. They are packaged as an .movpkg

Anyone have experience with the above and gotten it to work?

The session is currently set up like this:

private lazy var avAssetDownloadSession = AVAssetDownloadURLSession(configuration: downloadConfig, assetDownloadDelegate: self, delegateQueue: .main)
private let downloadConfig: URLSessionConfiguration

init() {
    self.downloadConfig = URLSessionConfiguration.background(withIdentifier: "DownloadConfig")
    self.downloadConfig.httpMaximumConnectionsPerHost = 1
}

private func startDownload(for asset: AVURLAsset) {
    guard let downloadTask = avAssetDownloadSession.makeAssetDownloadTask(asset: asset, assetTitle: "Test", assetArtworkData: nil, options: nil)
        else { return }

    downloadTask.taskDescription = "Test task description"
    downloadTask.resume()
}

The delegate methods are all firing appropriately, so there's no problem w/ the download part.

3

There are 3 best solutions below

1
M Abubaker Majeed On

This Adding meta-data to video in iOS link might be helpful.

0
M. LeRouge On

Modifying downloaded movpkg's is not supported. Any metadata must also exist in the version on the server.

0
Ned On

Apple doesn't recommend to store additional information in the package:

Important: Downloaded HLS assets are stored on disk in a private bundle format. This bundle format may change over time, and developers should not attempt to access or store files within the bundle directly, but should instead use AVFoundation and other iOS APIs to interact with downloaded assets.

But you can download additional information:

Downloading Additional Media Selections

You can update downloaded assets with additional audio and video variants or alternative media selections. This capability is useful if the originally downloaded movie does not contain the highest quality video bit rate available on the server or if a user would like to add supplementary audio or subtitle selections to the downloaded asset.

AVAssetDownloadTask downloads a single media-selection set. During the initial asset download, the user’s default media selections—their primary audio and video tracks—are downloaded. If additional media selections such as subtitles, closed captions, or alternative audio tracks are found, the session delegate’s URLSession:assetDownloadTask:didResolveMediaSelection: method is called, indicating that additional media selections exist on the server. To download additional media selections, save a reference to this resolved AVMediaSelection object so you can create subsequent download tasks to be executed serially.

func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didResolve resolvedMediaSelection: AVMediaSelection) {
    // Store away for later retrieval when main asset download is complete
    // mediaSelectionMap is defined as: [AVAssetDownloadTask : AVMediaSelection]()
    mediaSelectionMap[assetDownloadTask] = resolvedMediaSelection
}