In my Application I need to put Image on the video. The Size of Image and video are same. Video size is fix = 1080 x 1080 Image Size is fix = 1080 x 1080
My problem is blur video when i share on whatsapp status. I have check other applications also but it not too much low compress. But in my case it too much lower quality.
I am Export video in AVAssetExportPresetHighestQuality.
Please suggest me any github link which is add image on video.
URL path :
NSURL *filepath = [NSURL URLWithString:self.video_url];
Mix Composition :
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:filepath options:nil];
AVMutableComposition* mixComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *clipAudioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
//If you need audio as well add the Asset Track for audio here
CGSize firstvideoSize = clipVideoTrack.naturalSize;
CGSize videoSize = clipVideoTrack.naturalSize;
UIInterfaceOrientation mode = [self checkVideoTrack:videoAsset];
if (mode == UIInterfaceOrientationPortrait)
{
if(firstvideoSize.height<=firstvideoSize.width)
{
videoSize.height=firstvideoSize.width;
videoSize.width=firstvideoSize.height;
}
}
else if(mode == UIInterfaceOrientationLandscapeLeft)
{
if(firstvideoSize.height>=firstvideoSize.width)
{
videoSize.height=firstvideoSize.width;
videoSize.width=firstvideoSize.height;
}
}
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipVideoTrack atTime:kCMTimeZero error:nil];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil];
[compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]];
Create Image Layer :
UIImage *myImage = image;
CALayer *aLayer = [CALayer layer];
aLayer.contents = (id)myImage.CGImage;
aLayer.frame = CGRectMake(0,0, image.size.width, image.size.height); //Needed for proper display. We are using the app icon (57x57). If you use 0,0 you will not see it
aLayer.contentsGravity=kCAGravityResizeAspectFill;
aLayer.opacity = 1.0; //Feel free to alter the alpha here
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
videoLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:aLayer];
AVMutableVideoComposition* videoComp = [AVMutableVideoComposition videoComposition];
videoComp.renderSize = videoSize;
videoComp.frameDuration = CMTimeMake(1, 30);
videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
instruction
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mixComposition duration]);
AVAssetTrack *videoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
videoComp.instructions = [NSArray arrayWithObject: instruction];
AVAssetExportSession *_assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
_assetExport.videoComposition = videoComp;
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
NSString *stringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:@"Videos"];
// New Folder is your folder name
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:stringPath])
[[NSFileManager defaultManager] createDirectoryAtPath:stringPath withIntermediateDirectories:NO attributes:nil error:&error];
NSString *saveFilePath = [NSString stringWithFormat:@"Videos/%@",[self generateFileNameWithExtension:@".mp4"]];
NSURL *exportUrl = [documentsDirectoryURL URLByAppendingPathComponent:saveFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:exportUrl.path])
{
[[NSFileManager defaultManager] removeItemAtPath:exportUrl.path error:nil];
}
_assetExport.outputFileType = AVFileTypeMPEG4;
_assetExport.outputURL = exportUrl;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void ) {
switch (_assetExport.status)
{
case AVAssetExportSessionStatusUnknown:
NSLog(@"AVAssetExportSessionStatusUnknown");
break;
case AVAssetExportSessionStatusWaiting:
NSLog(@"AVAssetExportSessionStatusWaiting");
break;
case AVAssetExportSessionStatusExporting:
NSLog(@"AVAssetExportSessionStatusExporting");
break;
case AVAssetExportSessionStatusCompleted:
NSLog(@"AVAssetExportSessionStatusCompleted");
break;
case AVAssetExportSessionStatusFailed:
NSLog(@"AVAssetExportSessionStatusFailed");
break;
case AVAssetExportSessionStatusCancelled:
NSLog(@"AVAssetExportSessionStatusCancelled");
break;
}
dispatch_async(dispatch_get_main_queue(), ^{
[self saveVideoWithURL:exportUrl];
});
}];
Save Video With URL :
- (void)saveVideoWithURL:(NSURL *)filePath {
[[[ALAssetsLibrary alloc] init] writeVideoAtPathToSavedPhotosAlbum:filePath completionBlock:^(NSURL *assetURL, NSError *error) {
if(assetURL) {
[self.navigationController.view makeToast:@"Save video successfully in gallery"
duration:1.0
position:CSToastPositionBottom];
} else {
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:@"Error"
message:@"something went wrong"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:@"Ok"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
}];
[alert addAction:yesButton];
[self presentViewController:alert animated:YES completion:nil];
}
}];
}