2014-05-16 8 views
7

Ich verwende , um einen benutzerdefinierten Videoplayer in einer iOS-Anwendung zu implementieren. Um Video aus dem Netz zu spielen zuteilen ich einen Spieler:Wie informiert AVPlayer/AVPlayerItem meine Anwendung über nicht erreichbare Netzwerkfehler?

[[AVPlayer alloc] initWithURL:_URL]; 

ein Asset erstellen:

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:self.URL 
options:@{AVURLAssetPreferPreciseDurationAndTimingKey : @(YES)}]; 

Last der playable Schlüssel asynchron:

NSArray *keys = @[@"playable"]; 
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     for (NSString *key in keys) { 
      NSError *error; 
      AVKeyValueStatus status = [asset statusOfValueForKey:key error:&error]; 

      if (status == AVKeyValueStatusFailed) { 
       NSLog(@"Failed to load asset key %@ error %@", key, [error localizedDescription]); 
       [self fail]; 
       return; 
      } 
     } 

     if (asset.isPlayable) { 
      [self.player replaceCurrentItemWithPlayerItem:self.playerItem]; 
     } 
     else { 
      [self fail]; 
     } 
    }); 
}]; 

Das Problem ist, dass, wenn die Vorrichtung keine Internetverbindung oder hoher Paketverlust, die completionHandler wird nie aufgerufen (auch nach dem Warten auf Minuten) und so habe ich keine Ahnung, wann eine Nachricht an den Benutzer, die laden g Das Video ist fehlgeschlagen.

Meine Fragen sind:

  1. bin ich etwas fehlt/gibt es einen besseren Weg, dies zu umgehen?
  2. sollte ich meine eigene Timeout-Logik rollen oder sollte ich einfach nie loadValuesAsynchronouslyForKeys: wenn Reachability glaubt, dass das Netzwerk nicht erreichbar ist.
  3. Was sind die besten Praktiken in Bezug auf und Netzwerkfehler?

Antwort

1

Es stellt sich heraus, dass dies auf die Art und Weise im Zusammenhang wurde möglicherweise ich Tests war. Die Verwendung des Network Link Conditioners hat den Block nicht ausgelöst, aber als ich den Host mit Charles Proxy blockierte, funktionierte alles wie beabsichtigt. Ich versuche, mit meinem ursprünglichen Code für jetzt zu gehen, und werde einige von Dans Ideen hinzufügen, wenn es noch während des realen Tests problematisch erweist

1

Ich habe AVAsset bereits integriert, aber dieses spezielle Problem ist noch nicht aufgetreten. Nichtsdestotrotz würde ich Folgendes tun:

  1. Legen Sie einen Zeitgeber oder einen verzögerten Blockversand für die Dauer des Zeitlimits fest, das Sie erzwingen möchten.
  2. Überprüfen Sie den Wert der "spielbaren" Taste mit statusOfValueForKey:error:.
  3. Wenn der Status nicht AVKeyValueStatusLoaded ist oder der Fehler nicht null ist, rufen Sie [asset cancelLoading] an und zeigen Sie dem Benutzer oder einer anderen Bereinigung, die Sie möglicherweise vornehmen müssen, eine Fehlermeldung an.
4

Sie sollen (KVO) Merkmale des AVPlayerItem werden beobachten, die zeigen, wie der Puffer tun, wie playbackBufferEmpty usw.