在 UITableViewCell 中播放 MPMoviePlayerController 会导致应用冻结和崩溃
Playing MPMoviePlayerController in UITableViewCell causes app to freeze and crash
在我正在使用的应用程序中,我们将 MPMovePlayerController
添加到 UITableViewCell
,然后自动播放它。问题是,调用 prepareToPlay
and/or play
导致应用程序冻结,CPU 达到最大值,RAM 不断增加,应用程序当然会在一段时间后崩溃。如果我注释掉不会发生的 prepareToPlay
和 play
,那么我看到的只是一个没有播放控件的黑框。
我们在 cellForRowAtIndexPath
中创建 MPMoviePlayerController
并将其存储到一个数组中,因为我们可能在 table 中有多个视频,并且需要能够播放正确的视频按需点击一个或停止一个。首次加载 table 时,视频加载和播放没有问题。用户可以通过模态视图控制器演示添加视频,这将在将视频添加到数据源后重新加载 table。只有在用户添加新视频后才会出现此问题。
我尝试在单元格中为播放器存储 属性,但这并没有解决问题。我已经尝试按照其他地方的建议在设置 contentURL
之前调用 stop
,这也没有帮助。还尝试了 4 个不同的视频,每个视频都有不同的格式,以防它是损坏的视频。我不确定是什么问题。
//Table view controller:
@interface {
NSMutableArray *arrayOfMoviePlayers;
}
viewDidLoad {
arrayOfMoviePlayers = [NSMutableArray new];
}
cellForRowAtIndexPath {
MyTableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc]init];
[arrayOfMoviePlayers addObject:moviePlayer];
cell = [[MyTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell" withDictionary:dict withMoviePlayer:moviePlayer];
return cell;
}
//Cell subclass:
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier withDictionary:(NSDictionary*)dict withMoviePlayer:(MPMoviePlayer *)moviePlayer {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
moviePlayer.view.frame = self.contentView.bounds;
[self.contentView addSubview:moviePlayer.view];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSString* fileURL = dict[@"video"][@"url"]; //may be remote or local
dispatch_async(dispatch_get_main_queue(), ^{
[moviePlayer stop];
[moviePlayer setContentURL:[NSURL fileURLWithPath:fileURL]];
//next lines cause high CPU, RAM, eventual crash
[moviePlayer prepareToPlay];
[moviePlayer play];
});
});
}
return self;
}
崩溃的一些细节:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00007fff5291bd80
问题是由于视频文件 URL 无效所致。虽然 URL 存在,但它不正确。
在我正在使用的应用程序中,我们将 MPMovePlayerController
添加到 UITableViewCell
,然后自动播放它。问题是,调用 prepareToPlay
and/or play
导致应用程序冻结,CPU 达到最大值,RAM 不断增加,应用程序当然会在一段时间后崩溃。如果我注释掉不会发生的 prepareToPlay
和 play
,那么我看到的只是一个没有播放控件的黑框。
我们在 cellForRowAtIndexPath
中创建 MPMoviePlayerController
并将其存储到一个数组中,因为我们可能在 table 中有多个视频,并且需要能够播放正确的视频按需点击一个或停止一个。首次加载 table 时,视频加载和播放没有问题。用户可以通过模态视图控制器演示添加视频,这将在将视频添加到数据源后重新加载 table。只有在用户添加新视频后才会出现此问题。
我尝试在单元格中为播放器存储 属性,但这并没有解决问题。我已经尝试按照其他地方的建议在设置 contentURL
之前调用 stop
,这也没有帮助。还尝试了 4 个不同的视频,每个视频都有不同的格式,以防它是损坏的视频。我不确定是什么问题。
//Table view controller:
@interface {
NSMutableArray *arrayOfMoviePlayers;
}
viewDidLoad {
arrayOfMoviePlayers = [NSMutableArray new];
}
cellForRowAtIndexPath {
MyTableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc]init];
[arrayOfMoviePlayers addObject:moviePlayer];
cell = [[MyTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell" withDictionary:dict withMoviePlayer:moviePlayer];
return cell;
}
//Cell subclass:
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier withDictionary:(NSDictionary*)dict withMoviePlayer:(MPMoviePlayer *)moviePlayer {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
moviePlayer.view.frame = self.contentView.bounds;
[self.contentView addSubview:moviePlayer.view];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSString* fileURL = dict[@"video"][@"url"]; //may be remote or local
dispatch_async(dispatch_get_main_queue(), ^{
[moviePlayer stop];
[moviePlayer setContentURL:[NSURL fileURLWithPath:fileURL]];
//next lines cause high CPU, RAM, eventual crash
[moviePlayer prepareToPlay];
[moviePlayer play];
});
});
}
return self;
}
崩溃的一些细节:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00007fff5291bd80
问题是由于视频文件 URL 无效所致。虽然 URL 存在,但它不正确。