2017-02-11 1 views
2

У меня есть неприятная проблема с получением звука для игры в игру, но, похоже, не получается получить какой-либо выход через AVAudioPlayer. Первоначально это было настроено как класс, но когда он не работал, я пробовал жестко кодировать звуковой вывод, чтобы проверить, есть ли там проблема. Он по-прежнему не работает, и я попробовал несколько разных файлов, чтобы исключить проблемный аудиофайл или формат. URL-адрес восстанавливается, но аудиоплеер просто не выводит звук.Звук, воспроизводимый через SKAction, но не через AVAudioPlayer

Я прочитал несколько тем о похожих проблемах и искал системные настройки звука, но это не имеет никакого значения. Было высказано предположение, что Симулятор не может выводить звук в некоторых обстоятельствах, но я не думаю, что это имеет место здесь.

let myFile = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("gong", ofType: "wav")!) 
    print ("URL data: \(myFile)") 
    do{ 
     let audioPlayer = try AVAudioPlayer(contentsOfURL:myFile) 
     audioPlayer.prepareToPlay() 
     audioPlayer.play()  
    }catch { 
     print("Error playing sound") 
    } 

Однако это играет отлично:

self.runAction(SKAction.playSoundFileNamed("gong", waitForCompletion: false)) 

мне нужна функциональность AVAudioPlayer, как я хочу, чтобы иметь возможность начать остановку и регулировать громкость звука, как это петли. Я использую XCode 7.3.1 и Swift 2.2.

Любые идеи?

Большое спасибо, Kw

+0

Вы импортировали AVFoundation правильно? – Pierce

+0

Да. Думаю, я это проработал. Мне нужно было создать экземпляр на AVAudioPlayer в области, которая является постоянной, поэтому она не удаляется сборкой мусора. Кроме того, я думаю, что команда prepareToPlay не успевает загрузить файл в память до выполнения команды воспроизведения, и игрок также выходит из сферы действия и собирается почти мгновенно, когда вызывается код, в который он вызван. Результат: нет шансов на игру. Я собираюсь создать класс, который предварительно загружает все звуки в память на этапе init() с помощью prepareToPlay, чтобы их можно было вызвать, чтобы играть мгновенно. Спасибо – Kwangle

+0

Это было то, что я собирался сказать, я никогда не использовал метод prepareToPlay, и мне сказали, что это обычно не нужно. – Pierce

ответ

1

Говоря о Swift 2, я думаю, вы должны попробовать другой подход, чтобы получить URL:

import AVFoundation 

func playMusic(filename: String) { 
    let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil) 
    if (url == nil) { 
     print("Could not find file: \(filename)") 
     return 
    } 
    do { backgroundMusicPlayer = try AVAudioPlayer(contentsOfURL: url!, fileTypeHint: nil) } 
    catch let error as NSError { print(error.description) } 
    if let player = backgroundMusicPlayer { 
     player.volume = 1 
     player.numberOfLoops = -1 
     player.prepareToPlay() 
     player.play() 
    } 
} 
0

Я хотел бы добавить ответ, который мне помогает , play() метод AVAudioPlayer «s является асинхронным, так что я на самом деле нашел лучший способ, чтобы играть звуковой файл, не испытывая LAG в первый раз, он загружается в память является вызов асинхронно:

СВИФТ 2

import AVFoundation 

var audioPlayer: AVAudioPlayer? 

init() { 

    let soundURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("FileName", ofType: "wav")!) 
    if let soundURL = soundURL { 

     do { 
      self.audioPlayer = try AVAudioPlayer(contentsOfURL: soundURL) 
     } catch let error as NSError { 
      print(error.description) 
     } 
    } else { 
     // Handle situation where URL isn't found 
     print("Sound file URL not found") 
    } 

} 

func playSound() { 
    guard let audioPlayer = audioPlayer else { return } 
    // Now we can play the sound asynchronously - which will eliminate any lag upon initial play 
    let qualityOfServiceClass = QOS_CLASS_BACKGROUND 
    let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0) 
    dispatch_async(backgroundQueue, { 
     audioPlayer.play() 
    }) 

} 

СВИФТ 3

import AVFoundation 

var audioPlayer: AVAudioPlayer? 

init() { 

    let soundURL = URL(fileURLWithPath: Bundle.main.path(forResource: "FileName", ofType: "wav")!) 
    if let soundURL = soundURL { 

     do { 
      self.audioPlayer = try AVAudioPlayer(contentsOf: soundURL) 
     } catch let error { 
      print(error.description) 
     } 
    } else { 
     // Handle situation where URL isn't found 
     print("Sound file URL not found") 
    } 

} 

func playSound() { 
    guard let audioPlayer = audioPlayer else { return } 
    // Now we can play the sound asynchronously - which will eliminate any lag upon initial play 
    DispatchQueue.global().async { 
     audioPlayer.play() 
    } 

} 

идея этого является включение какой-то Soundmanager CLA ss в вашу модель. Я обычно создаю класс, подобный этому, который имеет AVAudioPlayer для каждого звука, который мне нужен во всем приложении, и я могу создать его экземпляр, когда загружу свой ViewController, который инициализирует отдельные аудиоплееры на свой собственный метод init(). Затем я могу играть в каждый файл, используя собственные методы игры. Если у вас есть множество разных звуков, он также может помочь использовать enum для организации разных файлов и иметь один настраиваемый метод play(), который будет воспроизводить любой файл, передаваемый в качестве запроса.

+0

Спасибо, Пирс. В итоге я сделал что-то очень похожее на это. Я создал словарь объектов AVAudioPlayer с именем файла звукового файла в качестве ключа. Метод нацелен на игрока через имя файла, переданное как параметр, и они мгновенно воспроизводятся. Единственная проблема заключается в том, что у вас есть один AVAudioPlayer для каждого звука, поэтому вы не можете одновременно использовать несколько экземпляров одного и того же звука. Я улучшил эту ситуацию, установив звук в исходное состояние, когда появляется второй игровой вызов, пока он все еще играет. Это звучит идеально в большинстве ситуаций. Надеюсь, это полезно и спасибо всем. – Kwangle

Смежные вопросы