Membuat dan memutar suara dengan cepat

103

Jadi yang ingin saya lakukan adalah membuat dan memutar suara dengan cepat yang akan diputar saat saya menekan tombol, saya tahu cara melakukannya di Objective-C, tetapi adakah yang tahu cara melakukannya di Swift?

Ini akan menjadi seperti ini untuk Objective-C:

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

Dan kemudian untuk memainkannya, saya akan melakukan:

AudioServicesPlaySystemSound(Explosion);

Adakah yang tahu bagaimana saya bisa melakukan ini?

Jacob Banks
sumber
2
Akar dari pertanyaan ini adalah bagaimana memanggil fungsi C dari swift. Saya juga penasaran tentang ini.
67cherries
baris ini dapat membuat url suara: var url :NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("mysoundname", ofType: "wav"))
Connor
@connor Terima kasih itu berfungsi, tetapi bagaimana dengan AudioServicesCreateSystemSoundID
Jacob Banks
Saya tidak yakin tentang itu. Saya hanya bisa memanggil api objektif-c dari swift.
Connor

Jawaban:

83

Ini sedikit kode yang saya tambahkan ke FlappySwift yang berfungsi:

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
sumber
Tampaknya Anda bisa langsung mendeklarasikan audioPlayer sebelum menggunakannya, tetapi itu tidak berhasil untuk saya di simulator. Saya harus mengumumkannya di atas seperti yang Anda lakukan.
Adam Loving
@Adam Loving Anda dapat mendeklarasikan audioPlayer tepat sebelum menggunakannya, tetapi pastikan Anda memanggil play () dalam fungsi yang sama dengan yang Anda nyatakan (berlawanan dengan jawaban yang baik). Selanjutnya, saya akan mendeklarasikan coinSounddan audioPlayerdengan letalih - alih varkarena Anda tidak mau ubah objek ini di lain waktu.
fat32
3
Di Swift 2, ingatlah untuk menjalankannya dengan cara ini do { (player object) } catch _ { }atau Anda akan terkena bug! :)
ParisNakitaKejser
1
Tapi perhatian! Ini akan menghentikan musik latar dari pemutar. Untuk memainkan suara pendek kita harus menggunakan jawaban di bawah ini
Nikita Pronchik
Suara negatif - ini bukan suara sistem, ini menggunakan api yang berbeda
William Entriken
119

Ini mirip dengan beberapa jawaban lain, tetapi mungkin sedikit lebih "Swifty":

// 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);
}

Perhatikan bahwa ini adalah contoh sepele yang mereproduksi efek kode dalam pertanyaan. Anda harus memastikannya import AudioToolbox, ditambah pola umum untuk jenis kode ini adalah memuat suara Anda saat aplikasi Anda mulai, menyimpannya dalam SystemSoundIDvariabel instance di suatu tempat, menggunakannya di seluruh aplikasi Anda, lalu memanggilnya AudioServicesDisposeSystemSoundIDsetelah Anda selesai dengan mereka.

Matt Gibson
sumber
1
Anda juga perlu mengimpor AudioToolbox
Brody Robertson
Apakah Anda perlu menelepon AudioServicesDisposeSystemSoundID(mySound)untuk mengosongkan memori nanti? jika Anda melakukannya segera, suara pada dasarnya tidak diputar (dibersihkan secara instan) jadi saya melakukannya dispatch_afterdan membersihkannya 10 detik kemudian.
owenfi
@owenfi Fragmen kode dalam jawaban saya hanyalah padanan Swift dari fragmen kode dalam pertanyaan. Pola umum AudioServices adalah memuat suara Anda saat aplikasi diaktifkan, menggunakannya di seluruh aplikasi, dan membuangnya saat aplikasi ditutup, tetapi setiap aplikasi akan berbeda.
Matt Gibson
@ Ozgur Mengapa Anda menggunakan versi Xcode yang sudah kadaluwarsa? Kami perlu mengetahui apa artinya "tidak berfungsi", dan Anda mungkin lebih baik mengajukan pertanyaan baru jika Anda memiliki masalah tertentu.
Matt Gibson
sebenarnya ini adalah satu-satunya cara untuk memutar file wav. AVPlayer sepertinya tidak berfungsi.
Haitao
18

Ekstensi Swift yang berguna:

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

Kemudian, dari mana saja di aplikasi Anda (ingat untuk import AudioToolbox), Anda dapat menelepon

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

untuk memutar "sound.mp3"

Aleix Pinardell
sumber
Saat saya menjalankan ini dalam game SpriteKit, selalu ada jeda sebelum suara dimainkan. Bahkan jika saya memasukkannya ke dalam DispatchQueue.global(qos: .userInitiated).async {}.
Jon Kantner
NSBundletelah diganti oleh Bundle, gunakan Bundle.main.url(forResource: fileName, withExtension: fileExtension)sebagai gantinya
diachedelic
14

