Как узнать длительность аудио файла в iOS? - PullRequest
44 голосов
/ 07 марта 2011
NSDictionary* fileAttributes = 
    [[NSFileManager defaultManager] attributesOfItemAtPath:filename 
                                                     error:nil]

Из ключей атрибутов файла вы можете получить дату, размер и т. Д. Но как узнать продолжительность?

Ответы [ 5 ]

126 голосов
/ 13 августа 2011

В 'Атрибутах файла' NSFileManager ссылка на класс вы можете видеть, что нет ключа, который будет возвращать длительность песни. Вся информация, которую получает экземпляр NSFileManager о файле, связана со свойствами самого файла в операционной системе, такими как его размер. NSFileManager фактически не интерпретирует файл.

Чтобы получить длительность файла, вам нужно использовать класс, который знает, как интерпретировать файл. Платформа AVFoundation предоставляет точный класс, который вам нужен, AVAsset . Вы можете создать экземпляр этого абстрактного класса, используя конкретный подкласс AVURLAsset , а затем предоставить ему NSURL , который указывает на аудиофайл, который вы хотите получить длительность. Затем вы можете получить продолжительность из экземпляра AVAsset , запросив его свойство duration.

Например:

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

Обратите внимание, что AVFoundation разработан как сильно асинхронная среда для повышения производительности и общего пользовательского опыта. Даже выполнение простых задач, таких как запрос продолжительности мультимедийного файла, может занять много времени и привести к зависанию приложения. Вам следует использовать протокол AVAsynchronousKeyValueLoading для асинхронной загрузки длительности песни, а затем обновить свой пользовательский интерфейс в блоке обработчика завершения. Вам следует взглянуть на «Руководство по блочному программированию» , а также на видео WWDC2010 под названием «Discovering AV Foundation», которое можно бесплатно получить по https://developer.apple.com/videos/wwdc/2010.

14 голосов
/ 31 октября 2012

Для полноты - есть другой способ получить продолжительность для mp3-файла:

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

double duration = avAudioPlayer.duration; 
avAudioPlayer = nil;

Я использовал это без заметной задержки.

8 голосов
/ 24 декабря 2017

Вы можете добиться того же в Swift, используя:

let audioAsset = AVURLAsset.init(url: audioFileURL, options: nil)
let duration = audioAsset.duration
let durationInSeconds = CMTimeGetSeconds(duration)
6 голосов
/ 28 мая 2018

Для тех, кто все еще ищет это. Исходя из ответа, код для Swift 4 (включая асинхронную загрузку значений, взятых из документации 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
    }
}
1 голос
/ 06 мая 2019

Swift 5.0 + iOS 12 : это единственный способ, которым он работал для меня (решение @John Goodstadt в Swift). В настоящее время я не уверен, почему, но существует разница в среднем 0,2 секунды между записанным аудиофайлом (в моем случае голосовой заметкой) и полученным аудиофайлом, используя следующий код.

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