buttons are not playing the sound. I have included the wav file - swift

The buttons are not playing the sound?
How can you make the coding more correct?
import UIKit
import AVFoundation
//var audioPlayer: AVAudioPlayer!
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
let path = Bundle.main.path(forResource: "BtnSon", ofType: " WAV")
let soundURL = URL(fileURLWithPath: (path)!)
do {
try audioPlayer = AVAudioPlayer(contentsOf: soundURL)
audioPlayer.prepareToPlay()
} catch let err as NSError {
print(err.debugDescription)
}
}
#IBAction func numberPressed(Sender: UIButton){
playSound()
}
func playSound(){
if audioPlayer.isPlaying {
audioPlayer.stop()
}
audioPlayer.play()
}
}

Try this:
import UIKit
import UIKit
import AVFoundation
//var audioPlayer: AVAudioPlayer!
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
//--------------------------------------------------------> No space before _W
guard let soundURL = Bundle.main.url(forResource: "BtnSon", withExtension: "WAV") else {
fatalError("You have failed to add 'BtnSon.WAV' in your app bundle.")
}
do {
try audioPlayer = AVAudioPlayer(contentsOf: soundURL)
audioPlayer.prepareToPlay()
} catch let err as NSError {
print(err.debugDescription)
}
}
#IBAction func numberPressed(_ sender: UIButton){
playSound()
}
func playSound(){
if audioPlayer.isPlaying {
audioPlayer.stop()
}
audioPlayer.play()
}
}
And be careful, iOS's file system is case-sensitive.

Related

how to have separate videos that play with separate buttons

can anyone please help me, I am trying to add separate buttons to play separate videos in the same view controller but I don't know how to.
this is my code, how do I do this?
import UIKit
import AVKit
class ViewController: UIViewController {
#IBAction func Town(_ sender: Any) {
if let path = Bundle.main.path(forResource: "grey", ofType: "mov") {
let video = AVPlayer(url: URL(fileURLWithPath: path))
let videoPlayer = AVPlayerViewController()
videoPlayer.player = video
self.present(videoPlayer, animated: true, completion: {
video.play()
})
}
func viewDidLoad() {
super.viewDidLoad()
}
}
}
To play 2 videos simultaneously in same viewController, you need to create 2 separate views and 2 respective buttons in your Storyboard.
Remaining functionality will go inside your IBActions.
Please use following code:
class VideoPlaybackViewController: UIViewController {
#IBOutlet weak var videoView1: UIView!
#IBOutlet weak var videoView2: UIView!
#IBAction func playFirstVideo(_ sender: Any) {
guard let path = Bundle.main.path(forResource: "640", ofType: "mov") else {
print("Video Source Not Found")
return
}
playVideo(playbackURL: URL(fileURLWithPath: path), playerView: videoView1)
}
#IBAction func playSecondVideo(_ sender: Any) {
guard let path = Bundle.main.path(forResource: "720", ofType: "mov") else {
print("Video Source Not Found")
return
}
playVideo(playbackURL: URL(fileURLWithPath: path), playerView: videoView2)
}
func playVideo(playbackURL: URL, playerView: UIView) {
let player = AVPlayer(url: playbackURL)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = playerView.bounds
playerView.layer.addSublayer(playerLayer)
player.play()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Please see the screen with this implementation
I used this code and it worked perfectly
import UIKit
import AVKit
class ViewController: UIViewController {
#IBOutlet weak var videoView1: UIButton!
#IBOutlet weak var videoView2: UIButton!
#IBAction func playFirstVideo(_ sender: Any) {
if let path = Bundle.main.path(forResource: "grey", ofType: "mov") {
let video = AVPlayer(url: URL(fileURLWithPath: path))
let videoPlayer = AVPlayerViewController()
videoPlayer.player = video
self.present(videoPlayer, animated: true, completion: {
video.play()
})
}
}
#IBAction func playSecondVideo(_ sender: Any) {
if let path = Bundle.main.path(forResource: "go", ofType: "mov") {
let video = AVPlayer(url: URL(fileURLWithPath: path))
let videoPlayer = AVPlayerViewController()
videoPlayer.player = video
self.present(videoPlayer, animated: true, completion: {
video.play()
})
}
}
}

"Thread1:Fatal error:Unexpectedly found nil while unwrapping an Optional value"

