Ich versuche, eine App zu erstellen, die Videos aus einer Datei mit AVFoundation
spielt. Die Videos werden in einer Ansicht angezeigt, auf die durch Tippen auf eine Zeile in einer übergeordneten Tabellenansicht zugegriffen wird. Die echte App wird für jede Reihe ein Video haben, aber im Moment benutze ich nur eine zum Testen.AVPlayer stürzt nach mehreren playbacks-
Wenn auf dem Simulator ausgeführt wird, ist die App in Ordnung, aber wenn auf dem Gerät (unter IOS 5.1) ausgeführt wird, wird das Video etwa 5 Mal ausgeführt und stürzt dann unvorhersehbar auf verschiedene Arten ab. Am häufigsten werden die Videoansicht lädt aber das Video selbst nicht spielt, aber manchmal ich eine EXC_BAD_ACCESS
auf einem coremedia.remote
Faden, beschwerte sich über Objekte ohne Autofreigabepool an Ort und Stelle zugeordnet ist. Ich habe einen @autoreleasepool
Block hinzugefügt, der den Code einpackt, der den AVPlayer startet, aber das scheint nicht zu helfen.
Ich frage mich, ob was passiert ist, dass GCD erstellt mehrere Threads in der Hauptwarteschlange, um die Elemente zu spielen, aber sie enden nicht.
So ist die entscheidende Frage ist-wie kann ich das überflüssige GCD aufklären fädelt die AVPlayer auf ausgeführt, wenn der Benutzer die Zurück-Taste in den Videoaufrufe so weit wie möglich Ich habe den Beispielcode gefolgt vorgesehen in Apples AVFoundation
Dokumentation here ich habe einige Protokollierung hinzugefügt und (wie oben erwähnt) einen @autoreleasepool
Block innerhalb einer der GCD Blocks- außer, dass ich den Code nicht geändert haben.
Die viewDidLoad
Methode ist wie folgt:
-(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");
}
}
});
}];
}
Die viewWillDisappear
Methode ist:
-(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");
});
}
Ich habe kämpfen mit diesem für die meisten heute - jede Hilfe wäre dankbar erhalten
Danke für die Nachfrage! – headkit