iPhone SDK: AVAudioRecorder не будет записывать после вызова [AVPlayer play] - PullRequest
7 голосов
/ 18 марта 2011

У меня есть контроллер вида, который использует AVPlayer. этот контроллер представления может загрузить модальный контроллер представления, где пользователь может записывать аудио, используя AVAudioRecorder.

вот что происходит:

если пользователь воспроизводит композицию в первом контроллере с помощью [AVPLayer play], AVAudioRecorder не будет записывать в контроллере модального вида. ошибок нет, но текущее время, возвращаемое AVAudioRecorder, равно 0,0;

, если пользователь закрывает модальное диалоговое окно и перезагружает его. AVAudioRecorder работает нормально.

это можно повторять снова и снова AVAudioRecorder не работает при первом запуске после вызова [воспроизведения AVPlayer]

Я боролся с этим уже несколько дней и просто реорганизовал свой код, связанный как с AVPlayer, так и с AVAudioRecorder, и он все еще ведет себя странно.

Любая помощь или указатель высоко ценится

Заранее спасибо

Jean-Pierre

Ответы [ 7 ]

9 голосов
/ 09 мая 2012

У меня тоже была такая же проблема, и вот решение, которое я нашел.

При записи напишите этот код строки после инициализации AVAudioRecord:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:NULL];

Затем вызовите метод record.

3 голосов
/ 22 апреля 2011

Как вы устанавливаете категорию AVAudioSession, т.е. воспроизводите или записываете? Попробуйте что-то вроде

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
1 голос
/ 11 июля 2012

Если вам нужно использовать AVPlayer и AVAudioRecorder одновременно, сделайте следующее:

  1. установить категорию аудио для воспроизведения и записи (как описано выше или с помощью функции аудиосеанса на основе C)
  2. Метод «record» должен вызываться после вызова метода «play» с некоторой задержкой. (Я установил 0,5 сек)

Если вы не предоставите это, воспроизведение начнется, но запись не начнется.

1 голос
/ 03 мая 2012

У меня была такая же проблема.Я использую AVPlayer для воспроизведения композиций (предыдущие записи, для которых я использовал AVAudioRecord).Тем не менее, я обнаружил, что, когда я использовал AVPlayer, я больше не мог использовать AVAudioRecorder.После некоторых поисков я обнаружил, что до тех пор, пока AVPlayer создается в памяти и воспроизводится хотя бы один раз (что обычно и делается сразу после его создания), AVAudioRecorder не будет записывать.Однако, как только AVPlayer будет освобожден, AVAudioRecorder снова будет свободен для записи.Похоже, что AVPlayer поддерживает какое-то соединение, которое нужно AVAudioRecorder, и оно жадное ... оно не пропустит его, пока вы не вырвете его из холодных мертвых рук.

Это решение, которое я 'нашел.Некоторые люди утверждают, что создание экземпляра AVPlayer занимает слишком много времени, чтобы продолжать ломаться и восстанавливать настройки.Однако это не так.Создание AVPlayer на самом деле довольно тривиально.Так же является создание экземпляра AVPlayerItem.То, что не тривиально, это загрузка AVAsset (или любого из его подклассов).Вы действительно хотите сделать это только один раз.Они должны использовать эту последовательность:

  1. Загрузите AVAsset (например, если вы загружаете из файла, используйте AVURLAsset напрямую или добавьте его в AVMutableComposition и используйте его) и сохраните ссылкук этому.Не отпускай, пока не покончишь с этим.Загрузка - это то, что занимает все время.
  2. Как только вы будете готовы к игре: создайте экземпляр AVPlayerItem с вашим активом, затем AVPlayer с AVPlayerItem и воспроизведите его.Не сохраняйте ссылку на AVPlayerItem, AVPlayer сохранит ссылку на нее, и вы все равно не сможете повторно использовать ее с другим игроком.
  3. Как только игра закончится, немедленно уничтожит AVPlayer ... отпустите его, установите его переменную на ноль, что вам нужно сделать.**
  4. Теперь вы можете записывать.AVPlayer не существует, поэтому AVAudioRecorder может делать свое дело.
  5. Когда вы будете готовы снова играть, создайте экземпляр AVPlayerItem с активом, который вы уже загрузили, и AVPlayer.Опять же, это тривиально.Актив уже загружен, поэтому задержка не должна быть.

** Обратите внимание, что уничтожение AVPlayer может занять больше, чем просто его освобождение и установка его переменной равной nil.Скорее всего, вы также добавили периодического наблюдателя времени, чтобы отслеживать ход игры.Когда вы делаете это, вы получаете обратно непрозрачный объект, который вы должны удерживать.Если вы не удалите этот элемент из плеера и не отпустите его / не установите ноль, AVPlayer не будет освобожден.Похоже, что Apple создает намеренный цикл хранения, который вы должны прервать вручную.Поэтому перед тем, как уничтожить AVPlayer, вам необходимо (пример):

[_player removeTimeObserver:_playerObserver];
[_playerObserver release]; //Only if you're not using ARC
 _playerObserver = nil;

В качестве дополнительной заметки вы, возможно, также настроили NSNotifications (я использую его, чтобы определить, когда игрок завершил игру) ...не забудьте также удалить их.

0 голосов
/ 28 августа 2014

@ Объяснение Аарона Хеймана точное, но решение для меня было очень простым.Просто реализуйте метод didFinishPlaying делегата проигрывателя и освободите проигрыватель там.

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    self.playerWord = nil;
}
0 голосов
/ 29 мая 2012

У меня была такая же проблема: AVAudioRecorder не начал запись.Мой пример немного отличается: у меня есть приложение на основе вкладок с несколькими AVAudioPlayers в разных представлениях.Для примера давайте предположим, что первое загруженное представление имеет 3 AVAudioPlayers, тогда как второе представление имеет один AVAudioPlayer и один AVAudioRecorder.Все они инициируются в методе viewDidLoad.

Устройство записи не работает во втором представлении.Когда я нажал кнопку записи, изображение слегка затрясло, и запись не началась.Странно, симулятор работал нормально и не показывал те же симптомы ... (кто-нибудь имеет представление, почему?)

После некоторых исследований и чтения этой темы я понял, что я не установил игроков в первомвид на ноль, так что я думаю, они все еще были в памяти, не позволяя запустить рекордер.Как только я установил для них значение nil в методе viewDidDisappear, он снова работал нормально.

вот что мне помогло:

-(void)viewDidDisappear:(BOOL)animated {
    firstPlayer = nil;
    secondPlayer = nil;
    thirdPlayer = nil;
}

ViewDidUnload не помогло, потому что View, а следовательно, иПеременные в самом классе не выгружались при переключении представлений.

Надеюсь, это может быть полезно и для других.

0 голосов
/ 08 апреля 2011

не должно быть [AVAudioRecorder record]; вместо play?

...