AVAudioPlayer не воспроизводит звук - PullRequest
57 голосов
/ 05 ноября 2011

Я работаю над приложением для iOS, которое должно воспроизводить некоторые звуки с использованием фреймворка AVFoundation. Структура рабочего пространства в Xcode 4 содержит два проекта:

  • Рабочая область
    • Само приложение (основной проект)
    • служебная библиотека

После создания библиотеки утилит она создает статическую библиотеку, которая используется в основном приложении в качестве платформы.

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

NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *path = [NSString stringWithFormat:@"%@/sound.mp3", resourcePath];

NSURL *url = [NSURL fileURLWithPath:path];
NSError *error = nil;

AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url
                                                                    error:&error];
[audioPlayer play];

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

Я убедился, что фреймворк AVFoundation есть в обоих проектах.

Кроме того, мой класс использует протокол AVAudioPlayerDelegate и реализует эти два метода:

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error;

Ни один из этих методов не вызывается после попытки воспроизведения звука.

Если вместо этого я использую AudioToolbox framework, он воспроизводит звук. Но я заинтересован в использовании AVFoundation по нескольким причинам.

Есть идеи о том, что происходит? Я что-то упускаю из-за AVFoundation? Может ли это быть связано с использованием AVAudioPlayer внутри статической библиотеки?

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

Ответы [ 10 ]

149 голосов
/ 07 декабря 2011

Я нашел решение, и оно связано с тем, о чем я не упомянул и о котором не думал: я компилирую с автоматическим подсчетом ссылок (ARC).

ARC вставляет вызов выпуска в аудиоигрок, поэтому он освобождается сразу после выхода из метода, в котором он был создан.Это не имеет ничего общего с AVAudioPlayer, но с ARC.

Чтобы решить эту проблему, я просто создал атрибут AVAudioPlayer для класса, который работает со звуками, чтобы он больше не выпускался ARC,Ну, по крайней мере, он не будет выпущен, пока не будет выпущен экземпляр этого класса.

Для получения дополнительной информации о ARC см. Автоматический подсчет ссылок: обнуление слабых ссылок с подробной информацией о том, почему у меня былэтот вопрос.

35 голосов
/ 18 апреля 2012

Да, абсолютно; ARC был причиной моего кода.

Я ввел свойство:

@property (strong, nonatomic) AVAudioPlayer *audioPlayer;

и это заставило все работать нормально.

26 голосов
/ 07 марта 2014

используйте это, это будет работать определенно ....

AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];

NSURL *url = [NSURL fileURLWithPath:@"path of the sound file :)"];
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[_player setDelegate:self];
[_player prepareToPlay];
[_player play];
17 голосов
/ 05 декабря 2011

Вы настроили AVAudioSession?

У меня была похожая проблема, и я исправил ее, используя что-то вроде этого:

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:NULL];

или

[audioSession setCategory:AVAudioSessionCategoryPlayback error:NULL];

Надеюсь, это поможет.

3 голосов
/ 05 ноября 2017

Даже если audioPlayer var объявлен в области видимости класса, он не будет воспроизводиться. По крайней мере, на iOS 10 iPhone 5c физическое устройство.

play() результат равен true, поэтому ошибок не возникает.

Пришлось добавить это ( Swift 3, 4 ) и теперь он правильно воспроизводит звук.

let session = AVAudioSession.sharedInstance()
try! session.setCategory(AVAudioSessionCategoryPlayback)
0 голосов
/ 10 августа 2018

Вы можете использовать AVPlayerViewController из AVKit взамен для аудио и видео.Код доступен как для быстрого, так и для объективного c здесь .

0 голосов
/ 29 июня 2016

У меня была такая же проблема. Я решил это, добавив строку ниже в файле .h:

@property (strong, nonatomic) AVAudioPlayer *audioPlayer;

И в .m файле:

NSError *error;
NSString *soundFilePath = [NSString stringWithFormat:@"%@/dancepechance.mp3",
                               [[NSBundle mainBundle] resourcePath]];
    NSURL *url = [NSURL fileURLWithPath:soundFilePath];
    self.audioPlayer = [[AVAudioPlayer alloc]
                                  initWithContentsOfURL:url
                                  error:&error];
    NSLog(@"Error %@",error);
    [self.audioPlayer prepareToPlay];
    [self.audioPlayer play];
0 голосов
/ 23 февраля 2016

Быстрое решение:

  import AVFoundation

  // define your player in class
  var player = AVAudioPlayer()

  override func viewDidLoad() {
    super.viewDidLoad() 
  }
0 голосов
/ 16 октября 2014

Пожалуйста, оставайтесь на странице некоторое время, я столкнулся с той же проблемой.и использовать сон, чтобы решить это.


NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                                             pathForResource:@"sounds-1027-are-you-kidding"
                                             ofType:@"mp3"]];
        AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc]
                                      initWithContentsOfURL:url
                                      error:nil];
        [audioPlayer play];
        sleep(2);

0 голосов
/ 23 января 2014

Я создал проект с открытым исходным кодом для простого аудиоплеера. Посмотрите на это, если у вас есть какие-либо проблемы с воспроизведением звука в iOS (также в фоновом режиме): https://github.com/wzbozon/DKAudioPlayer

...