How to deactivate playing a sound - swift

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() ^^!

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

Can't play local audio mp3 file with AVAudioPlayer

I want to download and play the sound from Google Translate (Text to Speech).
The mp3 file's downloaded successfull. I tried to play it with AVAudioPlayer, but there's no sound on both simulator and my real iPhone
I use XCode 10.2.1, Swift 5. Test on simulator (XSMax) and iPhone XSMax
import UIKit
import AVFoundation
class TextToSpeechGoogleTranslate: AVAudioPlayer, AVAudioPlayerDelegate {
var player: AVAudioPlayer?
func speak() {
let fileURL = URL(string: "https://translate.google.com/translate_tts?ie=UTF-8&total=1&idx=0&client=tw-ob&tl=vi&q=Hello" )!
let documentsUrl:URL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL?)!
let destinationFileUrl = documentsUrl.appendingPathComponent("voice.mp3")
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
try? FileManager.default.removeItem(at: destinationFileUrl)
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
print(destinationFileUrl)
do {
self.player = try AVAudioPlayer(contentsOf: destinationFileUrl)
self.player!.delegate = self
self.player!.prepareToPlay()
self.player!.volume = 1.0
self.player!.play()
}
catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
catch {
print("AVAudioPlayer init failed")
}
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: %#", error?.localizedDescription as Any);
}
}
task.resume()
}
}
Output:
Successfully downloaded. Status code: 200
file:///Users/macbook/Library/Developer/CoreSimulator/Devices/F43F9B03-674C-4EE1-8CAD-01B5145868DE/data/Containers/Data/Application/6D1A3310-386D-4706-9F1E-DFF536B2A43F/Documents/voice.mp3
I played that file in Finder. It's OK.
I just tried your code and it seems to work fine. Maybe the problem is in how you create the TextToSpeechGoogleTranslate object and call speak() on it. For example, here is what I tried:
class ViewController: UIViewController {
var test: TextToSpeechGoogleTranslate?
override func viewDidLoad() {
super.viewDidLoad()
test = TextToSpeechGoogleTranslate()
test!.speak()
}
}
If that doesn't help, can you post some code showing how you call this method?
import UIKit
import AVFoundation
class ViewController: UIViewController, AVAudioPlayerDelegate {
var audioPlayer = TextToSpeechGoogleTranslate()
override func viewDidLoad() {
super.viewDidLoad()
audioPlayer.delegate = self
audioPlayer!.speak()
}
}
1) create instance of your class
2) Confirm it's delegate
3) call your function after you received your data
4) while testing from device, don't forget to turn off silence mode (volume up)

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

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)")
}
}
}

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 initialize AVAudioPlayer in Swift

I have this file and want to use this file in another class, but this does not work. I assume that this is because I have not initialized the AVAudioPlayer in this file, so I tackled with this, but a message appeared, saying "Call can throw, but it is not marked with 'try' and the error is not handled" My implementation was unsuccessful. I have no idea how to deal with this. Could you point out what is wrong with the initialization and provide me with some code that works. Thanks in advance.
class SoundManager: AVAudioPlayer {
var _Sound: AVAudioPlayer!
override init() {
let url = NSBundle.mainBundle().URLForResource("rain", withExtension: "wav")
super.init(contentsOfURL: url!)
}
func playSound() {
if (url == nil) {
print("Could not find the file \(_Sound)")
}
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.numberOfLoops = -1
_Sound.play()
}
}
I recommend to use this way init you manager, It does not have to be subclass of AVAudioPlayer.
class SoundManager {
var _Sound: AVAudioPlayer!
var url: NSURL?
/**
init with file name
- parameter fileName: fileName
- returns: SoundManager
*/
init(fileName: String) {
url = NSBundle.mainBundle().URLForResource(fileName, withExtension: "wav")
}
func playSound() {
if (url == nil) {
print("Could not find the file \(_Sound)")
}
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.numberOfLoops = -1
_Sound.play()
}
}
Use
let manager = SoundManager(fileName: "hello")
manager.playSound()