Schnelles Erstellen und Abspielen eines Sounds


103

Ich möchte also schnell einen Sound erstellen und abspielen, der abgespielt wird, wenn ich einen Knopf drücke. Ich weiß, wie es in Objective-C geht, aber weiß jemand, wie man es in Swift macht?

Für Objective-C wäre es so:

NSURL *soundURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"mysoundname" ofType:@"wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &mySound);

Und um es dann zu spielen, würde ich tun:

AudioServicesPlaySystemSound(Explosion);

Weiß jemand, wie ich das machen könnte?


2
Die Wurzel dieser Frage ist, wie man C-Funktionen von Swift aus aufruft. Darauf bin ich auch neugierig.
67cherries

Diese Zeile kann die Sound-URL erstellen: var url :NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("mysoundname", ofType: "wav"))
Connor

@connor Danke, das funktioniert, aber was ist mit AudioServicesCreateSystemSoundID
Jacob Banks

Da bin ich mir nicht sicher. Ich konnte die Objective-API nur schnell aufrufen.
Connor

Antworten:


83

Hier ist ein bisschen Code, den ich zu FlappySwift hinzugefügt habe und der funktioniert:

import SpriteKit
import AVFoundation

class GameScene: SKScene {

    // Grab the path, make sure to add it to your project!
    var coinSound = NSURL(fileURLWithPath: Bundle.main.path(forResource: "coin", ofType: "wav")!)
    var audioPlayer = AVAudioPlayer()

    // Initial setup
    override func didMoveToView(view: SKView) {
        audioPlayer = AVAudioPlayer(contentsOfURL: coinSound, error: nil)
        audioPlayer.prepareToPlay()
    }

    // Trigger the sound effect when the player grabs the coin
    func didBeginContact(contact: SKPhysicsContact!) {
        audioPlayer.play()
    }

}

Es scheint, Sie könnten audioPlayer direkt vor der Verwendung deklarieren, aber das hat bei mir im Simulator nicht funktioniert. Ich musste es oben deklarieren, genau wie du.
Adam Loving

@Adam Loving, Sie können audioPlayer direkt vor der Verwendung deklarieren, aber stellen Sie sicher, dass Sie play () in derselben Funktion aufrufen, in der Sie es deklariert haben (im Gegensatz zur guten Antwort). Außerdem würde ich deklarieren coinSoundund audioPlayermit letstatt, varda Sie dies nicht möchten Ändern Sie diese Objekte zu einem späteren Zeitpunkt.
Fat32

3
Denken Sie in Swift 2 daran, es so auszuführen, do { (player object) } catch _ { }da sonst ein Fehler auftritt! :)
ParisNakitaKejser

1
Aber Aufmerksamkeit! Hintergrundmusik vom Player wird angehalten. Um kurzen Sound zu spielen, müssen wir die Antwort unten verwenden
Nikita Pronchik

Downvote - dies ist kein System-Sound, es wird eine andere API verwendet
William Entriken

119

Dies ähnelt einigen anderen Antworten, ist aber vielleicht etwas "schneller":

// Load "mysoundname.wav"
if let soundURL = Bundle.main.url(forResource: "mysoundname", withExtension: "wav") {
    var mySound: SystemSoundID = 0
    AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
    // Play
    AudioServicesPlaySystemSound(mySound);
}

Beachten Sie, dass dies ein triviales Beispiel ist, das die Wirkung des Codes in der Frage reproduziert. Sie müssen sicherstellen import AudioToolbox, dass das allgemeine Muster für diese Art von Code darin besteht, Ihre Sounds beim Start Ihrer App zu laden, sie SystemSoundIDirgendwo in Instanzvariablen zu speichern , sie in Ihrer gesamten App zu verwenden und dann aufzurufen, AudioServicesDisposeSystemSoundIDwenn Sie fertig sind mit ihnen.


1
Sie müssen auch AudioToolbox
Brody Robertson

Müssen Sie AudioServicesDisposeSystemSoundID(mySound)später anrufen , um den Speicher freizugeben? Wenn du es sofort machst, wird der Sound im Grunde nicht abgespielt (wird sofort bereinigt), also habe ich es getan dispatch_afterund es 10 Sekunden später aufgeräumt.
Owenfi

@owenfi Das Codefragment in meiner Antwort ist nur das Swift-Äquivalent des Codefragments in der Frage. Das allgemeine Muster für AudioServices besteht darin, Ihre Sounds beim Starten Ihrer App zu laden, sie in der gesamten App zu verwenden und sie beim Schließen der App zu entsorgen. Jede App ist jedoch anders.
Matt Gibson

