iOS保存录制视频并上传服务器

一、获取视频输入设备

      
      
1
2
3
4
5
6
7
8
9
10
11
      
      
//视频输入设备
-(AVCaptureDeviceInput *)getVideoInput
{
NSError *error = nil;
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionFront];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
return input;
}

二、配置输出

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
      
      
//视频输出
-(AVCaptureVideoDataOutput *)getVideoOutputWithQueue:(dispatch_queue_t)queue
{
if(_videoOutput != nil){
return _videoOutput;
}
_videoOutput = [[AVCaptureVideoDataOutput alloc] init];
_videoOutput.alwaysDiscardsLateVideoFrames = YES;
NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithInt:240], (id)kCVPixelBufferWidthKey,
[NSNumber numberWithInt:320], (id)kCVPixelBufferHeightKey,
[NSNumber numberWithInt:kCVPixelFormatType_32BGRA],(id)kCVPixelBufferPixelFormatTypeKey,
nil];
_videoOutput.videoSettings = settings;
[_videoOutput setSampleBufferDelegate:self queue:queue];
return _videoOutput;
}

三、初始化AVCaptureSession

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
      
      
-(void)setupSession{
//初始化session
_captureSession = [[AVCaptureSession alloc]init];
//设置输入输出格式(也会影响预览效果)
[_captureSession setSessionPreset:AVCaptureSessionPresetMedium];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionFront];
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
[_captureSession addInput:deviceInput];
//传入一个线程
dispatch_queue_t videoQueue = dispatch_queue_create("theQueue", NULL);
[_captureSession addOutput:[self getVideoOutputWithQueue:videoQueue]];
[_captureSession startRunning];
}

四、设置预览层

      
      
1
2
3
4
5
6
7
8
9
10
11
12
      
      
-(void)setupPreviewLayer{
_previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:_captureSession];
_previewLayer.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:_previewLayer];
self.view.layer.masksToBounds = YES;
}

五、设置AVAssetWriter

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
      
      
-(AVAssetWriter *)setMediaWriter
{
NSString *videoString = [NSString stringWithFormat:@"xxx.mov"];
NSLog(@"%@",videoString);
NSString *path = [NSTemporaryDirectory() stringByAppendingString:videoString];
NSURL *url = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:videoString]];
//首先判断当前文件的路径是否存在,如果存在则删除文件
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSLog(@"already exists");
NSError *error;
if ([[NSFileManager defaultManager] removeItemAtPath:path error:&error] == NO) {
NSLog(@"removeitematpath %@ error :%@", path, error);
}
}
NSError *error = nil;
//文件保存到沙盒
_assetWriter = [[AVAssetWriter alloc] initWithURL:url fileType:AVFileTypeQuickTimeMovie error:&error];
//AVVideoAverageBitRateKey,每秒钟多少bits,仅用于H264
int bitRate = 256 * 1024;
NSDictionary *codecSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:bitRate], AVVideoAverageBitRateKey,
nil];
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:480], AVVideoWidthKey,
[NSNumber numberWithInt:320], AVVideoHeightKey,
codecSettings, AVVideoCompressionPropertiesKey,
nil];
_videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
_videoWriterInput.expectsMediaDataInRealTime = YES;
[_assetWriter addInput:_videoWriterInput];
return _assetWriter;
}

六、代理中写入文件

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
      
      
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
if(!CMSampleBufferDataIsReady(sampleBuffer)){
NSLog( @"sample buffer is not ready. Skipping sample" );
return;
}
//设置写入器的写入时间,开启写入
if (_assetWriter.status == AVAssetWriterStatusUnknown)
{
CMTime startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
[_assetWriter startWriting];
[_assetWriter startSessionAtSourceTime:startTime];
//此时_assetWriter.status为1
NSLog(@"%ld",(long)_assetWriter.status);
}
if(_assetWriter.status == AVAssetWriterStatusFailed){
NSLog(@"error - %@",_assetWriter.error);
}
//判断如果正在读取,则直接写入
if(_assetWriter.status == AVAssetWriterStatusWriting){
//写入视频
if([captureOutput isKindOfClass:[_videoOutput class]]){
[_videoWriterInput appendSampleBuffer:sampleBuffer];
}
}
}

七、上传服务器

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
      
      
-(void)uploadDataToServer{
//字符串乱序
NSString *fineNameString = [[NSString alloc]init];
for (int i = 0; i < 32; i++) {
int number = arc4random() % 36;
if (number < 10) {
int figure = arc4random() % 10;
NSString *tempString = [NSString stringWithFormat:@"%d", figure];
fineNameString = [fineNameString stringByAppendingString:tempString];
}else {
int figure = (arc4random() % 26) + 97;
char character = figure;
NSString *tempString = [NSString stringWithFormat:@"%c", character];
fineNameString = [fineNameString stringByAppendingString:tempString];
}
}
//通过AFN上传数据到服务器
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", @"video/mov", nil];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
//服务器地址
NSString *uploadAddress = @"http://188.188.188.188:10898/video";
[manager POST:uploadAddress parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/xxx.mov"];
NSData *videoData = [NSData dataWithContentsOfFile:path];
NSString *fileName = [NSString stringWithFormat:@"%@.mov",fineNameString];
//formData的其他append方法上传文件失败
[formData appendPartWithFileData:videoData name:@"xxx.mov" fileName:fileName mimeType:@"video/mov"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"视频上传成功 %@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"视频上传失败 %@", error);
}];
}

猜你喜欢

转载自www.cnblogs.com/wangziqiang123/p/11711222.html