Last active
December 1, 2016 01:27
-
-
Save makthrow/e532e1513b5c39bd325eefb74502d447 to your computer and use it in GitHub Desktop.
preview cam - dismiss view not working
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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