@ozgur Warum verwenden Sie eine veraltete Version von Xcode? Wir müssen wissen, was "nicht funktioniert" bedeutet, und Sie sollten wahrscheinlich eine neue Frage stellen, wenn Sie bestimmte Probleme haben.
Matt Gibson

Eigentlich ist dies die einzige Möglichkeit, eine WAV-Datei abzuspielen. AVPlayer scheint nicht zu funktionieren.
Haitao

18

Handliche Swift-Erweiterung:

import AudioToolbox

extension SystemSoundID {
    static func playFileNamed(fileName: String, withExtenstion fileExtension: String) {
        var sound: SystemSoundID = 0
        if let soundURL = NSBundle.mainBundle().URLForResource(fileName, withExtension: fileExtension) {
            AudioServicesCreateSystemSoundID(soundURL, &sound)
            AudioServicesPlaySystemSound(sound)
        }
    }
}

Dann können Sie von überall in Ihrer App (denken import AudioToolboxSie daran ) anrufen

SystemSoundID.playFileNamed("sound", withExtenstion: "mp3")

um "sound.mp3" zu spielen


Wenn ich dies in einem SpriteKit-Spiel ausführe, gibt es immer eine Verzögerung, bevor der Sound abgespielt wird. Auch wenn ich es hineingesteckt habe DispatchQueue.global(qos: .userInitiated).async {}.
Jon Kantner

NSBundlewurde ersetzt durch Bundle, Bundle.main.url(forResource: fileName, withExtension: fileExtension)stattdessen verwenden
diachedelisch

14

Dies erstellt eine SystemSoundIDaus einer Datei namens Cha-Ching.aiff.

import AudioToolbox

let chaChingSound: SystemSoundID = createChaChingSound()

class CashRegisterViewController: UIViewController {
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        AudioServicesPlaySystemSound(chaChingSound)
    }
}

func createChaChingSound() -> SystemSoundID {
    var soundID: SystemSoundID = 0
    let soundURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), "Cha-Ching", "aiff", nil)
    AudioServicesCreateSystemSoundID(soundURL, &soundID)
    CFRelease(soundURL)
    return soundID
}

Haben Sie versucht, den Code zu kompilieren? Ich erhalte die Fehlermeldung "Der Extressionstyp 'Nicht verwaltet <CFURL> kann nicht konvertiert werden!' Um 'CFString' "aus dieser Zeile" einzugeben, lassen Sie soundURL = CFBundleCopyResourceURL (CFBundleGetMainBundle (), "Cha-Ching", "aiff", nil) "
bpolat


2
Dies sollte die akzeptierte Antwort sein, da das bereitgestellte Obj-C-Beispiel auf dem AudioToolBox Framework basiert
eharo2

@JochenBedersdorfer, wahrscheinlich wird ein Fehler angezeigt, weil Core Foundation-Objekte automatisch speicherverwaltet werden.
XCool

8

Mit einer Klasse & AudioToolbox:

import AudioToolbox

class Sound {

    var soundEffect: SystemSoundID = 0
    init(name: String, type: String) {
        let path  = NSBundle.mainBundle().pathForResource(name, ofType: type)!
        let pathURL = NSURL(fileURLWithPath: path)
        AudioServicesCreateSystemSoundID(pathURL as CFURLRef, &soundEffect)
    }

    func play() {
        AudioServicesPlaySystemSound(soundEffect)
    }
}

Verwendung:

testSound = Sound(name: "test", type: "caf")
testSound.play()

2
Ich liebe diese Antwort. Auch weil es der System-Sound ist, bekomme ich keine Systemmeldung, die der AVAudioPlayer in die Konsole für Xcode 8 wirft.
TPot

Bitte helfen Sie mir, das Gleiche zu tun. Der Ton wird abgespielt, aber die Lautstärke ist zu niedrig. kann nicht hören
veeresh kumbar

5
import AVFoundation

var audioPlayer = AVAudioPlayer()

class GameScene: SKScene {

    override func didMoveToView(view: SKView) {

        let soundURL = NSBundle.mainBundle().URLForResource("04", withExtension: "mp3")
        audioPlayer = AVAudioPlayer(contentsOfURL: soundURL, error: nil)
        audioPlayer.play()
    }
}

Es ist AVAudioPlayer (Inhalt von: soundURL) in der modernen Swift
Box

5

Dieser Code funktioniert für mich. Verwenden Sie Try and Catch für AVAudioPlayer

import UIKit
import AVFoundation
class ViewController: UIViewController {

