I'm getting an error in the line of var filePathUrl. The error code is "Value of optional type 'String?' not unwrapped: did you mean to use '!' or '?'?'". How can I fix this error?
import UIKit
import AVFoundation
class PlayMusicViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var daten = NSBundle.mainBundle().pathForResource("Kool_Savas_Auge", ofType: "mp3")
var filePathUrl = NSURL.fileURLWithPath(daten)
var audioPlayer = AVAudioPlayer(contentsOfURL: filePathUrl, fileTypeHint: nil)
}
#IBAction func PlayMusic(sender: UIButton) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
try with
var filePathUrl = NSURL.fileURLWithPath(daten!)
Could you please tell me what I did wrong?
an exclamation mark (!) after an optional value to force the unwrapping of its value . please check this one
Swift 2: !, ? -" Value of optional type "..." not unwrapped"
UPDATE :
for example :
var daten = NSBundle.mainBundle().pathForResource("Kool_Savas_Auge", ofType: "mp3")
var filePathUrl = NSURL.fileURLWithPath(daten!)
do{
var audioPlayer = try AVAudioPlayer(contentsOfURL: filePathUrl, fileTypeHint: nil)
audioPlayer.prepareToPlay()
audioPlayer.play()
}
catch let err as NSError{
print(err.debugDescription);
}
Related
I'm trying to add some audio when a button is pressed and the code I use doesnt have any error until I run then I get the 'fatal error: unexpectedly found nil while unwrapping an Optional value' in the out put this line of code:
let url = Bundle.main.url(forResource:sound, withExtension: "mp3")!
This is my entire code just for reference:
import UIKit
import AVFoundation
class ViewController: UIViewController {
let soundFilenames = ["60gs", "check", "dada", "danceforme", "eat", "gods", "irelandbaby", "ko'd", "lefthand", "littlewerp", "nocalls", "precision", "sundaymorning", "surprise", "whothefuckisthatguy", "youlldonothing"]
var audioPlayers = [AVAudioPlayer]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
for sound in soundFilenames {
do {
let url = Bundle.main.url(forResource:sound, withExtension: "mp3")!
let audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayers.append(audioPlayer)
}
catch {
audioPlayers.append(AVAudioPlayer())
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func buttonTapped(_ sender: UIButton) {
let audioPlayer = audioPlayers[sender.tag]
audioPlayer.play()
}
}
Error is self-describing: url(forResource: withExtension:) returned nil and force-unwrapping it with ! causes your crash.
To fix this crash re-check that:
all files were added to the project
file names are written right in the code
If the file names are not needed later there is a more reliable way to get all mp3 files in the resources folder
let audioURLs = Bundle.main.urls(forResourcesWithExtension: "mp3", subdirectory: nil)!
for url in audioURLs {
do {
let audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayers.append(audioPlayer)
}
catch {
audioPlayers.append(AVAudioPlayer())
}
}
or - inspired by Alexander's comment – shortly
let audioURLs = Bundle.main.urls(forResourcesWithExtension: "mp3", subdirectory: nil)!
audioPlayers = audioURLs.flatMap{ try? AVAudioPlayer(contentsOf: $0) }
I've recently gotten into iOS development on my own and am building my first app: a Donald Trump soundboard. However, I got an error saying:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
This is the viewcontroller text:
import UIKit
import iAd
import AVFoundation
class SecondViewController: UIViewController {
// Array of every sound file
let soundFilenames = ["china", "drugs_killers_rapists", "america_great_again", "are_you_gay", "Mexico", "i_just_want_them_to_suffer", "are_you_homosexual", "are_you_surprised", "hes_a_loser", "isis_trump", "fantastic", "the_american_dream_is_dead", "wait_dummies", "special_guy", "I'm_really_rich", "speak_english", "so_probably_i'll_sue_her", "ladies", "ill_build_a_wall", "political_bullshit", "ima_bomb_em", "back_to_univision", "hes_a_pussy", "piece_of_garbage", "i_love_mexicans", "i_love_china", "i_love_saudis", "sit_down", "small_loan", "youre_fired", "lets_see_what_happens", "enough", "congratulations", "why", "are_you_anti_semite", "youre_the_boss", "1mm", "tell_it_like_it_is", "100b", "is_that_right", "hes_insecure", "beaten_up", "I_beat_China_all_the_time", "nonono", "ive_been_watching_you", "motivate_you", "okay_okay", "meatloaf"]
// Array of AudioPlayers for each file
var audioPlayers = [AVAudioPlayer]()
// Outlet for the ScrollView
#IBOutlet weak var ScrollView: UIScrollView!
var bannerView: ADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Set up scroll view to hold 48 buttons
ScrollView.contentSize.height = 1900
//Set up audio players
for sound in soundFilenames {
do {
// Try to do something
//THIS NEXT LINE IS WHERE THE BREAKPOINT
let url = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(sound, ofType: "mp3")!)
let audioPlayer = try AVAudioPlayer(contentsOfURL: url)
audioPlayers.append(audioPlayer)
}
catch {
// Catch the error that is thrown
audioPlayers.append(AVAudioPlayer())
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func buttonTapped(sender: UIButton) {
// Get the audioPlayer that corresponds to the tapped button
let audioPlayer = audioPlayers[sender.tag]
audioPlayer.play()
}
}
Any help will be extremely appreciated.
Edit: fatal error shown at the bottom states:
unexpectedly found nil while unwrapping an Optional value
//Set up audio players
for sound in soundFilenames {
do {
// Try to do something
if let pathOfResource = NSBundle.mainBundle().pathForResource(sound, ofType: "mp3") {
let url = NSURL(fileURLWithPath: pathOfResource)
let audioPlayer = try AVAudioPlayer(contentsOfURL: url)
audioPlayers.append(audioPlayer)
}
}
catch {
// Catch the error that is thrown
audioPlayers.append(AVAudioPlayer())
}
}
Try this updated code.
I am trying to pass button label to the filename of my multimedia.
Unfortunately it's not working.
Idea is when I press button named "cat" it will play filename named "cat", "mp3"
If I press button with label "cow" it will play sound with filename "cow".
So I tried already different variant's but I can't make it work. If you guys have some ideas, please help.
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
}
func playAudio() {
do {
self.audioPlayer = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("buttonName", ofType: "mp3")!))
self.audioPlayer.play()
} catch {
print("Error")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func playSound(sender: AnyObject) {
let buttonName = sender.currentTitle!
playAudio()
}
}
I'm no expert in Swift, but I don't think that dope LLVM can fix these for you:
You initialized buttonName as local variable, and you didn't pass it to playAudio() (which does not accept parameters anyways), it's 100% not working to me.
Since you didn't pass the local buttonName to playAudio() as a parameter, you can't get the button name within the function scope. Also, you use "buttonName", which is a String object, not even a variable. There's no file called buttonName.mp3 in your bundle, so nothing would happen (will always print("Error")).
Something like this should work: (Not tested, but should be similer)
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
}
func playAudio(buttonName: String!) {
do {
self.audioPlayer = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(buttonName, ofType: "mp3")!))
self.audioPlayer.play()
} catch {
print("Error")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func playSound(sender: AnyObject) {
let buttonName = sender.currentTitle!
playAudio(buttonName)
}
}
The .pathForResource(:String?,: String?) method of NSBundle does not take a selector, but a String. Hence, in your case, you will always try to open "buttonName.mp3", rather than the contents of some property called buttonName. Moreover, playSound in your function playSound(..) lives only locally in the scope of that function; and since you do not pass its value to playAudio(), the latter does now know of it. Finally, the sender for #IBAction is an UIButton, you're better of actually using type UIButton rather than AnyObject.
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
}
func playAudio(buttonName: String) {
do {
self.audioPlayer = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(buttonName, ofType: "mp3") ?? ""))
self.audioPlayer.play()
} catch {
print("Error")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func playSound(sender: UIButton) {
if let buttonName = sender.currentTitle {
playAudio(buttonName)
}
}
}
Notice that you should avoid using forced unwrapping of optionals (!) unless you know specifically that they will not be nil; I've used optional binding instead in the example above (if let ... in playSound(...).
Lately I have run into an issue while using the beta version of Xcode (7.0).
I am not able to hear the sound that I play through this code:
(It is a ViewController from the Main.storyboard, there is a button connected to buttonTouchUpInside())
import UIKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
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("NO AUDIO PLAYER")
}
return audioPlayer!
}
#IBAction func buttonTouchUpInside(sender: AnyObject) {
let backMusic = setupAudioPlayerWithFile("sound", type: "wav")
backMusic.play()
}
}
You just have to move the declaration of backMusic out of your IBAction:
Try like this:
class ViewController: UIViewController {
var backMusic: AVAudioPlayer!
// ...
#IBAction func buttonTouchUpInside(sender: AnyObject) {
backMusic = setupAudioPlayerWithFile("sound", type: "wav")
backMusic.play()
}
}
I am trying to record Audio, and pass the recorded audio, to the next view controller. Here is my code for recording Audio
class RecordSoundsViewController: UIViewController, AVAudioRecorderDelegate {
#IBOutlet weak var recording: UILabel!
#IBOutlet weak var recordButton: UIButton!
#IBOutlet weak var stopButton: UIButton!
var audioRecorder:AVAudioRecorder!
var recordedAudio : RecordedAudio!
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.
}
override func viewWillAppear(animated: Bool) {
// enables record button
// hides the stop button
recordButton.enabled = true
stopButton.hidden = true
}
#IBAction func recordAudio(sender: UIButton) {
//Shows recording label
recording.hidden = false
//diabling record button
recordButton.enabled = false
stopButton.hidden = false
//Filepath Creation
let dirPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String
let currentDateTime = NSDate()
let formatter = NSDateFormatter()
formatter.dateFormat = "ddMMyyyy-HHmmss"
let recordingName = formatter.stringFromDate(currentDateTime)+".wav"
let pathArray = [dirPath, recordingName]
let filePath = NSURL.fileURLWithPathComponents(pathArray)
println(filePath)
// Recording Session
var session = AVAudioSession.sharedInstance()
session.setCategory(AVAudioSessionCategoryPlayAndRecord, error: nil)
audioRecorder = AVAudioRecorder(URL: filePath, settings: nil, error: nil)
audioRecorder.delegate = self
audioRecorder.meteringEnabled = true
audioRecorder.prepareToRecord()
audioRecorder.record()
}
func audioRecorderDidFinishRecording(recorder: AVAudioRecorder!, successfully flag: Bool) {
// ToDo create recorded audio file
if(flag)
{ recordedAudio = RecordedAudio()
recordedAudio.filepathURL = recorder.url
recordedAudio.title = recorder.url.lastPathComponent
// ToDo Perform segue
self.performSegueWithIdentifier("stopRecording", sender: recordedAudio)
}
else {
println("Recording was unsuccessfull")
stopButton.hidden = true
recordButton.enabled = true
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue == "stopRecording") {
let PlaySoundsVC:PlaySoundsViewController = segue.destinationViewController as! PlaySoundsViewController
let data = sender as! RecordedAudio
PlaySoundsVC.receivedAudio = data
}
}
#IBAction func stopAudio(sender: UIButton) {
// Hides recording
recording.hidden = true
audioRecorder.stop()
var audioSession = AVAudioSession.sharedInstance()
audioSession.setActive(false, error: nil)
}
}
My Model class is ,
import Foundation
class RecordedAudio : NSObject{
var filepathURL :NSURL!
var title : String!
}
Here is how My second viewcontroller catch the data and uses it,
class PlaySoundsViewController: UIViewController {
var audioPlayer: AVAudioPlayer!
var receivedAudio: RecordedAudio!
func rateplay (rtt : Float32) {
audioPlayer.stop()
audioPlayer.rate = rtt
audioPlayer.currentTime = 0.0
audioPlayer.play()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// if var filePath = NSBundle.mainBundle().pathForResource("movie_quote", ofType: "mp3")
// {
// // if path is there for mp3
// let filepathurl = NSURL.fileURLWithPath(filePath)
//
// // println(receivedAudio.title)
//
// }
// else {
// println("Path is empty")
//
// }
audioPlayer = AVAudioPlayer(contentsOfURL: receivedAudio.filepathURL, error: nil)
audioPlayer.enableRate = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func playSlow(sender: UIButton) {
// play sloooowllyyyyy
audioPlayer.stop()
audioPlayer.rate = 0.5
audioPlayer.currentTime = 0.0
audioPlayer.play()
}
#IBAction func playFast(sender: UIButton) {
rateplay(1.5)
}
#IBAction func stopAudio(sender: UIButton) {
audioPlayer.stop()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Untill I add the below code,
audioPlayer = AVAudioPlayer(contentsOfURL: receivedAudio.filepathURL, error: nil)
audioPlayer.enableRate = true
I was able to move to the second scene, which means, the audio is successfully recorded. But as soon as i access the data like "receivedAudio.filepathURL" I am getting the error,
fatal error: unexpectedly found nil while unwrapping an Optional value
In the prepareForSegue function of the RecordSoundsViewController you need to write segue.identifier == "stopRecording" as the condition.
Currently you have segue == "stopRecording".
Happy Coding!