AVAudioPlayer на Mac не воспроизводится / вылетает - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь воспроизвести mp3 из моего приложения Mac Cocoa. Выглядело довольно просто использовать AVAudioPlayer. Но это не работает. Я посмотрел онлайн, и большинство проблем, которые я вижу, связано с освобождением объекта игрока, но я не думаю, что это моя проблема. Объект player является постоянным и отвечает на вызовы функций-членов.

Я создаю AVAudioPlayer из URL-адреса примерно так:

class Soundtrack:Bobject, AVAudioPlayerDelegate {

    var player:AVAudioPlayer!
    var volume:Float = 1.0
    var pan:Float = 0.0
    var rate:Float = 1.0
    var numberOfLoops:Int = -1
    var url:URL?
    var reference = false

    ...

   func setFile(_ url:URL) throws {
    self.url = url
    player = try AVAudioPlayer(contentsOf: url)
    player.prepareToPlay()
    print("player duration: \(player.duration)")
    print("player settings: \(player.settings)")
    player.play()  // this is commented / uncommented out for testing
}

Объект Soundtrack - это объект, который я создаю и добавляю в постоянную иерархию объектов перед вызовом функции setFile. URL-адрес указывает на файл, который я просматриваю на рабочем столе перед созданием саундтрека - например, «file: ///Users/bob/Desktop/2_02_Cycle.mp3».

Если я немедленно вызову player.play (), как показано выше, то это работает. Песня играет, пока я не остановлюсь. Однако, если я закомментирую эту функцию play () и вызову ее позже, например, нажатием клавиши, она не будет воспроизведена. Он говорит, что это успешно:

player.prepareToPlay()
let ok = player!.play(atTime:atTime)
print("play \(ok)")

Здесь 'ok' возвращает true. Кроме того, если я проверяю значение player.isPlaying с течением времени, примерно на секунду или около того (80-90 кадров) он также возвращает TRUE, затем он останавливается. Но я никогда ничего не слышу. Проверка настроек проигрывателя сообщает правильность длительности, 175 секунд, а также всю информацию о скорости / громкости / панорамировании. Я могу вызывать play () и pause () несколько раз, и каждый раз, когда я играю, он думает, что он играет в течение одной секунды.

Однако я упомянул, что песня воспроизводится, если я запускаю ее сразу после создания AVAudioPlayer. В этом случае я могу приостановить песню, вызвав pause (), но если я затем попробую воспроизвести ее снова с помощью play () или play (atTime :), то произойдет сбой, с помощью этого: "com.apple.audio.IOThread .client (36): EXC_BAD_INSTRUCTION (code = EXC_I386_INVOP, subcode = 0x0) ". Я приложил изображение трассировки стека.

РЕДАКТИРОВАТЬ: сегодня утром, после вчерашней проблемы, она больше не падает. Он просто не играет, если я не играю сразу после создания. Хотя он говорит, что играет, на секунду. Кроме того, я распечатал переменную player.currentTime для секунды, которую он «воспроизводит» без вывода сообщений, и он говорит, что время - какое-то огромное число, например 297130 или 594407. Это несмотря на то, что я запрашиваю время начала воспроизведения 0 На самом деле, при дальнейшем тестировании это число кажется случайным - иногда оно мало, например 10 или 35. Когда это разумное число, игрок сообщает, что продолжает играть - оно не останавливается через секунду. Но я никогда не слышу ни звука.

Я не думаю, что это может быть проблемой освобождения игрока, потому что я могу продолжать ссылаться на него и вызывать его функции на протяжении всего процесса. Кто-нибудь знает, в чем еще может быть проблема?

enter image description here

1 Ответ

0 голосов
/ 27 июня 2018

Хорошо - я решил это. Я не осознавал, что play (atTime :) использует текущее время аудиоустройства. Как только я использовал устройство CurrentTime, оно заиграло. Довольно глупая ошибка с моей стороны. Я понятия не имею, хотя, почему это терпело крах вчера. Это не повторилось.

...