Couldn't write a frame when i swich background to foreground
zj381652512 opened this issue · 1 comments
when i swicth to background and foreground, i find that can not write a video frame...because GPUImageMovieWriter's assetWriter status is AVAssetWriterStatusFailed,
this my code:
#import "ZJCaptureVC.h"
#import "NSTimer+ZJWeakTimer.h"
#import "GPUImage.h"
@interface ZJCaptureVC ()
// GPUImage
@Property (nonatomic, strong) GPUImageVideoCamera *videoCamera;
@Property (nonatomic, strong) GPUImageOutput *filter;
@Property (nonatomic, strong) GPUImageMovieWriter *movieWriter;
@Property (nonatomic, strong) GPUImageView *filterView;
// UI
@Property (weak, nonatomic) IBOutlet UILabel *mLabel;
@Property (nonatomic, weak) NSTimer *mTimer;
@Property (nonatomic, assign) long mLabelTime;
@Property (weak, nonatomic) IBOutlet UIButton *endBtn;
// status
@Property (nonatomic, assign) BOOL recording;
// path
@Property (nonatomic, strong) NSString *pathToMovie;
@implementation ZJCaptureVC
-
(NSString *)pathToMovie {
if (!_pathToMovie) {
_pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/recordingmovie.mp4"];
}
return _pathToMovie;
} -
(void)viewDidLoad {
[super viewDidLoad];_videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
_videoCamera.outputImageOrientation = [UIApplication sharedApplication].statusBarOrientation;_filter = [[GPUImageSepiaFilter alloc] init];
_filterView = [[GPUImageView alloc] initWithFrame:self.view.bounds];
[self.view insertSubview:_filterView atIndex:0];[_videoCamera addTarget:_filter];
[_filter addTarget:_filterView];
[_videoCamera startCameraCapture];
}
#pragma mark - Actions
-
(IBAction)backClick:(UIButton *)sender {
[self.navigationController popViewControllerAnimated:YES];
} -
(IBAction)endClick:(UIButton *)sender {
[self endRecording];
} -
(IBAction)startClick:(UIButton *)sender {
sender.selected = !sender.selected;
if (sender.selected) {
[self startRecording];
} else {
[self pauseRecording];
}
} -
(void)onTimer:(id)sender {
_mLabel.text = [NSString stringWithFormat:@"录制时间:%lds", _mLabelTime++];
}
#pragma mark - Private
- (void)setRecording:(BOOL)recording {
_recording = recording;
_endBtn.hidden = !recording;
}
// 开始录制
-
(void)startRecording {
if (self.recording) {
self.movieWriter.paused = NO;
} else {
// 如果已经存在文件,AVAssetWriter会有异常,删除旧文件
NSURL *movieURL = [NSURL fileURLWithPath:self.pathToMovie];
unlink([self.pathToMovie UTF8String]);// 视频设置 CGFloat width = 480.f; CGFloat height = 640.f; NSInteger numPixels = width * height; CGFloat bitsPerPixel = 6.0; NSInteger bitsPerSecond = numPixels * bitsPerPixel; // 码率和帧率设置 NSDictionary *compressionProperties = @{ AVVideoAverageBitRateKey: @(bitsPerSecond), AVVideoExpectedSourceFrameRateKey: @(30), AVVideoMaxKeyFrameIntervalKey: @(30), AVVideoProfileLevelKey: AVVideoProfileLevelH264BaselineAutoLevel }; // 视频属性 NSDictionary *videoCompressionSettings = @{ AVVideoCodecKey: AVVideoCodecH264, AVVideoScalingModeKey: AVVideoScalingModeResizeAspectFill, AVVideoWidthKey: @(width), AVVideoHeightKey: @(height), AVVideoCompressionPropertiesKey: compressionProperties }; // 创建_movieWriter _movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(480.0, 640.0) fileType:AVFileTypeMPEG4 outputSettings:videoCompressionSettings]; _movieWriter.encodingLiveVideo = YES; _videoCamera.audioEncodingTarget = _movieWriter; [_filter addTarget:_movieWriter]; [_movieWriter startRecording]; self.recording = YES;
}
// 计时
_mTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
[self onTimer:nil];
}
// 暂停
- (void)pauseRecording {
if (!self.recording) {
NSLog(@"还没开始录制");
return;
}
if (_mTimer) {
[_mTimer invalidate];
}
_movieWriter.paused = YES;
}
// 完成录制
-
(void)endRecording {
if (!self.recording) {
NSLog(@"还没开始录制");
return;
}
if (_mTimer) {
[_mTimer invalidate];
}
[_filter removeTarget:_movieWriter];
_videoCamera.audioEncodingTarget = nil;[_movieWriter finishRecording];
self.recording = NO;if (self.completionHandler) {
self.completionHandler(self.pathToMovie);
}
[self.navigationController popViewControllerAnimated:YES];
}
GPUImageMovieWriter's assetWriter status is AVAssetWriterStatusFailed when app enter background...so we can solve it as below:
- (void)willEnterBackground:(NSNotification *)notification {
__weak typeof(self)weakSelf = self;
UIApplication *app = [UIApplication sharedApplication];
self.backgroundRenderingID = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:weakSelf.backgroundRenderingID];
weakSelf.backgroundRenderingID = UIBackgroundTaskInvalid;
}];
}