Skip to content

Instantly share code, notes, and snippets.

@davidlondono
Created May 17, 2016 21:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidlondono/fedef4d1a42d9ad38657c3626c2b275d to your computer and use it in GitHub Desktop.
Save davidlondono/fedef4d1a42d9ad38657c3626c2b275d to your computer and use it in GitHub Desktop.
this is the inspiration original gist https://github.com/jai/VideoMerge
//
// VideoMerge.swift
// David Alejandro
//
// Created by David Alejandro on 5/12/16.
// Copyright © 2016 David Alejandro. All rights reserved.
//
// inpired by https://github.com/jai/VideoMerge
import AVFoundation
import AssetsLibrary
class Video: Equatable {
var assetURL: NSURL
init(url: NSURL) {
self.assetURL = url
}
}
func == (left: Video, right: Video) -> Bool {
return left.assetURL == left.assetURL
}
private extension Selector {
static let updateProgress = #selector(VideoMerge.updateProgress)
}
class VideoMerge: NSObject {
private var timerProgress: NSTimer?
var progressCallback: ((Float) -> ())?
var exporter: AVAssetExportSession?
func merge(sourceVideos: [Video], completition: (video: Video)->()) throws {
let composition = AVMutableComposition()
let track = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID:Int32(kCMPersistentTrackID_Invalid))
for (index, currentVideoObject) in sourceVideos.enumerate() {
let videoAsset = AVAsset(URL: currentVideoObject.assetURL)
let time: CMTime
if index == 0 {
time = kCMTimeZero
} else {
time = composition.duration
}
try track.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), ofTrack: videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0] , atTime: time)
}
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = NSURL(string: paths[0])!
let videoPathToSave = documentsDirectory.URLByAppendingPathComponent("mergeVideo-\(arc4random()%1000)-d.mp4")
let videoURLToSave = videoPathToSave
guard let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetMediumQuality) else { return }
self.exporter = exporter
exporter.outputURL = videoURLToSave
exporter.outputFileType = AVFileTypeMPEG4
exporter.shouldOptimizeForNetworkUse = true
exporter.exportAsynchronouslyWithCompletionHandler({self.timerProgress?.invalidate()
self.timerProgress = nil
self.progressCallback = nil
switch exporter.status {
case .Completed:
let video = Video(url: videoURLToSave)
completition(video: video)
case .Failed:
print("failed \(exporter.error)")
case .Cancelled:
print("cancelled \(exporter.error)")
default:
print("complete")
}
})
timerProgress = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: .updateProgress, userInfo: nil, repeats: true)
}
func updateProgress() {
if let exporter = exporter {
progressCallback?(exporter.progress)
}
}
}
@Shahbaz-Akram
Copy link

always export fail .How to handle this.

@Shahbaz-Akram
Copy link

How to call this merge method with sourcevideos type url

@mr-fixit
Copy link

func == (left: Video, right: Video) -> Bool should compare left to right, not left to left.

@chandu1987
Copy link

Does this work with airplay?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment