Swift Sound Effects // Why Won't My Code Work? - swift

I have been trying to make a game to teach myself swift, and cant seem to get this code to work. I am extremely new to this, and can't seem to find out why it won't work... XCode doesn't flag any problems, build sucseed, and debugger even prints "Got to Stage 1 & Got to Stage 2... anything help?
I Imported AVFoundation..
class GAME {
class func SuperStartGame(playerwhowon1: SKSpriteNode) {
var player = AVAudioPlayer()
func PlaySound() {
guard let URL = Bundle.main.url(forResource: "PowerUp", withExtension: "mp3")
else {
print("Didn't Find URL")
return
}
do {
print("Got to Stage 1")
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: URL, fileTypeHint: "mp3")
player.prepareToPlay()
player.play()
print("Got to Stage 2")
} catch let error as NSError {
print("error: \(error.localizedDescription)")
}
RoundNumber += 1
Round.text = "Round \(RoundNumber)"
if playerwhowon1 == Mine {
MyScore.run(addscoreM) {
PlaySound()
Round.run(NewRoundForRound) {
...
Code keeps going.. thats the only part that is relevant to the sound. I added the sound file to Xcode, and made sure it was added tot he project target... it is in my main bundle.

Make sure that your device isn't muted
mp3 file is copied to bundle
Example VC playing sound:
class ViewController: UIViewController {
var game = Game()
#IBAction func playAction(_ sender: UIButton) {
game.playSound()
}
}
class Game {
var player: AVAudioPlayer?
func playSound() {
guard let URL = Bundle.main.url(forResource: "SampleAudio", withExtension: "mp3") else {
print("Didn't Find URL")
return
}
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: URL, fileTypeHint: "mp3")
player?.prepareToPlay()
player?.play()
} catch let error as NSError {
print("\(error.localizedDescription)")
}
}
}

Related

How to play sound after each network request is successful?

I want to play a sound after each network request is successful. I have some objects that I want to send to the server using a for loop. In each iteration I'm sending a request to the server and after each request is complete, I want to play a sound.
I've tried this:
for object in objects {
sendObjectToServer(object)
}
func playSound() {
let url = Bundle.main.url(forResource: "sound", withExtension: "mp3")!
let player = try! AVAudioPlayer(url)
player.play()
}
func sendObjectToServer(object: Object) {
URLSession.shared.dataTask(with url: object.url) {(data,response,error) in
DispatchQueue.main.async {
playSound() // doesn't play sound synchronously
}
}
}
Why are you using the main thread for background-related operations. Only update your UI in the Dispatch.main.async code:
Try this on a physical device (tested and worked)
import AVFoundation
for object in objects {
DispatchQueue.global(qos: .background).async {
sendObjectToServer(object)
}
}
var player: AVAudioPlayer?
func playSound() {
guard let url = Bundle.main.url(forResource: "sound", withExtension: "mp3") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
/* The following line is required for the player to work on iOS 11. Change the file type accordingly*/
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
/* iOS 10 and earlier require the following line:
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
}
}
func sendObjectToServer(object: Object) {
URLSession.shared.dataTask(with url: object.url) {(data,response,error) in
// Custom Logic
playSound()
}
}

Swift 4 / Xcode 9.2 - Audio Player

For playing back audio I went through a bigger post here. Resulting in the best version now, but:
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
does not work, giving a String member error on .playback. HereĀ“s the full code:
import Foundation
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
#IBAction func triggerSample(_ sender: Any) {
playSound()
}
var player: AVAudioPlayer?
func playSound() {
guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
/* The following line is required for the player to work on iOS 11. Change the file type accordingly*/
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
/* iOS 10 and earlier require the following line:
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
UPDATE: The solution is written in the commented out sections above: Regarding this, use the following playSound()for Xcode 9.2:
func playSound() {
guard let url = Bundle.main.url(forResource: "MWSTW_Bowie", withExtension: "mp3") else { return }
do {
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
} //end of do/catch
} // end of playSound()
That works just fine. Just make sure you have an MP3 in the App bundle named "soundName" of type .mp3

Playing sound in Xcode 9.2

I am having some issues with playing sound in Xcode 9.2.
I tried watching few different tutorials and guides, but with no luck.
Either code is outdated, my app with crashes, the sound doesn't work, or it starts and cuts out after few milliseconds...
func updateDiceImages() {
// This is where the actual sound is attempted to play,
it should be triggered every time the button is pressed. Rest of the app works fine.
var soundEffect: AVAudioPlayer?
let path = Bundle.main.path(forResource: "rollingDice.wav", ofType:nil)!
let url = URL(fileURLWithPath: path)
do {
soundEffect = try AVAudioPlayer(contentsOf: url)
soundEffect?.play()
} catch {
print(error)
}
...
I am just not sure what I am doing wrong, tried tons of variations.
I am completely open to giving any information that I can provide. I didn't paste the whole code so it doesn't bother or swamp the people that try to read it.
Thank you so much for the help! =)
This is a taken piece of code from one of my applications, it works completely.
import AVFoundation
final class AudioManager {
private init() { }
static let shared = AudioManager()
private var player: AVAudioPlayer?
enum SoundType {
case incomingCall
}
open func playSound(_ type: SoundType) {
switch type {
case .incomingCall:
playIncomingCall()
}
}
// MARK: - Sounds
private func playIncomingCall() {
guard let url = Bundle.main.url(forResource: "incoming", withExtension: "wav") else { return }
playSound(url)
}
private func playSound(_ url: URL) {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
guard let player = player else { return }
player.numberOfLoops = -1 // infinity loop
player.prepareToPlay()
player.play()
debugPrint("playSound play sound")
} catch {
debugPrint(error.localizedDescription)
}
}
open func stop() {
player?.stop()
}
}

Swift 3: stream MP3 file from server

I am trying to stream a sample mp3 from a url. It is a very small sample file. However, when I press the play button nothing happens. Well, no sound plays.
I am rather new to Swift and very much a noob so here is the full View Controller as I am unsure what you might need.
import UIKit
import AVKit
import AVFoundation
import Foundation
class ViewController: UIViewController {
#IBAction func playButton(_ sender: Any) {
print("pressed")
let urlstring = "http://cdn.mos.musicradar.com/audio/samples/80s-heat-demos/AM_Eighties08_85-01.mp3"
let url = NSURL(string: urlstring)
print("the url = \(url!)")
downloadFileFromURL(url: url!)
}
override func viewDidLoad() {
// Do any additional setup after loading the view
}
func downloadFileFromURL(url:NSURL){
weak var weakSelf = self
var downloadTask:URLSessionDownloadTask
downloadTask = URLSession.shared.downloadTask(with: url as URL, completionHandler: { (URL, response, error) -> Void in
print("URL = \(URL)")
weakSelf!.plays(url: URL! as URL)
})
downloadTask.resume()
}
func plays(url:URL) {
print("playing \(url)")
do {
var playerItem = AVPlayerItem(url: url as URL)
player = AVPlayer(url : url)
player.volume = 1.0
player.play()
} catch let error as NSError {
print(error.localizedDescription)
} catch {
print("AVAudioPlayer init failed")
}
}
}
in my console I am getting this:
pressed
the url = http://cdn.mos.musicradar.com/audio/samples/80s-heat-demos/AM_Eighties08_85-01.mp3
URL = Optional(file:///private/var/mobile/Containers/Data/Application/C255E8F4-DDBA-43BB-BC33-AF71C08BBDFD/tmp/CFNetworkDownload_tm0O8v.tmp)
playing file:///private/var/mobile/Containers/Data/Application/C255E8F4-DDBA-43BB-BC33-AF71C08BBDFD/tmp/CFNetworkDownload_tm0O8v.tmp
URL = Optional(file:///private/var/mobile/Containers/Data/Application/C255E8F4-DDBA-43BB-BC33-AF71C08BBDFD/tmp/CFNetworkDownload_J1f2LF.tmp)
playing file:///private/var/mobile/Containers/Data/Application/C255E8F4-DDBA-43BB-BC33-AF71C08BBDFD/tmp/CFNetworkDownload_J1f2LF.tmp
Can anyone help me solve this? I just want to be able to play this sound on click of the button from the server not locally.
Please try to use this code for you player function.
func plays(url:URL) {
print("playing \(url)")
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url)
guard let player = player else { return }
player.play()
} catch let error as NSError {
print(error.localizedDescription)
} catch {
print("AVAudioPlayer init failed")
}
}

How to deactivate playing a sound

I have been trying to figure out how to deactivate playing a sound. I tried to attached a removeAtionWithKey with a sound action, and it seems to be working fine, but the sound does not stop to play. Is this because I am using action in SpriteKit?
If this problem is solved here instead of importing AVFoundation, then could you give me some examples to stop a sound from being played? Or, if importing AVFoundation is preferred in this case, could you provide me with some code as well.
Here's an example of how to use AVFoundation.
import Foundation
import AVFoundation
var backgroundMusicPlayer: AVAudioPlayer!
func playBackgroundMusic(filename: String) {
let url = NSBundle.mainBundle().URLForResource(filename, withExtension: "mp3")
if (url == nil) {
print("Could not find the file \(filename)")
}
do { backgroundMusicPlayer = try AVAudioPlayer(contentsOfURL: url!, fileTypeHint: nil) } catch let error as NSError { print(error.debugDescription)}
if backgroundMusicPlayer == nil {
print("Could not create audio player")
}
backgroundMusicPlayer.numberOfLoops = -1
backgroundMusicPlayer.prepareToPlay()
backgroundMusicPlayer.play()
}
var Sound: AVAudioPlayer!
func playSound(filename: String) {
let url = NSBundle.mainBundle().URLForResource(filename, withExtension: "wav")
if (url == nil) {
print("Could not find the file \(filename)")
}
do { Sound = try AVAudioPlayer(contentsOfURL: url!, fileTypeHint: nil) } catch let error as NSError { print(error.debugDescription)}
if Sound == nil {
print("Could not create audio player")
}
Sound.prepareToPlay()
Sound.play()
}
And here's what you want to achieve (if I understood well):
#IBAction func MusicButton(sender: UIButton) {
if backgroundMusicPlayer.playing {
backgroundMusicPlayer.stop()
}
else {
playBackgroundMusic("SomeMusicName")
}
}
Stopping the music with AVFoundation is as easy as .stop() ^^!