Skip to content

Instantly share code, notes, and snippets.

@makthrow
Last active December 1, 2016 01:27
Show Gist options
  • Save makthrow/e532e1513b5c39bd325eefb74502d447 to your computer and use it in GitHub Desktop.
Save makthrow/e532e1513b5c39bd325eefb74502d447 to your computer and use it in GitHub Desktop.
preview cam - dismiss view not working
CamViewController
// self.performSegue(withIdentifier: "preview", sender: self)
// leads to PreviewViewController
// PreviewViewController.swift
import UIKit
import AVKit
import AVFoundation
class PreviewViewController: UIViewController {
let avPlayerViewController = AVPlayerViewController()
var avPlayer:AVPlayer? = nil
var overlayView = UIView()
var fileToUploadURL: URL!
var uploadMediaTitle: String?
var videoDismissed: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(_ animated: Bool) {
self.previewVideo(videoURL: fileToUploadURL)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: Merge
func mergeVideoWithTheme(inputVideoUrl videoUrl: URL!, onComplete completionHandler: ((AVAssetExportSessionStatus) -> ())!) -> Void {
// 1. mergeComposition adds all the AVAssets
var mergeComposition : AVMutableComposition = AVMutableComposition()
var trackVideo : AVMutableCompositionTrack = mergeComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
//var trackAudio : AVMutableCompositionTrack = mergeComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
// 2. Add a bank for theme insertion later
//trackVideo.insertTimeRange(range, ofTrack: VideoHelper.Static.blankTrack, atTime: kCMTimeZero, error: nil)
// 3. Source tracks
let sourceAsset = AVURLAsset(url: videoUrl, options: nil)
let sourceDuration = CMTimeRangeMake(kCMTimeZero, sourceAsset.duration)
let vtrack: AVAssetTrack? = sourceAsset.tracks(withMediaType: AVMediaTypeVideo)[0]
let atrack: AVAssetTrack? = sourceAsset.tracks(withMediaType: AVMediaTypeAudio)[0]
if (vtrack == nil) {
return
}
let renderWidth = vtrack?.naturalSize.width
let renderHeight = vtrack?.naturalSize.height
let insertTime = kCMTimeZero
let endTime = sourceAsset.duration
let range = sourceDuration
// append tracks
do {
try trackVideo.insertTimeRange(range, of: vtrack!, at: insertTime)
}
catch {
}
//if(atrack > 0){
// trackAudio.insertTimeRange(sourceDuration, ofTrack: atracks[0] as AVAssetTrack, atTime: insertTime, error: nil)
//}
// 4. Add subtitles (we call it theme)
var themeVideoComposition : AVMutableVideoComposition = AVMutableVideoComposition(propertiesOf: sourceAsset)
// 4.1 - Create AVMutableVideoCompositionInstruction
let mainInstruction: AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()
mainInstruction.timeRange = range
// 4.2 - Create an AVMutableVideoCompositionLayerInstruction for the video track and fix the orientation.
let videolayerInstruction: AVMutableVideoCompositionLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: vtrack!)
videolayerInstruction.setTransform(trackVideo.preferredTransform, at: insertTime)
videolayerInstruction.setOpacity(0.0, at: endTime)
// 4.3 - Add instructions
mainInstruction.layerInstructions = Array([videolayerInstruction])
themeVideoComposition.renderScale = 1.0
themeVideoComposition.renderSize = CGSize(width: renderWidth!, height: renderHeight!)
themeVideoComposition.frameDuration = CMTimeMake(1, 30)
themeVideoComposition.instructions = Array([mainInstruction])
// add the theme
// setup variables
// add text
let title = self.uploadMediaTitle
var titleLayer = CATextLayer()
titleLayer.string = title
titleLayer.frame = CGRect(x: 0, y: 0, width: renderWidth!, height: renderHeight!)
let fontName: CFString = "Helvetica-Bold" as CFString
let fontSize = CGFloat(36)
titleLayer.font = CTFontCreateWithName(fontName, fontSize, nil)
titleLayer.alignmentMode = kCAAlignmentCenter
titleLayer.foregroundColor = UIColor.white.cgColor
var backgroundLayer = CALayer()
backgroundLayer.frame = CGRect(x: 0, y: 0, width: renderWidth!, height: renderHeight!)
backgroundLayer.masksToBounds = true
backgroundLayer.addSublayer(titleLayer)
// 2. set parent layer and video layer
var parentLayer = CALayer()
var videoLayer = CALayer()
parentLayer.frame = CGRect(x: 0, y: 0, width: renderWidth!, height: renderHeight!)
videoLayer.frame = CGRect(x: 0, y: 0, width: renderWidth!, height: renderHeight!)
parentLayer.addSublayer(backgroundLayer)
parentLayer.addSublayer(videoLayer)
// 3. make animation
themeVideoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
// create new file to receive data
let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let docsDir: AnyObject = dirPaths[0] as AnyObject
let movieDestinationUrl = docsDir.strings(byAppendingPaths: ["result.mov"])[0]
let outputUrl = URL(fileURLWithPath: movieDestinationUrl)
// let movieFilePath:URL = docsDir.appendingPathComponent("result.mov")!
// let outputUrl = URL(fileURLWithPath: movieFilePath)
// Remove the file if it already exists (merger does not overwrite)
let fileManager = FileManager.default
do {
try fileManager.removeItem(at: outputUrl)
}
catch {
}
// export to output url
var exporterSession = AVAssetExportSession(asset: mergeComposition, presetName: AVAssetExportPresetHighestQuality)
if let exporter = exporterSession {
exporter.outputURL = outputUrl
exporter.videoComposition = themeVideoComposition
exporter.outputFileType = AVFileTypeQuickTimeMovie
exporter.shouldOptimizeForNetworkUse = true
exporter.exportAsynchronously(completionHandler: {
if (exporter.error != nil) {
print("Error")
print(exporter.error)
print("Description")
print(exporter.description)
}
completionHandler(exporter.status)
if exporter.status == AVAssetExportSessionStatus.completed {
print ("videoURL: \(videoUrl)")
print ("outputURL: \(outputUrl)")
OperationQueue.main.addOperation({ () -> Void in
self.previewVideo(videoURL: outputUrl)
})
// upload the new output URL with text layer
//uploadVideoToMediaInfo(outputUrl, title: title ?? "\(Constants.userID)")
}
})
}
}
func previewVideo(videoURL: URL) {
self.avPlayer = AVPlayer(url: videoURL)
self.avPlayerViewController.player = self.avPlayer
self.avPlayerViewController.showsPlaybackControls = false
NotificationCenter.default.addObserver(self, selector: #selector(self.videoItemFinished(_:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: self.avPlayer?.currentItem)
self.present(self.avPlayerViewController, animated: true) { () -> Void in
self.avPlayerViewController.player?.play()
self.addContentOverlayView()
}
}
func videoItemFinished (_ notification: Notification) {
if !videoDismissed {
replayVideo()
}
}
func addContentOverlayView() {
overlayView.frame = CGRect(x: 0,y: 0,width: avPlayerViewController.view.bounds.width, height: avPlayerViewController.view.bounds.height)
overlayView.isHidden = false
overlayView.backgroundColor = UIColor.clear
let bottomMiddleRect = CGRect(x: (avPlayerViewController.view.bounds.width/2) - 30, y:avPlayerViewController.view.bounds.height - 100, width: 70, height: 70)
let uploadButton = UIButton(frame:bottomMiddleRect)
uploadButton.setTitle("", for: UIControlState())
uploadButton.setImage(UIImage(named: "Sort_Right_100"), for: .normal)
uploadButton.addTarget(self, action:#selector(uploadVideo), for: .touchUpInside)
overlayView.addSubview(uploadButton)
let cancelButton = UIButton(frame:CGRect(x: 5,y: 15,width: 60,height: 60))
cancelButton.setTitle("", for:UIControlState())
cancelButton.addTarget(self, action:#selector(closeVideo), for:.touchUpInside)
cancelButton.setImage(UIImage(named: "cancel_video_50"), for: UIControlState.normal)
overlayView.addSubview(cancelButton)
avPlayerViewController.view.addSubview(overlayView);
}
func replayVideo() {
// avPlayerViewController.player?.currentItem?.seek(to: kCMTimeZero)
// avPlayerViewController.player?.play()
}
func uploadVideo() {
print ("upload video pressed")
}
func closeVideo() {
overlayView.isHidden = true
videoDismissed = true
dismiss(animated: true, completion: nil)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment