Search code examples
iosobjective-cvideogpuimagecifilter

Objective-c how to add filter to an existing video like Instagram Application?


I'm trying to add filter to video after recording it, just like Instagram. After searching for a way I found GPUImage, but that didn't solve it since in this code the video is being written to directory before displaying it (causing delay):

//Setting path for temporary storing the video in document directory
NSURL *movieURL = [self dataFilePath: @"tempVideo.mp4"]; // url where we want to save our new edited video

Is there a way to preview the filtered video before saving it in order not to take time? If so, how it is done?

Also, I found in the apple documentation about CIFilter but still can not find a way that states how to add filters to the video.

In addition, that there are some codes but written in swift.

Thanks in advance.


Solution

  • I couldn't find a way to stop the delay that is happing with the GPUImage. So I tried working with the SCRecorder.

    What I have done is:

    [_player setItemByUrl:videoURL];
    

    instead of:

    [_player setItemByAsset:_recordSession.assetRepresentingSegments];
    

    by this way I'm able to play and add filter to an existing video just like Instagram.

    To export the video with the chosen filter I used this code:

     - (void)saveToCameraRoll {
    
      NSString *fileName = videoURL.lastPathComponent;
      NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
      NSString *docsDir = [dirPaths objectAtIndex:0];
      NSString *videoPath = [NSString stringWithFormat:@"%@/%@",docsDir,fileName];
      NSURL *urlPath = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@", videoPath]];
    
      NSURL *assetUrl = urlPath;
      AVAsset *asset = [AVAsset assetWithURL:assetUrl];
      SCFilter *exportFilter = [self.filterSwitcherView.selectedFilter copy];
    
      SCAssetExportSession *exportSession = [[SCAssetExportSession alloc] initWithAsset:asset];
      NSURL *urlFile = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@.mov",docsDir,fileName]];
      exportSession.outputUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@",urlFile]];
    
      filterURL = exportSession.outputUrl;
    
      exportSession.videoConfiguration.filter = exportFilter;
      exportSession.videoConfiguration.preset = SCPresetHighestQuality;
      exportSession.audioConfiguration.preset = SCPresetHighestQuality;
      exportSession.videoConfiguration.maxFrameRate = 35;
      exportSession.outputFileType = AVFileTypeMPEG4;
      exportSession.delegate = self;
      exportSession.contextType = SCContextTypeAuto;
      self.exportSession = exportSession;
    
      [exportSession exportAsynchronouslyWithCompletionHandler:^{
          if (exportSession.error == nil) {
              [[UIApplication sharedApplication] beginIgnoringInteractionEvents];
              [exportSession.outputUrl saveToCameraRollWithCompletion:^(NSString * _Nullable path, NSError * _Nullable error) {
                  [[UIApplication sharedApplication] endIgnoringInteractionEvents];
    
                  if (error == nil) {
                    //Success
                  }
              }];
    
          } else {
              NSLog(@"Error: %@", exportSession.error);
          }
      }];
    }