I am working on a personal iOS project that requires a full-screen video (15 seconds long) to upload to the backend via a 4G connection. Although I can shoot the video just fine, the output file size is 30 MB, which makes me think that I am doing something completely wrong when it comes to compression. Below is the code that I use to create AssetWriter:
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections
{
NSLog(@"Started Recording! *******************");
self.movieWriter = [AVAssetWriter assetWriterWithURL:fileURL fileType:AVFileTypeMPEG4 error:nil];
[self.movieWriter setShouldOptimizeForNetworkUse:YES];
NSDictionary *videoCleanApertureSettings = @{
AVVideoCleanApertureWidthKey: [NSNumber numberWithFloat:self.view.frame.size.width],
AVVideoCleanApertureHeightKey: [NSNumber numberWithFloat:self.view.frame.size.height],
AVVideoCleanApertureHorizontalOffsetKey: [NSNumber numberWithInt:10],
AVVideoCleanApertureVerticalOffsetKey: [NSNumber numberWithInt:10],
};
NSDictionary *videoCompressionSettings = @{
AVVideoAverageBitRateKey: [NSNumber numberWithFloat:5000000.0],
AVVideoMaxKeyFrameIntervalKey: [NSNumber numberWithInteger:1],
AVVideoProfileLevelKey: AVVideoProfileLevelH264Baseline30,
AVVideoCleanApertureKey: videoCleanApertureSettings,
};
NSDictionary *videoSettings = @{AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey: [NSNumber numberWithFloat:self.view.frame.size.width],
AVVideoHeightKey: [NSNumber numberWithFloat:self.view.frame.size.height],
AVVideoCompressionPropertiesKey: videoCompressionSettings,
};
self.movieWriterVideoInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
self.movieWriterVideoInput.expectsMediaDataInRealTime = YES;
[self.movieWriter addInput:self.movieWriterVideoInput];
NSDictionary *audioSettings = @{AVFormatIDKey: [NSNumber numberWithInteger:kAudioFormatMPEG4AAC],
AVSampleRateKey: [NSNumber numberWithFloat:44100.0],
AVNumberOfChannelsKey: [NSNumber numberWithInteger:1],
};
self.movieWriterAudioInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio outputSettings:audioSettings];
self.movieWriterAudioInput.expectsMediaDataInRealTime = YES;
[self.movieWriter addInput:self.movieWriterAudioInput];
[self.movieWriter startWriting];
}
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
NSLog(@"Done Recording!");
[self.movieWriterVideoInput markAsFinished];
[self.movieWriterAudioInput markAsFinished];
[self.movieWriter finishWritingWithCompletionHandler:^{
AVURLAsset *compressedVideoAsset = [[AVURLAsset alloc] initWithURL:self.movieWriter.outputURL options:nil];
}];
}
To configure the actual session, I use the following code:
[self.captureSession beginConfiguration];
self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
AVCaptureInput* currentCameraInput = [self.captureSession.inputs objectAtIndex:0];
for (AVCaptureInput *captureInput in self.captureSession.inputs) {
[self.captureSession removeInput:captureInput];
}
AVCaptureDevice *videoCamera = nil;
if(((AVCaptureDeviceInput*)currentCameraInput).device.position == AVCaptureDevicePositionBack)
{
videoCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];
}
else
{
videoCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];
}
AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:videoCamera error:nil];
[self.captureSession addInput:newVideoInput];
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];
[self.captureSession addInput:audioInput];
for (AVCaptureOutput *output in self.captureSession.outputs) {
[self.captureSession removeOutput:output];
}
self.movieOutput = [AVCaptureMovieFileOutput new];
int32_t preferredTimeScale = 30;
self.movieOutput.maxRecordedDuration = CMTimeMakeWithSeconds(15, preferredTimeScale);
[self.captureSession addOutput:self.movieOutput];
[self.captureSession commitConfiguration];
, AVCaptureSessionPresetHigh , , , , AVCaptureSessionPresetiFrame1280x720 - , , ( 20 4G).
Stack Overflow, , , .