Reputation: 315
I am able to show the current filtered video on GPUImageView. BUT I can't save it using GPUImageMovieWriter. (Or I just dont know how..)
My goal is to feed in a VideoURL and get the filteredVideo output URL. THEN I will play the filtered video.
This is what I have currently
static func createFilterMovie(videoURL url: NSURL?, filteredView: GPUImageView, completion completionHandler: (movieURL: NSURL?) -> Void) {
let gpuMovie = GPUImageMovie(URL: url)
gpuMovie.playAtActualSpeed = true
filteredView.fillMode = kGPUImageFillModePreserveAspectRatioAndFill
let filter = GPUImageGrayscaleFilter()
gpuMovie.addTarget(filter)
gpuMovie.playAtActualSpeed = true
filter.addTarget(filteredView)
// save
let filteredFile = NSHomeDirectory().stringByAppendingString("Documents/Movie.m4v")
unlink(NSString(string: filteredFile).UTF8String)
let movieURL = NSURL.fileURLWithPath(filteredFile)
gpuMovie.startProcessing()
completionHandler(movieURL: movieURL)
}
Upvotes: 1
Views: 609
Reputation: 181
I have Used following code to save video, I hope it helped
Declare GPUImageMovie and GPUImageMovieWriter as followed:
private var gpuMovie: GPUImageMovie = GPUImageMovie()
private var movieWriter: GPUImageMovieWriter!
Save Video using Following Code:
gpuMovie.removeAllTargets()
gpuMovie = GPUImageMovie(url: videoURL)
let filter = GPUImageThresholdSketchFilter()
gpuMovie.addTarget(filter)
gpuMovie.playAtActualSpeed = true
filter.addTarget(filterView)
gpuMovie.runBenchmark = true
let documentsPath: String = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask,true)[0] as String
let exportPath: String = documentsPath.appendingFormat("/ExportedVideo.mov")
let exportUrl: URL = NSURL.fileURL(withPath: exportPath as String)
let asset = AVURLAsset(url: videoURL!, options: nil)
let videoAssetTrack: AVAssetTrack = asset.tracks(withMediaType: .video)[0]
unlink(exportUrl.path)
print(exportUrl)
let videoSettings: NSDictionary = [AVVideoCodecKey: AVVideoCodecH264 , AVVideoWidthKey: 720 , AVVideoHeightKey: 1080, AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey: 6000000, AVVideoProfileLevelKey: AVVideoProfileLevelH264High40]]
movieWriter = GPUImageMovieWriter.init(movieURL: exportUrl, size: CGSize(width: videoAssetTrack.naturalSize.width, height: videoAssetTrack.naturalSize.height), fileType: AVFileType.mp4.rawValue, outputSettings: videoSettings as! [AnyHashable : Any])
filter.addTarget(movieWriter)
movieWriter.shouldPassthroughAudio = true
movieWriter.startRecording()
gpuMovie.startProcessing()
Note: videoURL is your video's Import URL
Upvotes: 1
Reputation: 854
Here is the solution.. Code like below..
But First please keep the thing in mind htta first you need to only play video (Filtered). Then once you need you can save it also. Because there are more than one filters in your app. So each and every time if you will save it it causes memory problem or loading issues. So first only apply filters on video which is playing With GPUImage Filter then you can save it. I am putting both code below :
// 1. Code for playing Video on GPUMovieView.
self.playerItem = AVPlayerItem(URL: NSURL(fileURLWithPath: filePath))
self.player = AVPlayer(playerItem: self.playerItem)
self.movieView = GPUImageView(frame: self.vview.frame)
self.player.replaceCurrentItemWithPlayerItem(self.playerItem)
self.movieFile = GPUImageMovie(playerItem: self.playerItem)
self.movieFile.runBenchmark = true
self.movieFile.playAtActualSpeed = true
self.movieFile.addTarget(self.filter)
self.filter.addTarget(self.movieView)
self.movieFile.startProcessing()
self.view.addSubview(self.movieView)
// self.view.sendSubviewToBack(self.movieView)
self.movieRunning = true
self.player.play()
And to save that video code like below :
self.movieFile = GPUImageMovie(URL: NSURL(fileURLWithPath: filePath))
self.movieFile.runBenchmark = true
self.movieFile.playAtActualSpeed = false
self.movieFile.addTarget(self.filter)
let Data = NSData(contentsOfURL: NSURL(fileURLWithPath: filePath))
let anAsset = AVAsset(URL: NSURL(fileURLWithPath: filePath))
let vanasset = anAsset.tracksWithMediaType(AVMediaTypeVideo)[0]
print(vanasset.naturalSize)
let orientation : UIInterfaceOrientation = self.orientationForTrack(anAsset)
print(orientation)
if orientation == .Portrait
{
filter.setInputRotation(.RotateRight, atIndex: 0)
}
else if orientation == .LandscapeRight {
filter.setInputRotation(.Rotate180, atIndex: 0)
}
else if orientation == .PortraitUpsideDown {
filter.setInputRotation(.RotateLeft, atIndex: 0)
}
let videoAssetTrack = anAsset.tracksWithMediaType(AVMediaTypeVideo)[0]
var naturalSize = CGSize()
naturalSize = vanasset.naturalSize
self.movieWriter = GPUImageMovieWriter(movieURL: NSURL(fileURLWithPath:pathToMovie), size: p)
let input : GPUImageOutput!
input = self.filter
input.addTarget(self.movieWriter)
self.movieWriter.shouldPassthroughAudio = true
if anAsset.tracksWithMediaType(AVMediaTypeAudio).count > 0 {
self.movieFile.audioEncodingTarget = self.movieWriter
}
else
{
self.movieFile.audioEncodingTarget = nil
}
self.movieFile.enableSynchronizedEncodingUsingMovieWriter(self.movieWriter)
self.movieWriter.startRecording()
self.movieFile.startProcessing()
self.movieWriter.completionBlock =
{() -> Void in
self.movieWriter.finishRecording()
self.movieFile.cancelProcessing()
input.removeAllTargets()
self.movieFile.removeAllTargets()
}
Try above codes and if you need any help feel free to ask me.
Upvotes: 3