を使用してファイルからビデオを再生するアプリを作成しようとしていますAVFoundation
。ビデオは、親テーブルビューの行をタップしてアクセスするビューに表示されます。実際のアプリには行ごとにビデオがありますが、現時点ではテスト用に 1 つだけ使用しています。
シミュレーターで実行すると、アプリは問題ありませんが、デバイス (ios 5.1 の下) で実行すると、ビデオは約 5 回正常に再生され、さまざまな方法で予期せずクラッシュします。最も一般的なのは、ビデオ ビューは読み込まれますが、ビデオ自体は再生されませんが、自動解放プールが配置されていない状態でオブジェクトが割り当てられているという不平を言うスレッドが発生EXC_BAD_ACCESS
することがあります。coremedia.remote
AVPlayer を起動するコードをラップするブロックを追加しました@autoreleasepool
が、これは役に立たないようです。
GCD がアイテムを再生するためにメイン キューに複数のスレッドを作成しているが、それらが終了していないことが原因であるかどうか疑問に思っています。
したがって、重要な問題は、ユーザーがビデオ ビューで [戻る] ボタンを押した場合に、AVPlayer が実行されている余分な GCD スレッドをどのようにクリアするかAVFoundation
です
。いくつかのロギングと (前述のように) GCD ブロックの 1 つの内部にブロックを追加しましたが、それ以外はコードを変更していません。@autoreleasepool
方法は次のviewDidLoad
とおりです。
-(void)viewDidLoad{
[super viewDidLoad];
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"TestLapCar2Vid" withExtension:@"m4v"];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil];
NSString *tracksKey = @"tracks";
[asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:tracksKey] completionHandler:
^{
dispatch_async(dispatch_get_main_queue(),
^{
@autoreleasepool {
NSError *error = nil;
AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error];
if(status == AVKeyValueStatusLoaded){
avPlayerItem = [AVPlayerItem playerItemWithAsset:asset];
[avPlayerItem addObserver:self forKeyPath:@"status"
options:0 context:&ItemStatusContext];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification object:avPlayerItem];
avPlayer = [AVPlayer playerWithPlayerItem:avPlayerItem];
[videoView setPlayer:avPlayer];
NSLog(@"Asset loaded");
[avPlayer play];
}
else{
NSLog(@"The asset's tracks were not loaded");
}
}
});
}];
}
viewWillDisappear
メソッドは次のとおりです。
-(void)viewWillDisappear:(BOOL)animated{
NSLog(@"view will disappear called");
[super viewWillDisappear:animated];
dispatch_async(dispatch_get_main_queue(),
^{
[avPlayer pause];
[avPlayerItem removeObserver:self forKeyPath:@"status"];
[[NSNotificationCenter defaultCenter]removeObserver:self];
NSLog(@"Race timeline nav controller has %d sub controllers",self.navigationController.childViewControllers.count);
avPlayerItem = nil;
avPlayer = nil;
videoView = nil;
dataStore = nil;
pkReader = nil;
receivedData = nil;
revDial = nil;
speedDial = nil;
mapView = nil;
throttle = nil;
NSLog(@"releasing stuff");
});
}
私は今日のほとんどの間これに苦労してきました-どんな助けも感謝して受け取ります