Hello everyone!
Recently our backend team integrated video streaming via HLS, before we had default HTTP streaming.
With HTTP streaming this exporting code worked fine:
private func cacheFile(from asset: AVURLAsset) {
guard asset.isExportable,
let fileName = asset.url.pathComponents.last,
let outputURL = self.cacheDirectory?.appendingPathComponent(fileName),
!FileManager.default.fileExists(atPath: outputURL.path)
else { return }
asset.resourceLoader.setDelegate(self, queue: backgroundQueue.underlyingQueue)
let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality)
exporter?.outputURL = outputURL
exporter?.determineCompatibleFileTypes(completionHandler: { types in
guard let type = types.first else { return }
exporter?.outputFileType = type
exporter?.exportAsynchronously(completionHandler: {
if let error = exporter?.error {
print(error)
}
})
})
}
This code works great with HTTP streaming, but for HLS asset.isExportable
is equal to false
.
After removing check for asset.isExportable
exporter?.determineCompatibleFileTypes
passes empty array inside closure. If setting outputFileType
to .mp4
or .mov
I'm receiving error inside exportAsynchronously completionHandler
:
Error Domain=AVFoundationErrorDomain Code=-11838 "Operation Stopped" UserInfo={NSLocalizedFailureReason=The operation is not supported for this media., NSLocalizedDescription=Operation Stopped, NSUnderlyingError=0x6000025abd50 {Error Domain=NSOSStatusErrorDomain Code=-16976 "(null)"
Why does this happen? AVAssetExportSession cannot combine all parts of .m3u8
to .mp4
? Is there any alternative way to cache streamed video via HLS?