2009-08-07 17 views
7

Jaki jest najłatwiejszy sposób uzyskania pliku audio?iPhone: uzyskaj czas trwania pliku audio

Mogę utworzyć obiekt AVAudioPlayer, zainicjować go za pomocą adresu URL, a następnie uzyskać czas trwania, ale ten sposób jest zbyt długi. Czy istnieje prostszy sposób?

Dzięki.

+0

Możliwy duplikat [Jak uzyskać czas trwania pliku audio w systemie iOS?] (http://stackoverflow.com/questions/5219379/how-to-get-turation-of-an-audio-file-in-ios) – user471651

Odpowiedz

8

Możesz korzystać z funkcji Audio File Services. Jest jedna właściwość, która powinna dać ci szacunkowy czas trwania. Kod:

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); 

Można sprawdzić docs here

+0

Dzięki, ale nie rozumiem, dlaczego nie mogę dostać za każdym razem, że outDataSize równa 0? –

+0

Dziękuję za rozwiązanie, dowiedziałem się, gdzie jest problem. –

+0

Hej, to nie w porządku, wykorzystując aktualną wiedzę, aby uzyskać czek, zamiast niejasnych spekulacji na temat systemu operacyjnego, z którym nigdy nie pracowałeś. :) – MusiGenesis

2

Jeśli wiesz coś na temat pliku audio w pytaniu (próbkowaniu, Głębia bitowa, liczba kanałów), a to nieskompresowany Format (WAV/AIFF), a następnie można obliczyć/przybliżoną/okres od Wielkość pliku:

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

+0

100 bajtów dla nagłówka ? Cokolwiek stało się z kanonicznym 44? :) – MusiGenesis

+0

Dowolna liczba powodów;) metadane BWF, nagłówek AIFF? –

+0

Powinienem wiedzieć lepiej po 14 latach, ale w zeszłym miesiącu spędziłem pół dnia próbując dowiedzieć się, skąd pochodzi małe kliknięcie na początku mojego dźwięku. Użyłem mojej szybkiej i brudnej metody, która zakładała tylko 44-bajtowy nagłówek. Nauczyłem się jeszcze raz mojej lekcji. – MusiGenesis

2

To zależy od typu pliku. Jeśli jest to plik WAV, możesz zlokalizować nagłówek pliku i określić czas odtwarzania w ten sposób. Jeśli jest to skompresowany format (* .mp3 itp.), Lepiej nie trzymać się metody, o której wspomniałeś.

12

Prawidłowy kod jest

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 powinny być Float64 nie UInt64.

1

W przypadku ktoś ląduje tutaj szukasz sposobu, aby uzyskać czas zarówno dla plików audio i wideo, rzucić okiem na to odpowiedź na innym stanowisku, w którym zamiast tego używa AVAsset Zamiast:

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

Używanie AudioFileGetProperty (podobnie jak pozostałe dwie główne odpowiedzi tutaj), aby uzyskać czas trwania plików A/V nie działał dla kilku plików .mov na moim urządzeniu (wynik był zawsze 0), natomiast rozwiązanie z wykorzystaniem AVAsset otrzymało czas wszystkie pliki audio i wideo na moim urządzeniu.

(Co ciekawe jednak, że czas trwania obu rozwiązań było czasem 1 sekunda więcej niż wyświetlana w interfejsie rzeczywistej AVAudioPlayer. Najprawdopodobniej AVAudioPlayer wykorzystuje niestandardowe rutynowych zaokrąglania dla wyświetlanego trwania.)

1

przykładowy kod z odpowiedzi How to get the duration of an audio file in iOS?. To jest najlepsza odpowiedź.

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

2

Łącząc AVAudioPlayer z Swift jest tak proste, jak (mam migracji tabelę Realm poniżej, ale masz pomysł):

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); 
        }];