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

画像コンテキストを 1 秒あたり 5 回作成しています。それが問題かもしれません。

UIGraphicsImageContext を ivar またはプロパティとして保存して再利用してみてください。

于 2013-02-06T14:30:41.790 に答える
0

写真のキャプチャの場合にも同様の問題がありました。実際には、ほとんどのメモリを占有するNOT RELEASED UIImage オブジェクトの問題を見てきました。ここで試すことができる修正があります

-(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 に答える