2011-10-07 17 views
30

Estoy utilizando con éxito AVPlayer para transmitir audio desde un servidor y lo que quiero hacer ahora es mostrar un UISlider personalizado que muestra el progreso del almacenamiento en búfer.AVPlayer progreso de transmisión

Algo como esto:

enter image description here

Con AVPlayer no parece ser una manera de conseguir el tamaño de descarga total o cuantía actual descargado el archivo de audio, sólo el tiempo de reproducción actual y tiempo total de juego.

¿Hay alguna solución para esto?

+3

¿Alguna vez implementar la parte de interfaz de usuario de esta? Necesito exactamente esto, y preferiría no hacer lo propio si ya hay algo por ahí. –

+3

Consulte la respuesta más frecuente a esta pregunta para la parte de UI: http://stackoverflow.com/questions/4495433/uislider-with-progressview-combined – Form

+1

Solución simple para implementar la interfaz de usuario anterior es simplemente poner una UIProgressBar debajo de un UISlider y establece el 'maximumTrackTintColor' del control deslizante en' [UIColor clearColor] '. – inorganik

Respuesta

51

Estoy trabajando en esto, y hasta ahora tengo el siguiente:

- (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

Para agregar a esto, el valor que está buscando es la propiedad AVPlayerItem loadedtimeRanges. Es un NSArray que contiene un NSValue de CMTimeRange. Este fragmento de código es lo que me costaba crear, es decir, cómo convertir esos datos en algo útil. –

+0

¿por qué tomas la primera vez, no la última? [loadedTimeRanges lastObject] – HotJard

+0

Recuerdo que escribí una función para observar cómo se comportaba esto, y que siempre veía solo un elemento en la matriz, por lo que es probable que sea discutible/arbitrario tomar el primero o el último.Un cálculo más teóricamente "correcto" sería usar esta matriz, y encontrar la duración máxima basada en el inicio máximo + duración, pero no fue necesario en la práctica. –

8

Debería funcionar bien:

Objective-C:

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

versión Swift :

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

Vigilar valor de tiempo actual se puede utilizar: CMTimeShow ([auto availableDuration]); oCMTimeShow (availableDuration())(para SWIFT)

0

Este método devolverá intervalo de tiempo de búfer para su 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

¿Podría explicarnos un poco más qué hace el código y cómo resuelve la pregunta del OP? En su formato actual, es un poco difícil de leer – Draken

0

respuesta seleccionada puede causar problemas si matriz devuelta es vacío. Aquí está una función fija:

- (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

El código de Suresh Kansujiya en 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)); 
} 
Cuestiones relacionadas