Ini membuat SystemSoundIDdari file bernama 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
sumber
Apakah Anda mencoba mengompilasi kode? Saya mendapatkan pesan kesalahan "Tidak dapat mengonversi jenis ekstensi 'Tidak Dikelola <CFURL>!' untuk mengetik 'CFString' "dari baris ini" let soundURL = CFBundleCopyResourceURL (CFBundleGetMainBundle (), "Cha-Ching", "aiff", nil) "
bpolat
Ya, itu terkompilasi untuk saya. Lihat github.com/acani/Chats/blob/master/Chats/Chats/…
ma11hew28
2
Ini harus menjadi jawaban yang diterima, mengingat bahwa contoh Obj-C yang disediakan didasarkan pada Kerangka
AudioToolBox
@JochenBedersdorfer, Anda mungkin mendapatkan error karena objek Core Foundation dikelola secara otomatis oleh memori.
XCool
8

Dengan kelas & 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)
    }
}

Pemakaian:

testSound = Sound(name: "test", type: "caf")
testSound.play()
karimhossenbux.dll
sumber
2
Saya suka jawaban ini. Juga karena ini adalah suara sistem, saya tidak mendapatkan pesan sistem yang dilemparkan AVAudioPlayer ke konsol untuk xcode 8.
TPot
tolong bantu saya melakukan hal yang sama, suara diputar tetapi volumenya terlalu rendah. tidak dapat mendengar
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.
sumber
Itu AVAudioPlayer (contentsOf: soundURL) di Swift yang modern
kemas
5

Kode ini bekerja untuk saya. Gunakan Coba dan Tangkap untuk 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
sumber
4
var mySound = NSSound(named:"Morse.aiff")
mySound.play()

"Morse.aiff" adalah suara sistem OSX, tetapi jika Anda hanya mengklik "bernama" dalam XCode, Anda akan dapat melihat (di panel QuickHelp) di mana fungsi ini mencari suara. Ini bisa berada di folder "File pendukung"

philippe
sumber
4
Pertanyaannya adalah tentang iOS.
rmaddy
Memang ... Tidak bisa di simulator. Tidak ada dokumen yang tersedia hingga saat ini
philippe
4

Menurut Swift 2.0 baru, kita harus menggunakan do try catch. Kode tersebut akan terlihat seperti ini:

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
sumber
3

ini bekerja dengan 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
sumber
2
Tolong, jelaskan kode Anda. Jawaban kode saja kurang berharga daripada penjelasan.
Vincent
@ Vincent +1, sebenarnya saya penasaran & operator. Ini mungkin direferensikan antara suara dan memori.
elia
Anda harus menambahkan impor AudioToolbox lalu tambahkan kode di atas
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
sumber
2

Mari kita lihat pendekatan yang lebih diperbarui untuk pertanyaan ini:

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
sumber
1
Kode berfungsi dengan baik di Swift 4, tetapi tampaknya suara yang dipancarkan tidak mengikuti volume media
David Vargas
1

Solusi Matt Gibson berhasil untuk saya, ini adalah versi 3 yang cepat.

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

Cepat 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])
    }
}
}

atau

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

}
}

sumber
1

bekerja di 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
sumber
1

Contoh kode Swift :

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
sumber
Harap tambahkan lebih banyak detail tentang mengapa kode ini berguna.
Berendschot
1

Anda dapat mencoba ini di Swift 5.2:

func playSound() {
        let soundURL = Bundle.main.url(forResource: selectedSoundFileName, withExtension: "wav")
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: soundURL!)
        }
        catch {
            print(error)
        }
        audioPlayer.play()
    }
Xab Ion
sumber
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
sumber
Jangan hanya memposting kode - jelaskan fungsinya! stackoverflow.com/help/how-to-answer
Nino Filiu
silakan merujuk ke pertanyaan posting ini. Anda dapat menemukan jawabannya! terima kasih @NinoFiliu
Gulsan Borbhuiya
0

Gunakan Fungsi Ini untuk mengeluarkan suara di Swift (Anda dapat menggunakan fungsi ini di tempat Anda ingin mengeluarkan suara.)

Pertama Tambahkan SpriteKit dan AVFoundation Framework.

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
sumber
0

Kode ini berfungsi untuk saya:

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
sumber
0

Untuk 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)
        }
    }
}
He Yifei 何 一 非
sumber
0

Swift 3 inilah cara saya melakukannya.

{

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)

        }
    }

sumber
0

Tidak bisakah Anda import AVFoundationmemilih pemutar audio ( var audioPlayer : AVAudioPlayer!), dan memutar suaranya? ( let soundURL = Bundle.main.url(forResource: "sound", withExtension: "wav")

BoeingLikesToDab
sumber
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
sumber