2017-02-11 3 views
2

ゲームでサウンドを再生するのに厄介な問題がありますが、AVAudioPlayerで出力が得られないようです。もともとこれはクラスとしてセットアップされていましたが、うまくいかなかったときに問題があるかどうかを確かめるためにサウンド出力をハードコーディングしてみました。それでも動作しませんでした。問題のあるオーディオファイルやフォーマットを除外するために、いくつかの異なるファイルを試しました.URLは取得されていますが、audioPlayerはサウンドを出力していないようです。AVAudioPlayerではなくSKActionで再生するサウンド

私は同様の問題についていくつかのスレッドを読んで、システムサウンドの設定を手伝ってきましたが、違いはありません。 Simulatorがいくつかの状況でサウンドを出力することはできないと示唆されていますが、ここではそうは思われません。

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コマンドは、プレイコマンドが実行される前にファイルをメモリにロードする時間がなく、プレイヤーもスコープ外に出て、呼び出されたコードブロックが終了したときにほぼ即座に収集されると思います。結果:演奏する機会ではありません。 prepareToPlayを使ってinit()ステージですべてのサウンドをメモリにプリロードするクラスを作成し、即座に再生するために呼び出すことができます。ありがとう – Kwangle

+0

これは私が言うつもりだったものです、私は 'prepareToPlay'メソッドを使ったことは一度もありませんでした。 – Pierce

答えて

1

についてスウィフト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

私は私を助け答えを追加したいと思います。 AVAudioPlayerplay()メソッドは非同期ですので、私は実際に遅れを経験することなく、サウンドファイルを再生するための最良の方法を見つけた、それがメモリにロードされる最初の時間は、非同期的に呼び出すことにより、次のとおりです。

SWIFT 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() 
    }) 

} 

SWIFT 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のいくつかの並べ替えを組み込むことですモデルをモデルに追加します。私は通常、私のアプリケーション全体に必要なすべてのサウンドのためのAVAudioPlayerを持つこのようなクラスを作成し、独自のinit()メソッドで個々のaudioPlayersを初期化するViewControllerをロードするときにインスタンス化できます。それから私は自分の演奏方法を使って各ファイルを再生することができます。たくさんの音がある場合は、enumを使用して別のファイルを整理し、リクエストとして渡されるファイルを再生するカスタムのplay()メソッドを使用することもできます。

+0

私はこれに非常に類似した何かをやり終えた。サウンドファイルのファイル名をキーとしてAVAudioPlayerオブジェクトの辞書を作成しました。メソッドは、パラメータとして渡されたファイル名を介してプレーヤをターゲットにし、それらは即座に再生されます。唯一の問題は、サウンドごとに1つのAVAudioPlayerがあるため、同じサウンドの複数のインスタンスを同時に再生できないことです。私は、再生中にセカンドプレイコールが到着したときにサウンドをその開始にリセットするように設定することで、その状況を改善しました。それはほとんどの状況で完璧に聞こえる。これが便利でありがとうと思います。 – Kwangle

関連する問題