2009-08-07 11 views
7

¿Cuál es la forma más fácil de obtener una duración de un archivo de audio?iPhone: obtenga la duración de un archivo de audio

Pude crear un objeto de AVAudioPlayer, inicializarlo con URL y obtener la duración, pero de esta manera es demasiado largo. hay una manera mas facil?

Gracias.

+0

duplicado posible de [¿Cómo obtener el duración de un archivo de audio en iOS?] (http://stackoverflow.com/questions/5219379/how-to-get-the-duration-of-an-audio-file-in-ios) – user471651

Respuesta

8

Puede usar las funciones de Audio File Services. Hay una propiedad para obtener que debería darle la duración estimada. Código:

NSURL *afUrl = [NSURL fileURLWithPath:soundPath]; 
    AudioFileID fileID; 
    OSStatus result = AudioFileOpenURL((CFURLRef)afUrl, kAudioFileReadPermission, 0, &fileID); 
    UInt64 outDataSize = 0; 
    UInt32 thePropSize = sizeof(UInt64); 
    result = AudioFileGetProperty(fileID, kAudioFilePropertyEstimatedDuration, &thePropSize, &outDataSize); 
    AudioFileClose(fileID); 

se puede comprobar la documentación here

+0

Gracias, pero no entiendo, ¿por qué recibo cada vez que outDataSize es igual a 0? –

+0

Gracias por su solución, descubrí dónde estaba el problema. –

+0

Oye, eso no es justo en absoluto, usar el conocimiento real para obtener el cheque, en lugar de vagas especulaciones sobre un sistema operativo con el que nunca has trabajado. :) – MusiGenesis

2

Si usted sabe algo sobre el archivo de audio en cuestión (de muestreo, bitdepth, el número de canales), y es un formato sin comprimir (WAV/AIFF), entonces se puede calcular el/aproximada/duración del tamaño de archivo:

length_in_seconds = (file_length-guess_100_bytes_for_header)/(samplerate * (bitdepth * channel_count/8))

+0

100 bytes para el encabezado ? ¿Qué pasó con el 44 canónico? :) – MusiGenesis

+0

Cualquier cantidad de razones;) metadatos BWF, encabezado AIFF? –

+0

Debería saberlo mejor después de 14 años de esto, pero el mes pasado pasé medio día tratando de averiguar de dónde venía el pequeño clic al principio de mi sonido. Estaba usando mi método rápido y sucio que suponía solo el encabezado de 44 bytes. Aprendí mi lección, una vez más. – MusiGenesis

2

Depende del tipo de archivo. Si se trata de un archivo WAV, puede ubicar el encabezado del archivo y determinar la duración de la reproducción de esa manera. Si se trata de un formato comprimido (* .mp3, etc.), es mejor que sigas el método que mencionaste.

12

código correcto es

NSURL *afUrl = [NSURL fileURLWithPath:soundPath]; 
AudioFileID fileID; 
OSStatus result = AudioFileOpenURL((CFURLRef)afUrl, kAudioFileReadPermission, 0, &fileID); 
Float64 outDataSize = 0; 
UInt32 thePropSize = sizeof(Float64); 
result = AudioFileGetProperty(fileID, kAudioFilePropertyEstimatedDuration, &thePropSize, &outDataSize); 
AudioFileClose(fileID); 

outDataSize debe ser float64 no UInt64.

1

En caso de que alguien aterriza aquí en busca de una manera de conseguir la duración tanto para archivos de audio y vídeo, echar un vistazo a esta respuesta a otro puesto, el cual en su lugar utiliza AVAsset lugar:

https://stackoverflow.com/a/7052147/381233

Uso AudioFileGetProperty (como las otras dos respuestas principales aquí) para obtener la duración de los archivos A/V no funcionó para unos pocos archivos .mov en mi dispositivo (el resultado siempre fue 0), mientras que la solución que usaba AVAsset obtuvo la duración de todos los archivos de audio y video en mi dispositivo.

(Curiosamente, sin embargo, la duración de las dos soluciones fue a veces 1 segundo más de la que se muestra en la interfaz de usuario de un real AVAudioPlayer. Lo más probable es la AVAudioPlayer utiliza una rutina de redondeo no estándar para la duración visualizada.)

1

código de ejemplo de la respuesta How to get the duration of an audio file in iOS?. Esta es la mejor respuesta.

AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:audioFileURL options:nil]; CMTime audioDuration = audioAsset.duration; float audioDurationSeconds = CMTimeGetSeconds(audioDuration);

2

Combinando AVAudioPlayer con Swift se vuelve tan fácil como (estoy migrando una mesa Realm más adelante, pero se entiende la idea):

import AVFoundation 

let resource = old!["filename"] as? String 
let afUrl = NSBundle.mainBundle().URLForResource(resource, withExtension: nil) 
let player = try! AVAudioPlayer(contentsOfURL: afUrl!) 

new!["duration"] = Double(player.duration) 
1
AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:mp3_url options:nil]; 
        [audioAsset loadValuesAsynchronouslyForKeys:@[@"duration"] completionHandler:^{ 
         CMTime audioDuration = audioAsset.duration; 
         float audioDurationSeconds = CMTimeGetSeconds(audioDuration); 

         NSLog(@"duration:%f",audioDurationSeconds); 
        }]; 
Cuestiones relacionadas