2011-10-07 24 views
30

Sto utilizzando con successo lo AVPlayer per lo streaming audio da un server e quello che voglio fare ora è mostrare un annuncio personalizzato UISlider che mostra l'avanzamento del buffering.Avanzamento dello streaming di AVPlayer

Qualcosa di simile a questo:

enter image description here

Con AVPlayer non sembra essere un modo per ottenere la dimensione totale dei download o la quantità scaricato corrente per il file audio, solo il tempo di riproduzione corrente e tempo di gioco totale.

Esistono soluzioni alternative per questo?

+3

Ti è mai attuare la parte di interfaccia utente di questo? Ho proprio bisogno di questo, e preferirei non rotolare da solo se c'è già qualcosa là fuori. –

+3

Vedere la risposta superiore a questa domanda per la parte UI: http://stackoverflow.com/questions/4495433/uislider-with-progressview-combined – Form

+1

La soluzione semplice per implementare l'interfaccia utente precedente è semplicemente mettere un UIProgressBar sotto un UISlider e imposta il 'maximumTrackTintColor' del cursore su' [UIColor clearColor] '. – inorganik

risposta

51

Sto solo lavorando su questo, e finora ho il seguente:

- (NSTimeInterval) availableDuration; 
{ 
    NSArray *loadedTimeRanges = [[self.player currentItem] loadedTimeRanges]; 
    CMTimeRange timeRange = [[loadedTimeRanges objectAtIndex:0] CMTimeRangeValue]; 
    Float64 startSeconds = CMTimeGetSeconds(timeRange.start); 
    Float64 durationSeconds = CMTimeGetSeconds(timeRange.duration); 
    NSTimeInterval result = startSeconds + durationSeconds; 
    return result; 
} 
+0

Per aggiungere a questo, il valore che stai cercando è la proprietà AVPlayerItem loadedtimeRanges. È un NSArray che contiene un NSValue di un CMTimeRange. Questo pezzo di codice è quello che stavo avendo problemi a venire, cioè come ottenere quei dati in qualcosa di utile. –

+0

perché prendi la prima volta, non l'ultima? [loadedTimeRanges lastObject] – HotJard

+0

Ricordo di aver scritto una funzione per vedere come si comportava, e vedevo sempre un solo elemento nell'array, quindi è probabilmente moot/arbitrario prendere il primo o l'ultimo.Un calcolo più "teorico" teoricamente sarebbe quello di utilizzare questo array e trovare la durata massima in base alla durata massima + durata, ma non era necessario nella pratica. –

8

Dovrebbe funzionare bene:

Objective-C:

- (CMTime)availableDuration 
{ 
    NSValue *range = self.player.currentItem.loadedTimeRanges.firstObject; 
    if (range != nil){ 
     return CMTimeRangeGetEnd(range.CMTimeRangeValue); 
    } 
    return kCMTimeZero; 
} 

versione Swift :

func availableDuration() -> CMTime 
{ 
    if let range = self.player?.currentItem?.loadedTimeRanges.first { 
     return CMTimeRangeGetEnd(range.timeRangeValue) 
    } 
    return kCMTimeZero 
} 

Per visualizzare il valore dell'ora corrente è possibile utilizzare: CMTimeShow ([self availableDuration]); oCMTimeShow (availableDuration())(per SWIFT)

0

Questo metodo restituirà tampone intervallo di tempo per la vostra UISlider

public var bufferAvail: NSTimeInterval { 

    // Check if there is a player instance 
    if ((player.currentItem) != nil) { 

     // Get current AVPlayerItem 
     var item: AVPlayerItem = player.currentItem 
     if (item.status == AVPlayerItemStatus.ReadyToPlay) { 

      var timeRangeArray: NSArray = item.loadedTimeRanges 
      var aTimeRange: CMTimeRange = timeRangeArray.objectAtIndex(0).CMTimeRangeValue 
      var startTime = CMTimeGetSeconds(aTimeRange.start) 
      var loadedDuration = CMTimeGetSeconds(aTimeRange.duration) 

      return (NSTimeInterval)(startTime + loadedDuration); 
     } 
     else { 
      return(CMTimeGetSeconds(kCMTimeInvalid)) 
     } 
    } 
    else { 
     return(CMTimeGetSeconds(kCMTimeInvalid)) 
    } 
} 
+0

Potresti spiegare un po 'di più cosa fa il codice e come risolve la domanda dell'OP? Nel suo formato attuale, è un po 'difficile da leggere – Draken

0

risposta selezionata può causare problemi se matrice restituita è vuoto. Ecco una funzione fissa:

- (NSTimeInterval) availableDuration 
{ 
    NSArray *loadedTimeRanges = [[_player currentItem] loadedTimeRanges]; 
    if ([loadedTimeRanges count]) 
    { 
     CMTimeRange timeRange = [[loadedTimeRanges objectAtIndex:0] CMTimeRangeValue]; 
     Float64 startSeconds = CMTimeGetSeconds(timeRange.start); 
     Float64 durationSeconds = CMTimeGetSeconds(timeRange.duration); 
     NSTimeInterval result = startSeconds + durationSeconds; 
     return result; 
    } 
    return 0; 
} 
0

Il codice da Suresh Kansujiya in Objective C

NSTimeInterval bufferAvail; 

if (player.currentItem != nil) { 

    AVPlayerItem *item = player.currentItem; 
    if (item.status == AVPlayerStatusReadyToPlay) { 
     NSArray *timeRangeArray = item.loadedTimeRanges; 
     CMTimeRange aTimeRange = [[timeRangeArray objectAtIndex:0] CMTimeRangeValue]; 
     Float64 startTime = CMTimeGetSeconds(aTimeRange.start); 
     Float64 loadedDuration = CMTimeGetSeconds(aTimeRange.duration); 

     bufferAvail = startTime + loadedDuration; 

     NSLog(@"%@ - %f", [self class], bufferAvail); 
    } else { 
     NSLog(@"%@ - %f", [self class], CMTimeGetSeconds(kCMTimeInvalid)); } 
} 
else { 
    NSLog(@"%@ - %f", [self class], CMTimeGetSeconds(kCMTimeInvalid)); 
} 
Problemi correlati