1these are the wav files I used
2I attached a screenshot of where it is throwing this error.
this is what I have right now. I thought I had everything correct. I know it has something to do with using an optional but not sure how to fix it.
import UIKit
import AVFoundation
class SecondViewController: UIViewController
{
var audioPlayer: AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
do
{
let catSound = Bundle.main.path(forResource: "Cat", ofType: "wav")
let horseSound = Bundle.main.path(forResource: "Horse", ofType: "wav")
let dogSound = Bundle.main.path(forResource: "Dog", ofType: "wav")
let raccoonSound = Bundle.main.path(forResource: "Raccoon", ofType: "wav")
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: catSound!))
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: horseSound!))
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: dogSound!))
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: raccoonSound!))
}
catch
{
print(error)///
}
}
#IBAction func cat(_ sender: Any)
{
audioPlayer?.play()
}
#IBAction func horse(_ sender: Any)
{
audioPlayer?.play()
}
#IBAction func dog(_ sender: Any)
{
audioPlayer?.play()
}
#IBAction func raccoon(_ sender: Any){
audioPlayer?.play()
}
}
As #Chris and #inexcitus mentioned, your complete code would look like.
class SecondViewController: UIViewController {
var audioPlayer: AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func cat(_ sender: Any)
{
if let catSound = Bundle.main.path(forResource: "cat", ofType: "wav") {
audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: catSound))
audioPlayer?.play()
}else {
print("Cat File is missing")
}
}
#IBAction func horse(_ sender: Any)
{
if let horseSound = Bundle.main.path(forResource: "horse", ofType: "wav") {
audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: horseSound))
audioPlayer?.play()
}else {
print("Horse File is missing")
}
}
#IBAction func dog(_ sender: Any)
{
if let dogSound = Bundle.main.path(forResource: "dog", ofType: "wav") {
audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: dogSound))
audioPlayer?.play()
}else {
print("Dog File is missing")
}
}
#IBAction func raccoon(_ sender: Any)
{
if let raccoonSound = Bundle.main.path(forResource: "raccoon", ofType: "wav") {
audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: raccoonSound))
audioPlayer?.play()
}else {
print("Raccoon File is missing")
}
}}
One of your resources is nil.
You should check if your resoruce is nil before (forcefully) unwrapping it:
if let catSound = Bundle.main.path(forResource: "Cat", ofType: "wav")
{
audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: catSound))
}
Do this for every resource and use the debugger to see which one is nil.
Case sensitivity matters.
The files are lowercased ("cat") but the parameter strings in the code are uppercased ("Cat"). The parameter string and the file name must match exactly.
Your code is not very useful anyway because it overwrites the audio player instance three times in viewDidLoad.
A more efficient solution is to create a method to load the file and play the sound and to use the URL related API of Bundle.
The force unwrapping is fine because all files must be in the bundle at compile time. A design mistake (file is missing or name is misspellt) can be fixed immediately.
class SecondViewController: UIViewController
{
var audioPlayer: AVAudioPlayer!
#IBAction func cat(_ sender: Any) {
playSound(withName: "cat")
}
#IBAction func horse(_ sender: Any) {
playSound(withName: "horse")
}
#IBAction func dog(_ sender: Any) {
playSound(withName: "dog")
}
#IBAction func raccoon(_ sender: Any){
playSound(withName: "raccoon")
}
func playSound(withName name : String) {
let sound = Bundle.main.url(forResource: name, withExtension: "wav")!
audioPlayer = try! AVAudioPlayer(contentsOf: sound)
audioPlayer.play()
}
}

