AVPlayer
will randomly just play audio, not showing the video track...
Playing video correctly with AVPlayer
while having an active compression session of AVAssetExportSession:exportAsynchronouslyWithCompletionHandler
is now failing. It seems it causes some instability that persists until the app goes into the background and comes back.
Examining AVURLAsset
when video playback fails, there is a video track even though there is no video output. I also don't get any errors from the compressor or the other playback components... The problem happens even for a while after the compression session has returned.
I've tried separate threading in different ways with no success.
It seems that as of iOS 10 there is something going on under the hood that causes some sort of conflict between both processes...
Just heard from Apple DTS. They also agree this points to an Apple iOS bug and asked me to log it.
I cut out usage of AVAssetExportSession
altogether and it solved the issue. So calling AVAssetExportSession
in combination with other AV methods is what causes the iOS instability.
In my case I was usingAVAssetExportSession
for post capture compression. So instead I used AVAssetWriter
to sample each frame in real-time to the format I needed...
This should be fixed soon by Apple, hopefully.
I found a solution to my problem. Like Sami said, the issue appears to be in AVVideoCompositionCoreAnimationTool which I was using to watermark my video. I shifted to using a CIFilter, which actually had cleaner code anyway.
I removed everything with CoreAnimationTool and used this (mixComposition is my AVMutableComposition):
let watermarkFilter = CIFilter(name: "CISourceOverCompositing")!
let watermarkImage = CIImage(image: #imageLiteral(resourceName: "watermark"))!
let videoComposition = AVVideoComposition(asset: mixComposition) { (filteringRequest) in
let source = filteringRequest.sourceImage.clampingToExtent()
watermarkFilter.setValue(source, forKey: "inputBackgroundImage")
let transform = CGAffineTransform(translationX: filteringRequest.sourceImage.extent.width - watermarkImage.extent.width - 2, y: 0)
watermarkFilter.setValue(watermarkImage.applying(transform), forKey: "inputImage")
filteringRequest.finish(with: watermarkFilter.outputImage!, context: nil)
}
and then in the AVAssetExportSession added this:
exporter!.videoComposition = videoComposition
Hope that helps somebody!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With