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?

Jacob Banks
quelle
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()
    }

}
Bauerpauer
quelle
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.

Matt Gibson
quelle
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

Aleix Pinardell
quelle
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
}
ma11hew28
quelle
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
Ja, es kompiliert für mich. Siehe github.com/acani/Chats/blob/master/Chats/Chats/…
ma11hew28
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()
karimhossenbux
quelle
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()
    }
}
Michael N.
quelle
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()
    }
}
Sachin Dobariya
quelle
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

philippe
quelle
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()
Roman Safin
quelle
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);
            }
Mohammad Aboelnasr
quelle
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
        }
    }
}
Soma Sharma
quelle
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)
}
Adam Eberbach
quelle
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);
}
Pavle Mijatovic
quelle
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()

}
}

quelle
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);
 }
Ray Sawyer
quelle
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);
    }
}
Pawel
quelle
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()
    }
Xab Ion
quelle
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()    }

}}

Gulsan Borbhuiya
quelle
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")
Rex
quelle
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)
    }
}
Jeeva
quelle
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)
        }
    }
}
Er Yifei 何 一 非
quelle
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)

        }
    }

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

BoeingLikesToDab
quelle
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] )
    }    

}
IslamNazir
quelle