-(void)AVCaptureVideo{
//创建视频设备(摄像头前,后)
NSArray *devices = [AVCaptureDevicedevicesWithMediaType:AVMediaTypeVideo];
//初始化一个摄像头输入设备(first是后置摄像头,last是前置摄像头)
AVCaptureDeviceInput *inputVideo = [AVCaptureDeviceInputdeviceInputWithDevice:[devices firstObject] error:NULL];
//创建麦克风设备
AVCaptureDevice *deviceAudio = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeAudio];
//初始化麦克风输入设备
AVCaptureDeviceInput *inputAudio = [AVCaptureDeviceInputdeviceInputWithDevice:deviceAudioerror:NULL];
//初始化一个movie的文件输出
AVCaptureMovieFileOutput *output = [[AVCaptureMovieFileOutputalloc] init];
self.output = output;//保存output,方便下面操作
//初始化一个会话
AVCaptureSession *session = [[AVCaptureSessionalloc] init];
//将输入输出设备添加到会话中
if ([sessioncanAddInput:inputVideo]) {
[session addInput:inputVideo];
}
if ([sessioncanAddInput:inputAudio]) {
[session addInput:inputAudio];
}
if ([sessioncanAddOutput:output]) {
[session addOutput:output];
}
//添加一个视频预览图层,设置大小,添加到控制器view的图层上
//创建一个预览涂层
AVCaptureVideoPreviewLayer *preLayer = [AVCaptureVideoPreviewLayerlayerWithSession:session];
//设置图层的大小
preLayer.frame =self.view.bounds;
//添加到view上
[self.view.layeraddSublayer:preLayer];
//开始会话
[session startRunning];
}
#pragma mark ==============
#pragma mark ===录制按钮======
- (void)clickVideoBtn:(UIButton *)sender {
//判断是否在录制,如果在录制,就停止,并设置按钮title
if ([self.outputisRecording]) {
[self.outputstopRecording];
[sender setTitle:@"录制"forState:UIControlStateNormal];
return;
}
//设置按钮的title
[sender setTitle:@"停止"forState:UIControlStateNormal];
//设置录制视频保存的路径
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES).lastObjectstringByAppendingPathComponent:[NSStringstringWithFormat:@"%@.mov",[NSDatedate]]];
//转为视频保存的url
NSURL *url = [NSURLfileURLWithPath:path];
// UISaveVideoAtPathToSavedPhotosAlbum(path, nil, nil, nil);
//开始录制,并设置控制器为录制的代理
[self.outputstartRecordingToOutputFileURL:urlrecordingDelegate:self];
}
//清楚缓存
- (void)clickClearMemory{
NSString *path = [LBClearCacheToolgetCacheSizeWithFilePath: [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)lastObject]];
UIAlertController *alert=[UIAlertControlleralertControllerWithTitle:[NSStringstringWithFormat:@"确定清除%@缓存吗?",path]message:nilpreferredStyle:UIAlertControllerStyleActionSheet];
//创建一个取消和一个确定按钮
UIAlertAction *actionCancle=[UIAlertActionactionWithTitle:@"取消"style:UIAlertActionStyleCancelhandler:nil];
//因为需要点击确定按钮后改变文字的值,所以需要在确定按钮这个block里面进行相应的操作
UIAlertAction *actionOk=[UIAlertActionactionWithTitle:@"确定"style:UIAlertActionStyleDestructivehandler:^(UIAlertAction *_Nonnull action) {
//清楚缓存
BOOL isSuccess = [LBClearCacheToolclearCacheWithFilePath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)lastObject]];
if (isSuccess) {
[MBProgressHUDshowSuccess:@"清楚成功"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[MBProgressHUDhideAllHUDsForView:self.viewanimated:YES];
});
}
} ];
//将取消和确定按钮添加进弹框控制器
[alert addAction:actionCancle];
[alert addAction:actionOk];
//添加一个文本框到弹框控制器
//显示弹框控制器
[selfpresentViewController:alert animated:YEScompletion:nil];
}
#pragma mark - AVCaptureFileOutputRecordingDelegate
//录制完成代理
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
[MBProgressHUDshowSuccess:@"录制完成"];
[selfsetAlertView:outputFileURL];
}
#pragma mark ==============
#pragma mark ===输入框======
-(void)setAlertView:(NSURL *)inPutUrl{
UIAlertController *alert = [UIAlertControlleralertControllerWithTitle:@"输入视频名称"message:@""preferredStyle:(UIAlertControllerStyleAlert)];
[alert addTextFieldWithConfigurationHandler:^(UITextField*textField) {
textField.text = [NSStringstringWithFormat:@"%@",[NSDatedate]];
[textField addTarget:selfaction:@selector(changValue:)forControlEvents:(UIControlEventEditingChanged)];
self.videoName = textField.text;
}];
UIAlertAction *ok = [UIAlertActionactionWithTitle:@"确定"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_Nonnull action) {
[selfZIPVideo:inPutUrl VideoName:self.videoName];
}];
[alert addAction:ok];
[selfpresentViewController:alert animated:YEScompletion:nil];
}
#pragma mark ==============
#pragma mark ===视频压缩======
- (void) lowQuailtyWithInputURL:(NSURL*)inputURL
outputURL:(NSURL*)outputURL
blockHandler:(void (^)(AVAssetExportSession*))handler
{
AVURLAsset *asset = [AVURLAssetURLAssetWithURL:inputURL options:nil];
AVAssetExportSession *session = [[AVAssetExportSessionalloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];
session.outputURL = outputURL;
session.outputFileType =AVFileTypeQuickTimeMovie;
[session exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(session);
}];
}
-(void)ZIPVideo:(NSURL *)inputURl VideoName:(NSString *)videoName{
//设置录制视频保存的路径
NSString *outpath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES).lastObjectstringByAppendingPathComponent:[NSStringstringWithFormat:@"%@.mov",videoName]];
//转为视频保存的url
NSURL *outurl = [NSURLfileURLWithPath:outpath];
//把path添加到数组中(合并视频)
[self.videoPathArrayaddObject:outpath];
[selflowQuailtyWithInputURL:inputURl outputURL:outurl blockHandler:^(AVAssetExportSession *session)
{
if (session.status ==AVAssetExportSessionStatusCompleted)
{
NSLog(@"压缩成功");
}
else
{
NSLog(@"压缩失败");
}
}];
}
#pragma mark ==============
#pragma mark ===监听textfield======
-(void)changValue:(UITextField *)text{
self.videoName = text.text;
}
//视频合并按钮
-(void)clickMergeButton{
[selfmergeAndExportVideos:self.videoPathArraywithOutPath:[selfvideoPath]];
}
#pragma mark =====下面是合成视频的方法===========
- (void)mergeAndExportVideos:(NSArray*)videosPathArray withOutPath:(NSString*)outpath{
if (videosPathArray.count ==0) {
[MBProgressHUDshowError:@"请录制视频"];
return;
}
[MBProgressHUDshowMessage:@"合并中..."toView:self.view];
AVMutableComposition *mixComposition = [[AVMutableCompositionalloc] init];
AVMutableCompositionTrack *audioTrack = [mixCompositionaddMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *videoTrack = [mixCompositionaddMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
//视频旋转270(视频合并后默认旋转了-90度)详情请参考(http://www.cnblogs.com/alby/p/4610077.html)
videoTrack.preferredTransform =CGAffineTransformMake(0,1.0, -1.0,0, 0,0);
CMTime totalDuration =kCMTimeZero;
for (int i =0; i < videosPathArray.count; i++) {
AVURLAsset *asset = [AVURLAssetassetWithURL:[NSURLfileURLWithPath:videosPathArray[i]]];
NSError *erroraudio =nil;
//获取AVAsset中的音频或者视频
AVAssetTrack *assetAudioTrack = [[assettracksWithMediaType:AVMediaTypeAudio]firstObject];
//向通道内加入音频或者视频
[audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
ofTrack:assetAudioTrack
atTime:totalDuration
error:&erroraudio];
// NSLog(@"erroraudio:%@",erroraudio);
NSError *errorVideo =nil;
AVAssetTrack *assetVideoTrack = [[assettracksWithMediaType:AVMediaTypeVideo]firstObject];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
ofTrack:assetVideoTrack
atTime:totalDuration
error:&errorVideo];
// NSLog(@"errorVideo:%@",errorVideo);
totalDuration = CMTimeAdd(totalDuration, asset.duration);
}
NSURL *mergeFileURL = [NSURLfileURLWithPath:outpath];
AVAssetExportSession *exporter = [[AVAssetExportSessionalloc] initWithAsset:mixComposition
presetName:AVAssetExportPresetMediumQuality];
exporter.outputURL = mergeFileURL;
exporter.outputFileType =AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse =YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{
if (exporter.error !=nil) {
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUDhideHUDForView:self.view];
[MBProgressHUDshowSuccess:@"合并失败"];
});
NSLog(@"合并失败");
}else{
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUDhideHUDForView:self.view];
[MBProgressHUDshowSuccess:@"合并成功"];
});
NSLog(@"合并成功");
}
//保存到相册
// UISaveVideoAtPathToSavedPhotosAlbum([mergeFileURL path], nil, nil, nil);
}];
}
//路径
- (NSString *)videoPath {
NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)firstObject];
NSString *moviePath = [basePathstringByAppendingPathComponent:[NSStringstringWithFormat:@"qqq%@.mov",[NSDatedate]]];
return moviePath;
}