60 votes

Comment obtenir la durée d'un fichier audio dans iOS ?

NSDictionary* fileAttributes = 
    [[NSFileManager defaultManager] attributesOfItemAtPath:filename 
                                                     error:nil]

À partir des clés d'attributs des fichiers, vous pouvez obtenir la date, la taille, etc. Mais comment obtenir la durée ?

145voto

James Bedford Points 10691

Dans le Les "clés d'attributs de fichiers" de l'interface utilisateur. NSFileManager référence de classe vous pouvez voir qu'il n'y a pas de touche à utiliser qui renvoie la durée d'une chanson. Toutes les informations que le NSFileManager L'instance obtient à propos d'un fichier est en rapport avec les propriétés du fichier lui-même dans le système d'exploitation, comme sa taille. Le site NSFileManager n'interprète pas réellement le fichier.

Afin d'obtenir la durée du fichier, vous devez utiliser une classe qui sait comment interpréter le fichier. Le site AVFoundation fournit la classe exacte dont vous avez besoin, AVAsset . Vous pouvez instancier une instance de cette classe abstraite à l'aide de la sous-classe concrète AVURLAsset et lui fournir ensuite un NSURL qui pointe vers le fichier audio dont vous souhaitez obtenir la durée. Vous pouvez ensuite obtenir la durée à partir de la fonction AVAsset en interrogeant son duration propriété.

Par exemple :

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

Notez que AVFoundation est conçu comme un cadre fortement asynchrone afin d'améliorer les performances et l'expérience globale de l'utilisateur. Même l'exécution de tâches simples, telles que l'interrogation de la durée d'un fichier multimédia, peut potentiellement prendre beaucoup de temps et provoquer le blocage de votre application. Vous devez utiliser la fonction Protocole AVAsynchronousKeyValueLoading pour charger de manière asynchrone la durée de la chanson, puis mettre à jour votre interface utilisateur dans un bloc de traitement d'achèvement. Vous devriez jeter un coup d'œil au Guide de programmation par blocs ainsi que la vidéo de la WWDC2010 intitulée "Discovering AV Foundation", qui est disponible gratuitement à l'adresse suivante https://developer.apple.com/videos/wwdc/2010 .

19voto

nCr78 Points 83

Pour tous ceux qui le cherchent encore. D'après la réponse, le code pour Swift 4 (y compris le chargement asynchrone de valeurs tirées de la documentation d'Apple) :

let audioAsset = AVURLAsset.init(url: yourURL, options: nil)

audioAsset.loadValuesAsynchronously(forKeys: ["duration"]) {
    var error: NSError? = nil
    let status = audioAsset.statusOfValue(forKey: "duration", error: &error)
    switch status {
    case .loaded: // Sucessfully loaded. Continue processing.
        let duration = audioAsset.duration
        let durationInSeconds = CMTimeGetSeconds(duration)
        print(Int(durationInSeconds))
        break              
    case .failed: break // Handle error
    case .cancelled: break // Terminate processing
    default: break // Handle all other cases
    }
}

15voto

Ashildr Points 667

Vous pouvez réaliser la même chose en Swift en utilisant :

let audioAsset = AVURLAsset.init(url: audioFileURL, options: nil)
let duration = audioAsset.duration
let durationInSeconds = CMTimeGetSeconds(duration)

14voto

John Goodstadt Points 328

Pour être complet - Il existe un autre moyen d'obtenir la durée d'un fichier mp3 :

NSURL * pathToMp3File = ...
NSError *error = nil;
AVAudioPlayer* avAudioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:pathToMp3File error:&error];

double duration = avAudioPlayer.duration; 
avAudioPlayer = nil;

Je l'ai utilisé sans aucun retard perceptible.

9voto

Bem Points 737

Swift 5.0 + iOS 13 : C'est la seule façon dont cela a fonctionné pour moi (solution @John Goodstadt en Swift). Actuellement je ne sais pas trop pourquoi, mais la il y a une différence de 0,2 secondes en moyenne entre un fichier audio enregistré (dans mon cas un mémo vocal) et le fichier audio reçu en utilisant le code suivant.

    do {
        let audioPlayer = try AVAudioPlayer(contentsOf: fileURL)
        return CGFloat(audioPlayer.duration)
    } catch {
        assertionFailure("Failed crating audio player: \(error).")
        return nil
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X