    //Make sure that sound file is present in your Project.
    var CatSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Meow-sounds.mp3", ofType: "mp3")!)
    var audioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        do {

            audioPlayer = try AVAudioPlayer(contentsOfURL: CatSound)
            audioPlayer.prepareToPlay()

        } catch {

            print("Problem in getting File")

        }      
        // 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.
    }

    @IBAction func button1Action(sender: AnyObject) {

        audioPlayer.play()
    }
}

4
var mySound = NSSound(named:"Morse.aiff")
mySound.play()

"Morse.aiff" ist ein System-Sound von OSX. Wenn Sie jedoch in XCode einfach auf "named" klicken, können Sie (im QuickHelp-Bereich) anzeigen, wo diese Funktion die Sounds durchsucht. Es kann sich in Ihrem Ordner "Unterstützende Dateien" befinden


4
Die Frage betrifft iOS.
rmaddy

In der Tat ... Konnte es nicht im Simulator schaffen. Bisher kein Dokument verfügbar
philippe

4

Laut dem neuen Swift 2.0 sollten wir do try catch verwenden. Der Code würde folgendermaßen aussehen:

var badumSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("BadumTss", ofType: "mp3"))
var audioPlayer = AVAudioPlayer()
 do {
     player = try AVAudioPlayer(contentsOfURL: badumSound)
 } catch {
     print("No sound found by URL:\(badumSound)")
 }
 player.prepareToPlay()

3

Dies funktioniert mit Swift 4:

if let soundURL = Bundle.main.url(forResource: "note3", withExtension: "wav") {
                var mySound: SystemSoundID = 0
                AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
                // Play
                AudioServicesPlaySystemSound(mySound);
            }

2
Bitte erläutern Sie Ihren Code. Nur-Code-Antworten sind weniger wertvoll als Erklärungen.
Vincent

@ Vincent +1, eigentlich frage ich mich & Betreiber. Dies kann zwischen Ton und Speicher referenziert werden.
Elia

Sie müssen Import AudioToolbox hinzufügen und dann den obigen Code hinzufügen
Mohammad Aboelnasr

2
//Swift 4
import UIKit
import AVFoundation

class ViewController: UIViewController {

    var player : AVAudioPlayer?

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

    @IBAction func notePressed(_ sender: UIButton) {
        let path = Bundle.main.path(forResource: "note1", ofType: "wav")!
        let url = URL(fileURLWithPath: path)
        do {
            player = try AVAudioPlayer(contentsOf: url)
            player?.play()
        } catch {
            // error message
        }
    }
}

2

Lassen Sie uns einen aktuelleren Ansatz für diese Frage sehen:

Import AudioToolbox

func noteSelector(noteNumber: String) {

    if let soundURL = Bundle.main.url(forResource: noteNumber, withExtension: "wav") {
        var mySound: SystemSoundID = 0
        AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
        AudioServicesPlaySystemSound(mySound)
}

1
Der Code funktioniert gut auf Swift 4, aber anscheinend folgt der ausgestrahlte Ton nicht der Medienlautstärke
David Vargas

1

Die Lösung von Matt Gibson hat bei mir funktioniert, hier ist die Swift 3-Version.

if let soundURL = Bundle.main.url(forResource: "ringSound", withExtension: "aiff") {
  var mySound: SystemSoundID = 0
  AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
  AudioServicesPlaySystemSound(mySound);
}

1

Swift 4

import UIKit
import AudioToolbox

class ViewController: UIViewController{

var sounds : [SystemSoundID] = [1, 2, 3, 4, 5, 6, 7]

override func viewDidLoad() {
    super.viewDidLoad()

    for index in 0...sounds.count-1 {
        let fileName : String = "note\(sounds[index])"

        if let soundURL = Bundle.main.url(forResource: fileName, withExtension: "wav") {
            AudioServicesCreateSystemSoundID(soundURL as CFURL, &sounds[index])
        }
    }
}



@IBAction func notePressed(_ sender: UIButton) {
    switch sender.tag {
    case 1:
        AudioServicesPlaySystemSound(sounds[0])
    case 2:
        AudioServicesPlaySystemSound(sounds[1])
    case 3:
        AudioServicesPlaySystemSound(sounds[2])
    case 4:
        AudioServicesPlaySystemSound(sounds[3])
    case 5:
        AudioServicesPlaySystemSound(sounds[4])
    case 6:
        AudioServicesPlaySystemSound(sounds[5])
    default:
        AudioServicesPlaySystemSound(sounds[6])
    }
}
}

oder

import UIKit
import AVFoundation

class ViewController: UIViewController, AVAudioPlayerDelegate{

var audioPlayer : AVAudioPlayer!

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

@IBAction func notePressed(_ sender: UIButton) {

    let soundURL = Bundle.main.url(forResource: "note\(sender.tag)", withExtension: "wav")

    do {
        audioPlayer = try AVAudioPlayer(contentsOf: soundURL!)
    }
    catch {
        print(error)
    }

    audioPlayer.play()

}
}

1

arbeitet in Xcode 9.2

if let soundURL = Bundle.main.url(forResource: "note1", withExtension: "wav") {
   var mySound: SystemSoundID = 0
   AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
   // Play
    AudioServicesPlaySystemSound(mySound);
 }

1

Schnelles Codebeispiel :

import UIKit
import AudioToolbox

class ViewController: UIViewController {  

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

@IBAction func notePressed(_ sender: UIButton) {

    // Load "mysoundname.wav"

    if let soundURL = Bundle.main.url(forResource: "note1", withExtension: "wav") {
        var mySound: SystemSoundID = 0
        AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
    // Play

        AudioServicesPlaySystemSound(mySound);
    }
}

Bitte fügen Sie weitere Details hinzu, warum dieser Code hilfreich ist.
Berendschot

1

Sie können dies in Swift 5.2 versuchen:

func playSound() {
        let soundURL = Bundle.main.url(forResource: selectedSoundFileName, withExtension: "wav")
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: soundURL!)
        }
        catch {
            print(error)
        }
        audioPlayer.play()
    }

