自定义裁剪视频

1,621 阅读1分钟

//自定义裁剪视频
+ (void)getclipingVideoWithVideoAsset:(AVAsset *)asset
							  success:(void (^)(NSString *))success
							  failure:(void (^)(NSString *))failure{

	NSString *outPutPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"/video/video1.mp4"];
	NSLog(@"video outputPath:\n %@\n",outPutPath);

	AVAssetReader *reader = [AVAssetReader assetReaderWithAsset:asset error:nil];
	AVAssetWriter *write = [AVAssetWriter assetWriterWithURL:[NSURL URLWithString:outPutPath] fileType:AVFileTypeMPEG4 error:nil];

	//video part
	AVAssetTrack *videoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;
	AVAssetReaderTrackOutput *videoOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:videoTrack outputSettings:[self videoOutputSettings]];//输出
	AVAssetWriterInput *videoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:[self videoCompressSettings]];//输入
	if ([reader canAddOutput:videoOutput]) {
		[reader addOutput:videoOutput];
	}
	if ([write canAddInput:videoInput]) {
		[write addInput:videoInput];
	}

	//audio part
	AVAssetTrack *audioTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;
	AVAssetReaderTrackOutput *audioOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:audioTrack outputSettings:[self audioOutputSettings]];
	AVAssetWriterInput *audioInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:[self audioCompressSettings]];
	if ([reader canAddOutput:audioOutput]) {
		[reader addOutput:audioOutput];
	}
	if ([write canAddInput:audioInput]) {
		[write addInput:audioInput];
	}

	//开始读写
	[reader startReading];
	[write startWriting];
	[write startSessionAtSourceTime:kCMTimeZero];

	dispatch_queue_t video_compression_queue = dispatch_queue_create("com.video_compression_queue.queue", NULL);
	dispatch_queue_t audio_compression_queue = dispatch_queue_create("com.video_compression_queue.queue", NULL);

	dispatch_group_t group = dispatch_group_create();
	//视频逐帧写入
	dispatch_group_enter(group);
	[videoInput requestMediaDataWhenReadyOnQueue:video_compression_queue usingBlock:^{
		while ([videoInput isReadyForMoreMediaData]) {
			CMSampleBufferRef sampleBuffer;
			if (reader.status == AVAssetReaderStatusReading && (sampleBuffer = [videoOutput copyNextSampleBuffer])) {
				BOOL reslut = [videoInput appendSampleBuffer:sampleBuffer];
				CFRelease(sampleBuffer);
				if (!reslut) {
					[reader cancelReading];
					break;
				}
			}else{
				[videoInput markAsFinished];
				dispatch_group_leave(group);
				break;
			}
		}
	}];

	//音频逐帧写入
	dispatch_group_enter(group);
	[audioInput requestMediaDataWhenReadyOnQueue:audio_compression_queue usingBlock:^{
		while ([audioInput isReadyForMoreMediaData]) {
			CMSampleBufferRef sampleBuffer;
			if (reader.status == AVAssetReaderStatusReading && (sampleBuffer = [audioOutput copyNextSampleBuffer])) {
				BOOL result = [audioInput appendSampleBuffer:sampleBuffer];
				if (!result) {
					[reader cancelReading];
					break;
				}
			}else{
				[audioInput markAsFinished];
				dispatch_group_leave(group);
				break;
			}
		}
	}];

	//完成压缩
	dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
		if (reader.status == AVAssetReaderStatusReading) {
			[reader cancelReading];
		}
		switch (write.status) {
			case AVAssetWriterStatusWriting:{

				[write finishWritingWithCompletionHandler:^{
					NSLog(@"the size video at %@ is %0.2f M",outPutPath, [NSString getFileSize:outPutPath]);
				}];

				}break;
			default:
				break;
		}
	});

}

//视频输出配置
+(NSDictionary *)videoOutputSettings{
	NSDictionary *videoOutputSettings = @{
		(id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_422YpCbCr8),
		(id)kCVPixelBufferIOSurfacePropertiesKey :@{}
	};
	return videoOutputSettings;
}

//视频输入配置
+(NSDictionary *)videoCompressSettings{
	NSDictionary *compressionProperties = @{
		AVVideoAverageBitRateKey:@(200 * 8 * 1024),
		AVVideoExpectedSourceFrameRateKey:@25,
		AVVideoProfileLevelKey : AVVideoProfileLevelH264HighAutoLevel
	};
	NSDictionary *videoCompressSettings = @{
		AVVideoCodecKey : UIDevice.systemVersion >= 11.0 ? AVVideoCodecTypeH264:AVVideoCodecH264,
		AVVideoWidthKey : @960,
		AVVideoHeightKey : @540,
		AVVideoCompressionPropertiesKey : compressionProperties,
		AVVideoScalingModeKey : AVVideoScalingModeResizeAspectFill
	};
	return videoCompressSettings;
}

//音频输出配置
+(NSDictionary *)audioOutputSettings{
	NSDictionary *audioOutputSettings = @{
		AVFormatIDKey : @(kAudioFormatLinearPCM)
 	};
	return audioOutputSettings;
}

//音频输入配置
+(NSDictionary *)audioCompressSettings{
	AudioChannelLayout stereoChannelLayout = {
		.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo,
		.mChannelBitmap = 0,
		.mNumberChannelDescriptions = 0
	};
	NSData *channelLayoutAsData = [NSData dataWithBytes:&stereoChannelLayout length:offsetof(AudioChannelLayout, mChannelDescriptions)];
	NSDictionary *audioCompressSettings = @{
		AVFormatIDKey : @(kAudioFormatMPEG4AAC),
		AVEncoderBitRateKey:@96000,
		AVSampleRateKey:@44100,
		AVChannelLayoutKey: channelLayoutAsData,
		AVNumberOfChannelsKey : @2
	};
	return audioCompressSettings;
}