Mit AVAudioPlayer einen Sound abspielen

73

Ich versuche einen Sound zu spielen, AVAudioPlayeraber es wird nicht funktionieren.

Edit 1: Funktioniert immer noch nicht.

Edit 2 : Dieser Code funktioniert. Mein Gerät war im lautlosen Modus.

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)

        var error:NSError?
        audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }
}
user3722523
quelle
2
Anstatt " nil" an den Fehlerparameter zu übergeben, geben Sie doch etwas ein und finden Sie heraus, was der Fehler tatsächlich ist.
Michael Dautermann
Der Fehler enthält nil
user3722523
Ich verwende praktisch genau den gleichen Code wie Sie für eine Osx-Anwendung, und alles funktioniert, bis auf den Fehlercode, der selbst einen Fehler auslöst: "Schwerwiegender Fehler: Beim Auspacken eines optionalen Werts unerwartet Null gefunden" Ich glaube, dass mit der Fehlererklärung etwas nicht stimmt. Ich weiß nicht viel über Fehler in Swift, aber ist das etwas, auf das Sie schon einmal gestoßen sind?
Uzebeckatrente
@Uzebeckatrente - Überprüfen Sie, ob Sie NSURL nicht verwenden (Zeichenfolge: ...). Dies gibt unter bestimmten Umständen aus irgendeinem Grund null zurück. Sie sollten NSURL (fileURLWithPath: ...) für Dateispeicherorte verwenden.
DJB
9
hahaha ... ein großes Lob für den Silent-Modus!
animal_chin

Antworten:

63

Ihr Code wurde geändert:

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

}

Swift 3 und Swift 4.1:

import UIKit
import AVFoundation

class ViewController: UIViewController {
    private var audioPlayer: AVAudioPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()

        let alertSound = URL(fileURLWithPath: Bundle.main.path(forResource: "button-09", ofType: "wav")!)
        print(alertSound)

        try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try! AVAudioSession.sharedInstance().setActive(true)

        try! audioPlayer = AVAudioPlayer(contentsOf: alertSound)
        audioPlayer!.prepareToPlay()
        audioPlayer!.play()
    }
}
vladof81
quelle
1
Hallo, ich versuche, meinem Programm mit ungefähr demselben Code Sound hinzuzufügen, und es stürzt ab. Wo genau legst du die Audiodatei ab? Im Assets-Ordner oder ..?
Skyguy
2
@skyguy, Sie können die Sounddatei in Ihr Projekt ziehen und das richtige Ziel zum Hinzufügen auswählen.
Vladof81
Irgendwelche Ideen, wie man es für pls oder Remote-MP3-Dateien verwendet?
Danielsalare
1
"Der AVplayer bietet keine Unterstützung für Streaming, Sie können mit AVPlayer stackoverflow.com/questions/3635792/…
houguet pierre
1
Muss ich AVAudioPlayerfür jede Sounddatei, die ich abspielen möchte, eine neue Instanz erstellen ?
Confile
36

Gemäß Swift 2 sollte der Code sein

var audioPlayer : AVAudioPlayer!

func playSound(soundName: String)
{
    let coinSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(soundName, ofType: "m4a")!)
    do{
        audioPlayer = try AVAudioPlayer(contentsOfURL:coinSound)
        audioPlayer.prepareToPlay()//there is also an async version
        audioPlayer.play()
    }catch {
        print("Error getting the audio file")
    }
}
Estevex
quelle
20
Sie sollten audioPlayer irgendwo zu einer Instanzvariablen machen. Dieser Code wird sofort nach dem Aufruf von .play () freigegeben, und Sie hören nichts.
Scrrr
Die App wird auch eine leichte Verzögerung erfahren, da sie die Datei laden und den Player auf einmal vorbereiten muss.
AppreciateIt
23

Ihre Audiowiedergabe wird direkt nach Abschluss von viewDidLoad freigegeben, da Sie sie einer lokalen Variablen zuweisen. Sie müssen eine Eigenschaft erstellen, damit sie erhalten bleibt.

rdelmar
quelle
1
@ Alexanders So geht's: stackoverflow.com/questions/24393495/…
Khaled Annajar
12

Die Lösung ist für AudioPlayer, der in der Navigationsleiste eine Wiedergabe- / Pause- / Stopp-Schaltfläche als Balkenschaltflächenelemente hat

