Cathy Oun
Cathy Oun

Reputation: 315

GPUImage input movieURL output filteredMovieURL

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

Answers (2)

Khush
Khush

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

JAck
JAck

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

Related Questions