Can't solve this? How would you fix this? "Variable binding in a condition requires an initializer" and "Expected '{' after 'if' condition"

The title summarized my problem. I'm new to coding and I don't understand how to solve the problem.
I've tried pretty much all I know.
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
#IBOutlet weak var PowerLVLlabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func randomNumber(_ sender: Any) {
let randomNumber = Int.random(in: 1000...10000)
PowerLVLlabel.text = String(randomNumber)
if case { randomNumber; >=9000 == (true);
func playVideo() {
guard let path = Bundle.main.path(forResource: "over 9000", ofType:"mp4") else {
debugPrint("over 9000.mp4 not found")
return
}
{let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
present(playerController, animated: true) }
{player.play()
}
try this:
func playVideo(){
guard let path = Bundle.main.path(forResource: "over 9000", ofType:"mp4") else {
debugPrint("over 9000.mp4 not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
present(playerController, animated: true)
player.play()
}
#IBAction func randomNumber(_ sender: Any) {
let randomNumber = Int.random(in: 1000...10000)
PowerLVLlabel.text = String(randomNumber)
if randomNumber >= 9000{
playVideo()
}
}
You need to get playVideo function out of randomNumber and remove some un needed ; and {}
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet weak var powerLVLlabel: UILabel!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func playVideo() {
guard let path = Bundle.main.path(forResource: "over 9000", ofType:"mp4") else {
debugPrint("over 9000.mp4 not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
present(playerController, animated: true)
player.play()
}
#IBAction func randomNumber(_ sender: Any) {
let randomNumber = Int.random(in: 1000...10000)
powerLVLlabel.text = String(randomNumber)
if randomNumber >= 9000 {
playVideo()
}
}
}

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

How to make a function play different sounds in Swift

I have 10 different buttons and each button has a unique tag associated with it. All buttons are linked to the same IBAction. I have the function to play different different sounds according to the tag associated with the particular button that is clicked.
import AVFoundation
var myAudio: AVAudioPlayer!
let path = Bundle.main.path(forResource: "sound1", ofType: "wav")!
let url = URL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOf: url)
myAudio = sound
sound.play()
} catch {
//
}
}
do like
#objc func yourbtnActionName(_ sender : UIButton){
switch sender.tag {
case 1:
commonSoundCode(name: "sound1")
break
case 2:
commonSoundCode(name: "yoursecondSoundname")
break
default:
break
}
}
then common method as
func commonSoundCode(name: String){
let path = Bundle.main.path(forResource: name, ofType: "wav")!
let url = URL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOf: url)
myAudio = sound
sound.play()
} catch {
//
}
}
option 2
if your sound files are in the same sequence, for e.g (sound1.wav, sound2.wav......, sound10.wav) then call like
#objc func yourbtnActionName(_ sender : UIButton){
let path = Bundle.main.path(forResource: "sound\(sender.tag)", ofType: "wav")!
let url = URL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOf: url)
myAudio = sound
sound.play()
} catch {
//
}
}
You need to simply play sounds according to the UIButton's tag.
#IBAction func playsound(_ sender: UIButton)
{
switch sender.tag
{
case 0:
//Sound for Button with tag=0
case 1:
//Sound for Button with tag=1
default:
//Default Sound
}
}
In the above code, add more cases according to your UIButton tags.
Please add some more code for a bit more clarity around your question.
import UIKit
//Mark: Do import AVFoundation is must here!
import AVFoundation
class ViewController: UIViewController {
//Mark: Create variable for AVAudioEngine! and AVAudioplayermode!
var engine: AVAudioEngine!
var audioPlayerNode : AVAudioPlayerNode!
//Mark: Create Variable for each tone as AVAudiofile!
var Cs:AVAudioFile!
var Ds:AVAudioFile!
var Es:AVAudioFile!
var Fs:AVAudioFile!
var Gs:AVAudioFile!
var As:AVAudioFile!
var Bs:AVAudioFile!
override func viewDidLoad() {
super.viewDidLoad()
// Mark: Load engine
engine = AVAudioEngine()
// Mark : Mention each sound
Cs = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
Bundle.main.path(forResource: "C", ofType: "wav")!))
Ds = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
Bundle.main.path(forResource: "D", ofType: "wav")!))
Es = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
Bundle.main.path(forResource: "E", ofType: "wav")!))
Fs = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
Bundle.main.path(forResource: "F", ofType: "wav")!))
Gs = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
Bundle.main.path(forResource: "G", ofType: "wav")!))
As = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
Bundle.main.path(forResource: "A", ofType: "wav")!))
Bs = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
Bundle.main.path(forResource: "B", ofType: "wav")!))
}
//Mark: create function(playSound) for connect AVAudioEngine and AVAudioplayermode for playing audio when button clicked
func playSound(audioFile: AVAudioFile) {
audioPlayerNode = AVAudioPlayerNode()
if(audioPlayerNode.isPlaying){
audioPlayerNode.stop()
}
if(engine.isRunning){
engine.stop()
engine.reset()
}
engine.attach(audioPlayerNode)
engine.connect(audioPlayerNode, to: engine.mainMixerNode, format: audioFile.processingFormat)
audioPlayerNode.scheduleFile(audioFile, at: nil, completionHandler: nil)
// Start the audio engine
engine.prepare()
try! engine.start()
audioPlayerNode.play()
}
//Mark: create required button for actions to connect function(playSound) and mention each sound to button
#IBAction func btnC(_ sender: UIButton) {
playSound(audioFile: Cs)
}
#IBAction func btnD(_ sender: UIButton) {
playSound(audioFile: Ds)
}
#IBAction func btnE(_ sender: UIButton) {
playSound(audioFile: Es)
}
#IBAction func btnF(_ sender: UIButton) {
playSound(audioFile: Fs)
}
#IBAction func btnG(_ sender: UIButton) {
playSound(audioFile: Gs)
}
#IBAction func btnA(_ sender: UIButton) {
playSound(audioFile: As)
}
#IBAction func btnB(_ sender: UIButton) {
playSound(audioFile: Bs)
}
}