gpt4 book ai didi

iphone - 保存太长的录制视频时,应用程序崩溃

转载 作者:可可西里 更新时间:2023-11-01 03:39:28 26 4
gpt4 key购买 nike

问题:

当保存在我的应用程序中录制的视频时,如果视频大小/持续时间太大/太长,我的应用程序会崩溃而不会出现日志/异常。

我的设置:

在我的应用程序中,我使用 UIImagePickerController 来录制视频。现在我注意到,如果我制作的视频长度非常长(例如,使用 UIImagePickerControllerQualityTypeMedium 时 30 分钟,或使用 UIImagePickerControllerQualityTypeIFrame1280x720 时超过一分钟),在保存视频时,应用程序会崩溃。有时有警告,有时没有警告。现在我开始调试并注意到它与内存有关(malloc_error)。

我使用探查器实时检查分配,并注意到当它要保存视频时,分配突然变得非常大(我猜与视频的临时内存使用有关?),然后它最终崩溃了。这是探查器的屏幕截图: Allocations screenshot

该应用必须能够录制最长 1 小时的视频(以任何指定的质量)。

我尝试过的:

  • 设置 picker.videoMaximumDuration 更短/更长
  • 使用分析器/仪器进行调试
  • 检查是否有泄漏
  • 关闭设备上所有打开的应用程序并删除应用程序(用于存储清理)以获取更多内存

代码:

- (void)openCamera:(id)sender context:(NSManagedObjectContext*)context {
self.context = context;
//Set self as delegate (UIImagePickerControllerDelegate)
[self.picker setDelegate:self];
//If the device has a camera
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.picker.allowsEditing = YES;
self.picker.videoQuality = [Settings videoQualitySetting];
//If the camera can record video
NSString *desired = (NSString *)kUTTypeMovie;
if ([[UIImagePickerController availableMediaTypesForSourceType:self.picker.sourceType] containsObject:desired]) {
//Let the user record video
self.picker.mediaTypes = [NSArray arrayWithObject:desired];
self.picker.videoMaximumDuration = MaxDuration;
}
else {
NSLog(@"Can't take videos with this device"); //debug
}
//Present the picker fullscreen/in popover
if ([Settings shouldDisplayFullScreenCamera]){
[self presentModalViewController:self.picker animated:YES];
[self.masterPopoverController dismissPopoverAnimated:YES];
}
else {
if (!_popover){
_popover = [[UIPopoverController alloc] initWithContentViewController:self.picker];
}
[_popover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
else {
NSLog(@"Does not have a camera"); //debug
}
}

以及在选择图像时的代码:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];

// Save the video, and close the overlay
if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0)
== kCFCompareEqualTo) {

self.tempVideoPath = [[info objectForKey:
UIImagePickerControllerMediaURL] path];
[LocalVideoStorage saveVideo:[NSData dataWithContentsOfPath:self.tempVideoPath name:self.videoName];
[_picker dismissModalViewControllerAnimated: YES];
[[_picker parentViewController] dismissModalViewControllerAnimated:YES];
[_popover dismissPopoverAnimated:YES];
}
}

最后,当它被保存时:

+ (NSString*)saveVideo:(NSData*)video:(NSString*)videoName {
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it

NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory

NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.MOV", videoName]]; //add our video to the path

[fileManager createFileAtPath:fullPath contents:video attributes:nil]; //finally save the path (video)

NSLog(@"Video saved!");
return fullPath;

}

我在 iOS 5.1.1 上使用 ARC

更新:我在 malloc_error_break 上设置了一个断点,在仪器中我可以看到它是从以下位置调用的:

#   Address Category    Timestamp   Live    Size    Responsible Library Responsible Caller
0 0x10900000 Malloc 473,29 MB 02:08.951.332 • 496283648 Foundation -[NSData(NSData) initWithContentsOfFile:]

解决方案:正如 lawicko & john.k.doe 所说,我试图将视频从它的路径加载到 NSData 变量中。这导致整个视频被加载到内存中。而不是这样做,我现在只是移动文件(并重命名)copyItemAtPath

NSError *error = nil;
if (![fileManager copyItemAtPath:path toPath:fullPath error:&error])
NSLog(@"Error: %@", error);

最佳答案

你的问题是这一行:

[NSData dataWithContentsOfPath:self.tempVideoPath]

你显然是想一次加载这个文件的内容到内存,但 iOS 永远不会让你一次加载那么多。您的 saveVideo 方法似乎只将文件从临时位置复制到文档目录。如果这是你唯一需要做的事情,那么看看 copyItemAtPath:toPath:error NSFileManager 的方法。您可以更改 saveVideo 方法以将临时文件路径而不是数据作为参数。

关于iphone - 保存太长的录制视频时,应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11051202/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com