Hi everyone I am trying to play a sound in swift on my xcode game on launch automatically and I have tried a bunch of different code. I was able to write and run the it in Objective - C like below in the viewdidload method, I created a method for the sound itself and called that in viewdidload.
-(void)Loadingsound {
AudioServicesPlaySystemSound(Loadingsound);
}
-(void)viewDidLoad {
[super viewDidLoad];
NSURL *LoadingSound = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Tap Sound" ofType:#"wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)LoadingSound, &Loadingsound);
[self Loadingsound];
But now I am trying to replicate the same in swift but I am not able to do so. I saw this code below in another question asked on stack overflow but since now this is on Xcode 7.2.1 and Swift 2.0, is it possible that there is a new way to write this? This is the code I that I tried and the sound does not load when the game starts.
override func viewDidLoad() {
super.viewDidLoad()
if let soundURL = NSBundle.mainBundle().URLForResource("Tap Sound", withExtension: "wav") {
var mySound: SystemSoundID = 0
AudioServicesCreateSystemSoundID(soundURL, &mySound)
// Play
AudioServicesPlaySystemSound(mySound);
}
Also another way I tried of running the code was...
override func viewDidLoad() {
super.viewDidLoad()
var loadingsound = NSURL(fileURLWithPath:
NSBundle.mainBundle().pathForResource("Tap Sound", ofType: "wav"))
var audioPlayer = AVAudioPlayer()
audioPlayer = AVAudioPlayer(contentsOfURL: loadingsound, error: nil)
audioPlayer.prepareToPlay()
audioPlayer.play()
In this method when I try running it, the complies fails and shows an error which tells me to put an "!" sign after tying in "wav" and putting the bracket after that. After I put in the exclamation sign it tells me to replace the word "error" below and putin "filetypeHint" instead. Someone please help me out with this. The original was working sooo well in objective-c, can someone please help me in translating that exact code to swift. The other examples I saw as I showed were showing errors.
Thanks!
Check If your "Tap Sound" soundfile is in your project target. You need to load via URLForResource and like in my case don't set the extension type. You only need the filename. You can put it in a method like this.
func playMusic(_ filename: String) {
var audioPlayer: AVAudioPlayer?
let url = Bundle.main.url(forResource: filename, withExtension: nil)
if (url == nil) {
print("Could not find file: \(filename)")
return
}
do {
try audioPlayer = AVAudioPlayer(contentsOf: url!)
let player = audioPlayer
// From Documentation: Negative integer value to loop the sound indefinitely until you call the stop method.
player!.numberOfLoops = -1
player!.prepareToPlay()
player!.play()
} catch _ {
audioPlayer = nil;
}
}
// call the function with your soundfile
playMusic("Tap Sound")
Related
The sound file is playing when i add breakpoints inside the below functions. But the sound file is not playing if i run the application without breakpoint.
I am calling this function in button click as Sound().playSounds()
import AVFoundation
class Sound {
private var audioplayer:AVAudioPlayer!
func playSounds()
{
if let path = Bundle.main.path(forResource: "Audio/ring.mp3", ofType: nil)
{
let url = URL(fileURLWithPath: path)
do {
self.audioplayer = try AVAudioPlayer(contentsOf: url)
self.audioplayer.numberOfLoops = 3
self.audioplayer.prepareToPlay()
self.audioplayer.play()
}
catch {
print("Couldn't load file")
}
}
}
}
Your Sound object gets deallocated before it has a chance to play a sound.
Store it where you are calling it from:
var sound = Sound()
// for example to play sound call
func playPressed(){
sound.playSounds()
}
Chane your player into a global variable like this. Otherwise it'll be a deadlock.
var audioplayer:AVAudioPlayer!
Also you may want to change your resource path extracting logic to below,
if let path = Bundle.main.path(forResource: "ring.mp3", ofType: "mp3")
Or you can directly use Bundle.main.url(forResource: withExtention) method.
I have a WAV file with tones at around 18kHz. The audio is 16-bit PCM mono.
I am using the following function to play the file:
func playSound(name: String) {
let documents = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let path = documents.appending("/").appending(name)
let url = NSURL.fileURL(withPath: path)
do {
player = try AVAudioPlayer(contentsOf: url)
guard let player = player else { return }
player.prepareToPlay()
player.play()
} catch let error {
print(error.localizedDescription)
}
}
When I play it on my iOS 10.2 device I hear a series of tones between 1000Hz to 10000Hz. I've analyzed the rendered audio by capturing it and a frequency plot shows that the original content at 18kHz is there, but there are also tones present between 1000Hz to 10000Hz. When I play the same WAV file with VLC or any other desktop audio player, I don't hear the tones (which is expected since they're located around 18kHz). I suspect that the code above isn't loading the data correctly or that the player isn't properly initialized, so I need a seasoned iOS veteran who can tell me what I'm doing wrong.
Thank you in advance.
Check the following code it might work for you
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
var alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("button-09", ofType: "wav"))
println(alertSound)
// Removed deprecated use of AVAudioSessionDelegate protocol
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
var error:NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error)
audioPlayer.prepareToPlay()
audioPlayer.play()
}
}
I'm current developing a small game where balloons float up from the bottom of the screen and the player has to pop them before they reach the top.
Each balloon object contains a method to safely set up it's AVAudioPlayer's:
func setUpAudioPlayerWithFile(file:NSString, type:NSString) -> AVAudioPlayer? {
let path = NSBundle.mainBundle().pathForResource(file as String, ofType: type as String)
let url = NSURL.fileURLWithPath(path!)
var audioPlayer:AVAudioPlayer?
do {
try audioPlayer = AVAudioPlayer(contentsOfURL: url)
}catch {
print("BALLOON ERROR - AudioPlayer not avaliable.")
}
return audioPlayer
}
Then in each balloons init() method I run the following code:
if let popSound = self.setUpAudioPlayerWithFile("PopSound", type: "wav") {
self.popSound = popSound
}
Which works absolutely fine until a couple of minutes into the game. At this point I start receiving "BALLOON ERROR - AudioPlayer not available." in the console for every single balloon being spawned from then onwards indicating that my resource isn't being found?
At this time my SKEmitterNodes start to return nil as well. (2016-08-13 18:59:54.527 Stop & Pop[256:13785] *** -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL)
Is there anything obvious I'm missing that could be causing these errors?
I hope I've provided enough information, thank you for reading.
No... this won't work. You have to instantiate the audioPlayer variable into the Class Level.
I tried to do this, instantiated the var audioPlayer on another ViewController at the Class Level.
Your best bet is to localize this method into your ViewController, and put the audioPlayer here:
class YourClassName : Type {
var audioPlayer : AVAudioPlayer?
yourMethodForCalling() {
}
I have made a class which handles audio that is played in my app:
import AVFoundation
class GSAudio{
var soundFileNameURL: NSURL = NSURL()
var soundFileName = ""
var soundPlay = AVAudioPlayer()
func playSound (soundFile: String){
soundFileName = soundFile
soundFileNameURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(soundFileName, ofType: "aif", inDirectory:"Sounds")!)
do{
try soundPlay = AVAudioPlayer(contentsOfURL: soundFileNameURL)
} catch {
print("Could not play sound file!")
}
soundPlay.prepareToPlay()
soundPlay.play()
}
}
But the problem is when I call this code by using something like GSAudio().playSound("Start") from a different class, the sound does not play. Does anyone know why this is? Any help is appreciated.
Many thanks.
I have method AVAudioPlayer and its working fine when the button click action then perform this below method play well, but You want to call class and method (ex 'GSAudio().playSound("Start")') from different class, you create the delegate method to call, its work well.
#IBAction func btnPlayAction(sender: AnyObject) {
let fileURL: NSURL = NSURL(string: previewUrl)!
let soundData = NSData(contentsOfURL: fileURL)
do {
playerVal = try AVAudioPlayer(data: soundData!)
}
catch {
print("Something bad happened. Try catching specific errors to narrow things down",error)
}
playerVal.delegate = self
playerVal.prepareToPlay()
playerVal.play()
}
hope its helpful
Check Your Sound File (URL) Path..(print That) and Checkout file:// Is There Or Not That's Main Problem In Your Sound ULR Ok Add it File://
//Or Use this One
NSURL *SoundURL = [NSURL fileURLWithPath:YourFilePath];
Try This One And Let me Know is i'm Correct or not
I have a helper on GitHub that does what you want. It's properly better to make this class a Singleton so you can control your music better and don't create multiple instances of your helper.
https://github.com/crashoverride777/Swift-Music-Helper
For the var testAudio declaration in my iPhone app, I am receiving an error here
"Call can throw, but errors cannot be thrown out of a property initializer"
import UIKit
import AVFoundation
class ViewController: UIViewController {
var testAudio = AVAudioPlayer(contentsOfURL: NSURL (fileURLWithPath: NSBundle.mainBundle().pathForResource("testAudio", ofType: "wav")!), fileTypeHint:nil)
This happened when I moved to the Xcode 7 beta.
How can I get this audio clip functioning in Swift 2.0?
Swift 2 has a brand new error handling system, you can read more about it here: Swift 2 Error Handling.
In your case, the AVAudioPlayer constructor can throw an error. Swift won't let you use methods that throw errors in property initializers because there is no way to handle them there. Instead, don't initialize the property until the init of the view controller.
var testAudio:AVAudioPlayer;
init() {
do {
try testAudio = AVAudioPlayer(contentsOfURL: NSURL (fileURLWithPath: NSBundle.mainBundle().pathForResource("testAudio", ofType: "wav")!), fileTypeHint:nil)
} catch {
//Handle the error
}
}
This gives you a chance to handle any errors that may come up when creating the audio player and will stop Xcode giving you warnings.
If you know an error won't be returned you can add try! beforehand:
testAudio = try! AVAudioPlayer(contentsOfURL: NSURL (fileURLWithPath: NSBundle.mainBundle().pathForResource
Works for me in Swift 2.2
But don't forget to add the fileName.mp3 to the project Build phases->Copy Bundle Resources (right click on the project root)
var player = AVAudioPlayer()
func music()
{
let url:NSURL = NSBundle.mainBundle().URLForResource("fileName", withExtension: "mp3")!
do
{
player = try AVAudioPlayer(contentsOfURL: url, fileTypeHint: nil)
}
catch let error as NSError { print(error.description) }
player.numberOfLoops = 1
player.prepareToPlay()
player.play()
}