I'm trying to crop a video / display a portion of a video in AVFoundation. So far my code looks right to me but the output is not what I wanted. I don't see what is wrong. Any ideas?
let item = AVPlayerItem(url: nextVideoItem.url)
let cropRect = CGRect(x: 200, y: 200, width: 300, height: 300)
let cropComposition = AVMutableVideoComposition(asset: item.asset, applyingCIFiltersWithHandler: { request in
let cropFilter = CIFilter(name: "CICrop")!
cropFilter.setValue(request.sourceImage, forKey: kCIInputImageKey)
cropFilter.setValue(CIVector(cgRect: cropRect), forKey: "inputRectangle")
let imageAtOrigin = cropFilter.outputImage!.transformed(by: CGAffineTransform(translationX: -cropRect.origin.x, y: -cropRect.origin.y))
request.finish(with: imageAtOrigin, context: nil)
})
cropComposition.renderSize = cropRect.size
item.videoComposition = cropComposition
self.player.replaceCurrentItem(with: item)
self.player.play()
The above code runs fine in itself, the reason you can't see it is you're probably not setting the frame of the AVPlayerViewController's view or AVPlayerLayer correctly in your surrounding UI code. Here is a Swift Playground code snippet that plays a video asset with the crop you specified above:
import UIKit
import AVKit
import PlaygroundSupport
class MyViewController : UIViewController {
var player: AVPlayer!
var avLayer: AVPlayerLayer!
override func loadView() {
let view = UIView()
view.backgroundColor = .white
player = AVPlayer()
let item = AVPlayerItem(url: #fileLiteral(resourceName: "logos.mov"))
let cropRect = CGRect(x: 500, y: 250, width: 480, height: 320)
let cropComposition = AVMutableVideoComposition(asset: item.asset, applyingCIFiltersWithHandler: { request in
let cropFilter = CIFilter(name: "CICrop")!
cropFilter.setValue(request.sourceImage, forKey: kCIInputImageKey)
cropFilter.setValue(CIVector(cgRect: cropRect), forKey: "inputRectangle")
let imageAtOrigin = cropFilter.outputImage!.transformed(by: CGAffineTransform(translationX: -cropRect.origin.x, y: -cropRect.origin.y))
request.finish(with: imageAtOrigin, context: nil)
})
cropComposition.renderSize = cropRect.size
item.videoComposition = cropComposition
self.player.replaceCurrentItem(with: item)
self.player.play()
avLayer = AVPlayerLayer()
avLayer.player = self.player
view.layer.addSublayer(avLayer)
self.view = view
}
override func viewDidAppear(_ animated: Bool) {
// this is the important bit
avLayer.frame = view.bounds
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()