1

Swift 4 & iOS 12

var audioPlayer: AVAudioPlayer?

override func viewDidLoad() {
    super.viewDidLoad()



}

@IBAction func notePressed(_ sender: UIButton) {

    // noise while pressing button

    _ = Bundle.main.path(forResource: "note1", ofType: "wav")

    if Bundle.main.path(forResource: "note1", ofType: "wav") != nil {
        print("Continue processing")
    } else {
        print("Error: No file with specified name exists")
    }

    do {
        if let fileURL = Bundle.main.path(forResource: "note1", ofType: "wav") {
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: fileURL))
        } else {
            print("No file with specified name exists")
        }
    } catch let error {
        print("Can't play the audio file failed with an error \(error.localizedDescription)")
    }


    audioPlayer?.play()    }

}}


Postleitzahl nicht nur - erklären Sie, was es tut! stackoverflow.com/help/how-to-answer
Nino Filiu

Bitte beziehen Sie sich auf die Frage dieses Beitrags. Sie können Ihre Antwort finden! danke @NinoFiliu
Gulsan Borbhuiya

0

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

0

Dieser Code funktioniert für mich:

class ViewController: UIViewController {

    var audioFilePathURL : NSURL!
    var soundSystemServicesId : SystemSoundID = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        audioFilePathURL = NSBundle.mainBundle().URLForResource("MetalBell", withExtension: "wav")

        AudioServicesCreateSystemSoundID( audioFilePathURL, &soundSystemServicesId)


    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.


    }


    @IBAction func PlayAlertSound(sender: UIButton) {

         AudioServicesPlayAlertSound(soundSystemServicesId)
    }
}

0

Für Swift 3 :

extension SystemSoundID {
    static func playFileNamed(_ fileName: String, withExtenstion fileExtension: String) {
        var sound: SystemSoundID = 0
        if let soundURL = Bundle.main.url(forResource: fileName, withExtension: fileExtension) {
            AudioServicesCreateSystemSoundID(soundURL as CFURL, &sound)
            AudioServicesPlaySystemSound(sound)
        }
    }
}

0

Swift 3 hier ist, wie ich es mache.

{

import UIKit
import AVFoundation

        let url = Bundle.main.url(forResource: "yoursoundname", withExtension: "wav")!
        do {

            player = try AVAudioPlayer(contentsOf: url); guard let player = player else { return }

            player.prepareToPlay()
            player.play()
        } catch let error as Error {
            print(error)

        }
    }

0

Könnten Sie nicht einfach import AVFoundationden Audio-Player ( var audioPlayer : AVAudioPlayer!) auswählen und den Sound abspielen? ( let soundURL = Bundle.main.url(forResource: "sound", withExtension: "wav")


0
import UIKit
import AudioToolbox

class ViewController: UIViewController {

    let toneSound : Array =  ["note1","note2","note3","note4","note5","note6"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

    }

    func playSound(theTone : String) {
        if let soundURL = Bundle.main.url(forResource: theTone, withExtension: "wav") {
            var mySound: SystemSoundID = 0
            do {
                AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
                // Play
                AudioServicesPlaySystemSound(mySound);
            }
            catch {
               print(error)
            }
        }
    }

    @IBAction func anypressed(_ sender: UIButton) {
        playSound(theTone: toneSound[sender.tag-1] )
    }    

}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.