2

我为 ipad 制作了一个包含图像拖动和视频录制的应用程序。

它会在录制开始时截取屏幕截图,然后通过附加它们来制作电影。

当我录制 5 到 10 秒的视频时,它工作正常。但是当我尝试录制 1 分钟或更长时间的视频时,它会崩溃并"Received memory warning"输入日志。

我使用了以下代码;

- (IBAction)btnRecording_Pressed:(id)sender
{
    if ([recordButton.titleLabel.text isEqualToString:@"Start Recording"]) {
        backButton.enabled = NO;
        [recordButton setTitle:@"Stop Recording" forState:UIControlStateNormal];
        fileIndex = 0;
        recTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/5.0 target:self selector:@selector(startFrameCapture) userInfo:nil repeats:YES];
        [recTimer retain];
        [self startRecording];
    }else{
        [recordButton setTitle:@"Start Recording" forState:UIControlStateNormal];
        [recTimer invalidate];
        [recTimer release];
        [self stopRecording];
        [self getFileName];
    }
  }

-(void)startFrameCapture
{

    fileIndex++;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    documentsDirectory = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"Screenshot%d.jpg",fileIndex]];
    [self performSelectorInBackground:@selector(newThread:) withObject:documentsDirectory];


}

-(void)newThread:(NSString *)frameName{

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
        UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
    else
    UIGraphicsBeginImageContext(self.view.bounds.size);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];

    viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    imageData = UIImageJPEGRepresentation(viewImage, 1.0);
    [imageData writeToFile:frameName atomically:YES];

}

- (void) startRecording{
    if([recorder isRecording]){
        NSLog(@"Stopped Recording");
        [self stopRecording];
    }else{

        NSLog(@"Started Recording");
        [self prepareRecorderNow];
        [recorder record];
    }
}

- (void) stopRecording{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    if([recorder isRecording]){
        [recorder stop];
        [recorder release];
        recorder = nil;
    }
    [pool drain];
}

-(void)prepareRecorderNow{

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    NSError *err = nil;
    [audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
    if(err){
        NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
        return;
    }
    [audioSession setActive:YES error:&err];
    err = nil;
    if(err){
        NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
        return;
    }

    recordSetting = [[NSMutableDictionary alloc] init];

    [recordSetting setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
    [recordSetting setValue:[NSNumber numberWithFloat:44100] forKey:AVSampleRateKey];
    [recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

    [recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];

    // Create a new dated file

    [recorderFilePath release];
    recorderFilePath = [[NSString stringWithFormat:@"%@/deformed.caf", DOCUMENTS_FOLDER] retain];

    NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
    err = nil;
    recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];
    [recordSetting release];
    if(!recorder){
        NSLog(@"recorder: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
        UIAlertView *alert =
        [[UIAlertView alloc] initWithTitle: @"Warning"
                                   message: [err localizedDescription]
                                  delegate: nil
                         cancelButtonTitle:@"OK"
                         otherButtonTitles:nil];
        [alert show];
        [alert release];
        return;
    }

    //prepare to record
    [recorder setDelegate:self];
    [recorder prepareToRecord];
    recorder.meteringEnabled = YES;

    BOOL audioHWAvailable = audioSession.inputIsAvailable;
    if (! audioHWAvailable) {
        UIAlertView *cantRecordAlert =
        [[UIAlertView alloc] initWithTitle: @"Warning"
                                   message: @"Audio input hardware not available"
                                  delegate: nil
                         cancelButtonTitle:@"OK"
                         otherButtonTitles:nil];
        [cantRecordAlert show];
        [cantRecordAlert release];
        return;
    }
    NSLog(@"Not Over Man");

    [pool drain];
}

可能是什么问题?

谢谢!!

4

2 回答 2

0

在捕获图片的情况下我遇到了类似的问题,实际上,我已经看到了占用大部分内存的NOT RELEASED UIImage objects的问题,这是一个你可以尝试的修复

-(void)newThread:(NSString *)frameName
{
 UIImage *viewImage=nil;
 viewImage=[[UIImage alloc] init];
 if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
 else
    UIGraphicsBeginImageContext(self.view.bounds.size);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];

    viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    imageData = UIImageJPEGRepresentation(viewImage, 1.0);
    [imageData writeToFile:frameName atomically:YES];
    [viewImage release];

}
于 2013-02-07T13:44:53.890 回答
0

您每秒创建 5 次图像上下文。这可能是问题所在。

尝试通过将 UIGraphicsImageContext 保存为 ivar 或属性来重用它。

于 2013-02-06T14:30:41.790 回答