In Swift 2.1 können Sie den folgenden Code verwenden

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var player:AVAudioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
            super.viewDidLoad()

            let audioPath = NSBundle.mainBundle().pathForResource("ARRehman", ofType: "mp3")
            var error:NSError? = nil
            do {
                player = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath!))
            }
            catch {
                print("Something bad happened. Try catching specific errors to narrow things down")
            }

        }

    @IBAction func play(sender: UIBarButtonItem) {
        player.play()

    }


    @IBAction func stop(sender: UIBarButtonItem) {
        player.stop()
        print(player.currentTime)
        player.currentTime = 0
    }


    @IBAction func pause(sender: UIBarButtonItem) {

        player.pause()
    }


    @IBOutlet weak var sliderval: UISlider!


    @IBAction func slidermov(sender: UISlider) {

        player.volume = sliderval.value
        print(player.volume)
    }

}
Naishta
quelle
7

Das wird funktionieren.....

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var ding:AVAudioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        prepareAudios()
        ding.play()
    }

    func prepareAudios() {

        var path = NSBundle.mainBundle().pathForResource("ding", ofType: "mp3")
        ding = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: path!), error: nil)
        ding.prepareToPlay()
    }
}
Chetan Prajapati
quelle
1
"Das wird funktionieren" Aber warum wird es funktionieren? Bitte erläutern Sie, was mit OP nicht stimmt und wie Sie es behoben haben, damit zukünftige Benutzer das dahinter stehende Konzept verstehen können.
Prudhvi
2

Verwenden Sie diese Funktion, um in Swift Ton zu erzeugen (Sie können diese Funktion dort verwenden, wo Sie Ton erzeugen möchten.)

Fügen Sie zuerst SpriteKit und AVFoundation Framework hinzu.

import SpriteKit
import AVFoundation
func playEffectSound(filename: String){
     runAction(SKAction.playSoundFileNamed("\(filename)", waitForCompletion: false))
}// use this function to play sound

playEffectSound("Sound File Name With Extension")
// Example :- playEffectSound("BS_SpiderWeb_CollectEgg_SFX.mp3")
Raksha
quelle
1
Dies mag "funktionieren", aber es
Ray
2

Dies ist eine ziemlich alte Frage, aber ich habe keine Antwort gesehen, die mit Swift 3.0 funktioniert hat. Deshalb habe ich den Code modernisiert und einige Sicherheitsüberprüfungen hinzugefügt, um Abstürze zu vermeiden.

Ich habe auch den Ansatz gewählt, die spielende Rolle in eine eigene Funktion zu ziehen, um die Wiederverwendung für alle zu erleichtern, die auf diese Antwort stoßen.

import UIKit
import AVFoundation

class ViewController: UIViewController {
    var audioPlayer: AVAudioPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()

        play(for: "button-09", type: "wav")
    }

    func play(for resource: String, type: String) {
        // Prevent a crash in the event that the resource or type is invalid
        guard let path = Bundle.main.path(forResource: resource, ofType: type) else { return }
        // Convert path to URL for audio player
        let sound = URL(fileURLWithPath: path)
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: sound)
            audioPlayer?.prepareToPlay()
            audioPlayer?.play()
        } catch {
            // Create an assertion crash in the event that the app fails to play the sound
            assert(false, error.localizedDescription)
        }
    }
}
CodeBender
quelle
Machen Sie AudioPlayer zu einer Instanzvariablen
Codierung22
2

Ab Swift 4.2 wurden die Setup-Optionen für die AudioSession-Kategorie geändert. (Versuchen Sie, den folgenden Code ab Swift 4.2 zu verwenden.)

import UIKit
import AVFoundation


class ViewController: UIViewController {


    var audioPlayer: AVAudioPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()
        prepareAudioSession()
    }


    func prepareAudioSession() -> Void {
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: AVAudioSession.CategoryOptions.defaultToSpeaker)
            try AVAudioSession.sharedInstance().setActive(true)

            prepareAudioPlayer()

        } catch {
            print("Issue with Audio Session")
        }
    }


    func prepareAudioPlayer() -> Void {

        let audioFileName = "test"
        let audioFileExtension = "mp3"

        guard let filePath = Bundle.main.path(forResource: audioFileName, ofType: audioFileExtension) else {
            print("Audio file not found at specified path")
            return
        }

        let alertSound = URL(fileURLWithPath: filePath)
        try? audioPlayer = AVAudioPlayer(contentsOf: alertSound)
        audioPlayer?.prepareToPlay()
    }


    func playAudioPlayer() -> Void {
        audioPlayer?.play()
    }


    func pauseAudioPlayer() -> Void {
        if audioPlayer?.isPlaying ?? false {
            audioPlayer?.pause()
        }
    }


    func stopAudioPlayer() -> Void {
        if audioPlayer?.isPlaying ?? false {
            audioPlayer?.stop()
        }
    }

    func resetAudioPlayer() -> Void {
        stopAudioPlayer()
        audioPlayer?.currentTime = 0
        playAudioPlayer()
    }

}
Krunal
quelle
Ich habe Fehler in der prepareAudioSession-Funktion ... haben Sie dieses Problem in iOS 12
konfrontiert