2012-08-28 15 views
10

Próbuję nagrać dźwięk na urządzeniu za pomocą AVAudioRecorder. Ten plik jest przesyłany do serwera WWW i chcę odtworzyć wynikowy plik w przeglądarce internetowej.AVAudioRecorder rekord AAC/m4a

Próbowałem różnych kombinacji ustawień na urządzeniu ... nic nie wydaje się kodować pliku do właściwego formatu AAC .

QuickTime mówi, że nie wie, jak odtworzyć ten plik.

Przykładowy kod

private void InitializeRecordingSession() { 
     string fileName = string.Format("{0}.m4a", Guid.NewGuid()); 
     string tmpdir = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "/audio"; 
      if (!Directory.Exists(tmpdir)) 
       Directory.CreateDirectory(tmpdir); 
      audioFilePath = Path.Combine(tmpdir, fileName); 

      Console.WriteLine("Audio File Path: " + audioFilePath); 

      var url = NSUrl.FromFilename(audioFilePath); 
      var settings = new AVAudioRecorderSettings() { 
       AudioFormat = AudioFormatType.MPEG4AAC, 
       SampleRate = 44100, 
       NumberChannels = 1, 
       AudioQuality = AVAudioQuality.High,  
      }; 

      recorder = AVAudioRecorder.ToUrl(url, settings, out error); 

      //Set Recorder to Prepare To Record 
      recorder.PrepareToRecord(); 
    } 

Edit -Przez wprowadzenie tego kodu przed linią

recorder = AVAudioRecorder.ToUrl(url, settings, out error); 

wszystko działało.

NSError error;  
AVAudioSession audioSession = AVAudioSession.SharedInstance(); 
audioSession.SetCategory(AVAudioSession.CategoryRecord, out error); 
audioSession.SetActive(true, out error); 
+0

Zastanawiam się, czy znalazłeś rozwiązanie tego jak w obliczu tego samego problemu. – justinkoh

Odpowiedz

6

SDK iOS jest najwyraźniej głupi. Ustawienie klucza ID formatu na kAudioFormatMPEG4AAC nie wystarczy, aby faktycznie zakodować plik; w QuickTime będzie grać, ale w jego właściwościach po prostu zobaczysz AAC i nie będzie żadnych dalszych szczegółów. Zmiana rozszerzenia pliku wyjściowego na m4a powinna pomóc w rozwiązaniu problemu i sprawić, że zastosuje odpowiednie kodowanie.

+0

Jestem prawie pewien, że próbowałem tego i to nie działało. Ale spróbuję jeszcze raz. –

+0

to nadal nie działa "To nie jest plik, który quicktime rozumie" –

+0

Obawiam się, że ta metoda też nie działała dla mnie. – justinkoh

30

Dla enkoderów przyspieszanych sprzętowo, tylko jedna sesja może być aktywna w danym momencie. Oznacza to, że w przypadku AAC będzie działać w symulatorze (w którym używany jest koder programowy), ale może się nie udać na urządzeniu (w którym używany jest koder sprzętowy), chyba że aplikacja aktywuje AVAudioSession.

Próbowałem również użyć AVAudioRecorder do nagrywania dźwięku w formacie AAC, najlepiej w pliku .m4a. Miałem kiedyś tego zwierzęcia. Szybko udało mi się uzyskać kod do nagrywania w formacie AAC w głównym pliku audio (.caf), ale nie mogłem zmusić AVAudioRecorder do odpowiedniego sformatowania .m4a. Miałem właśnie przepisać kod nagrywania w mojej aplikacji za pomocą interfejsu API niższych jednostek Audio Unit, ale zamiast tego umieściłem to na odwrocie i dodałem kod, aby obsłużyć wspólną sesję audio. Po skonfigurowaniu wróciłem i próbowałem zapisać jako .m4a i po prostu zadziałało.

Oto przykładowy kod:

NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *docsDir = [dirPaths objectAtIndex:0]; 
NSURL *tmpFileUrl = [NSURL fileURLWithPath:[docsDir stringByAppendingPathComponent:@"tmp.m4a"]]; 
NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
         [NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey, 
         [NSNumber numberWithFloat:16000.0], AVSampleRateKey, 
         [NSNumber numberWithInt: 1], AVNumberOfChannelsKey, 
         nil]; 
NSError *error = nil; 
AVAudioRecorder *recorder = [[AVAudioRecorder alloc] initWithURL:tmpFileUrl settings:recordSettings error:&error]; 
[recorder prepareToRecord]; 

AVAudioSession *session = [AVAudioSession sharedInstance]; 
[session setCategory:AVAudioSessionCategoryRecord error:nil]; 
[session setActive:YES error:nil]; 

[recorder record]; 

Następnie, aby zakończyć nagrywanie użyłem:

[recorder stop]; 
AVAudioSession *session = [AVAudioSession sharedInstance]; 
int flags = AVAudioSessionSetActiveFlags_NotifyOthersOnDeactivation; 
[session setActive:NO withFlags:flags error:nil]; 

Następnie plik na „tmpFileUrl” może być używany jak należy.

+1

To powinno zostać wznowione niezliczoną ilość razy! – mahboudz

+0

Niesamowita odpowiedź. Dzięki temu zaoszczędziło mi to wiele czasu! –

3

Wskazówki dotyczące AVAudioSession są bardzo pomocne!

Od setActive:withFlags:error: stał się nieaktualny w iOS 6.0 kod do zatrzymania sesji audio, powinny być dostosowane do:

AVAudioSession *session = [AVAudioSession sharedInstance]; 
int flags = AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation; 
[session setActive:NO withOptions:flags error:nil];