Tạo và phát âm thanh nhanh chóng


103

Vì vậy, những gì tôi muốn làm là tạo và phát nhanh một âm thanh sẽ phát khi tôi nhấn một nút, tôi biết cách làm điều đó trong Objective-C, nhưng có ai biết cách làm trong Swift không?

Nó sẽ như thế này cho Objective-C:

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

Và sau đó để chơi nó, tôi sẽ làm:

AudioServicesPlaySystemSound(Explosion);

Có ai biết làm thế nào tôi có thể làm điều này?


2
Gốc của câu hỏi này là cách gọi các hàm C từ swift. Tôi cũng tò mò về điều này.
67cherries

dòng này có thể tạo url âm thanh: var url :NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("mysoundname", ofType: "wav"))
Connor

@connor Cảm ơn điều đó hoạt động nhưng còn đối với AudioServicesCreateSystemSoundID
Jacob Banks

Tôi không chắc về điều đó. Tôi chỉ có thể gọi mục tiêu-c api nhanh chóng.
Connor

Câu trả lời:


83

Đây là một chút mã mà tôi đã thêm vào FlappySwift hoạt động:

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

}

Có vẻ như bạn chỉ có thể khai báo audioPlayer ngay trước khi sử dụng nó, nhưng điều đó không hoạt động với tôi trong trình mô phỏng. Tôi đã phải khai báo nó ở đầu giống như bạn đã làm.
Adam Thương mến

@ Adam Loving bạn có thể khai Audioplayer ngay trước khi sử dụng nó, nhưng chắc chắn rằng bạn invoke play () trong hàm tương tự như bạn tuyên bố nó (như trái ngược với câu trả lời tốt) Hơn nữa, tôi sẽ tuyên bố coinSoundaudioPlayervới letthay vì varkể từ khi bạn không muốn thay đổi các đối tượng này tại một thời điểm sau đó.
fat32

3
Trong Swift 2, hãy nhớ chạy nó theo cách này do { (player object) } catch _ { }nếu không bạn sẽ gặp lỗi! :)
ParisNakitaKejser

1
Nhưng chú ý! Nó sẽ tạm dừng nhạc nền từ máy nghe nhạc. Để chơi âm thanh ngắn chúng ta phải sử dụng câu trả lời dưới đây
Nikita Pronchik

Downvote - đây không phải là một hệ thống âm thanh, nó được sử dụng một api khác nhau
William Entriken

119

Điều này tương tự với một số câu trả lời khác, nhưng có lẽ "Swifty" hơn một chút:

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

Lưu ý rằng đây là một ví dụ nhỏ tái tạo tác dụng của mã trong câu hỏi. Bạn sẽ cần phải đảm bảo import AudioToolbox, cộng với mẫu chung cho loại mã này sẽ là tải âm thanh của bạn khi ứng dụng của bạn khởi động, lưu chúng vào SystemSoundIDcác biến ví dụ ở đâu đó, sử dụng chúng trong toàn bộ ứng dụng của bạn, sau đó gọi AudioServicesDisposeSystemSoundIDkhi bạn hoàn thành với họ.


1
Bạn cũng cần phải AudioToolbox nhập khẩu
Brody Robertson

Sau này có cần gọi điện AudioServicesDisposeSystemSoundID(mySound)để giải phóng bộ nhớ không? nếu bạn làm điều đó ngay lập tức, âm thanh về cơ bản không phát (được làm sạch ngay lập tức) vì vậy tôi đã làm dispatch_aftervà làm sạch nó 10 giây sau đó.
owenfi

@owenfi Đoạn mã trong câu trả lời của tôi chỉ là Swift tương đương với đoạn mã trong câu hỏi. Mô hình chung cho AudioServices là tải âm thanh của bạn lên khi ứng dụng của bạn kích hoạt, sử dụng chúng trong toàn bộ ứng dụng và loại bỏ chúng khi ứng dụng đóng, nhưng mỗi ứng dụng sẽ khác nhau.
Matt Gibson

@ozgur Tại sao bạn đang sử dụng phiên bản Xcode lỗi thời? Chúng tôi sẽ cần biết "không hoạt động" nghĩa là gì và có lẽ bạn nên đặt một câu hỏi mới nếu bạn gặp vấn đề cụ thể.
Matt Gibson

thực sự đây là cách duy nhất để phát tệp wav. AVPlayer dường như không hoạt động.
Haitao

18

Tiện ích mở rộng Swift:

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

Sau đó, từ bất kỳ đâu trong ứng dụng của bạn (nhớ là import AudioToolbox), bạn có thể gọi

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

để phát "sound.mp3"


Khi tôi thực hiện điều này trong trò chơi SpriteKit, luôn có độ trễ trước khi âm thanh được phát. Ngay cả khi tôi đặt nó vào bên trong DispatchQueue.global(qos: .userInitiated).async {}.
Jon Kantner

NSBundleđã được thay thế bởi Bundle, sử dụng Bundle.main.url(forResource: fileName, withExtension: fileExtension)thay thế
diachedelic

14

Điều này tạo ra một SystemSoundIDtừ một tệp có tên 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
}

Bạn đã thử biên dịch mã chưa? Tôi gặp lỗi "Không thể chuyển đổi loại giải nén 'Unmanaged <CFURL>!' để gõ 'CFString' "từ dòng này" let soundURL = CFBundleCopyResourceURL (CFBundleGetMainBundle (), "Cha-Ching", "aiff", nil) "
bpolat


2
Đây phải là câu trả lời được chấp nhận, vì ví dụ obj-C được cung cấp dựa trên Khung
AudioToolBox

@JochenBedersdorfer, có thể bạn đang gặp lỗi do các đối tượng Core Foundation được quản lý bộ nhớ tự động.
XCool

8

Với lớp học & Hộp công cụ âm thanh:

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

Sử dụng:

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

2
Tôi thích câu trả lời này. Cũng bởi vì nó là hệ thống âm thanh, tôi không nhận được thông báo hệ thống AVAudioPlayer ném trong giao diện điều khiển cho xcode 8.
TPot

vui lòng giúp tôi đang làm điều tương tự, âm thanh phát nhưng âm lượng quá nhỏ. không thể nghe thấy
veeresh ktyles

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

Đó là AVAudioPlayer (contentOf: soundURL) trong Swift hiện đại
đóng hộp

5

Mã này phù hợp với tôi. Sử dụng Thử và Bắt cho 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" là âm thanh hệ thống của OSX, nhưng nếu bạn chỉ cần nhấp vào "có tên" trong XCode, bạn sẽ có thể xem (trong ngăn Trợ giúp nhanh) nơi chức năng này đang tìm kiếm âm thanh. Nó có thể nằm trong thư mục "Các tệp hỗ trợ" của bạn


4
Câu hỏi là về iOS.
rmaddy

Thật vậy ... Không thể làm cho nó trong giả lập. Không có tài liệu nào cho đến nay
philippe

4

Theo Swift 2.0 mới, chúng ta nên sử dụng hãy thử bắt. Mã sẽ như thế này:

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

điều này đang hoạt động với 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
Vui lòng giải thích mã của bạn. Câu trả lời chỉ có mã ít giá trị hơn so với lời giải thích.
Vincent

@Vincent +1, thực sự tôi đang thắc mắc & nhà điều hành. Điều này có thể được tham chiếu giữa âm thanh và bộ nhớ.
elia

bạn phải thêm AudioToolbox nhập khẩu sau đó thêm các mã trên
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

Hãy để chúng tôi xem một cách tiếp cận cập nhật hơn cho câu hỏi này:

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
Mã này hoạt động tốt trên Swift 4, nhưng dường như âm thanh phát ra không theo khối lượng phương tiện truyền thông
David Vargas

1

Giải pháp của Matt Gibson phù hợp với tôi, đây là phiên bản 3 nhanh chóng.

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

hoặc là

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

làm việc ở 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

Ví dụ về mã 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);
    }
}

Vui lòng thêm chi tiết về lý do tại sao mã này hữu ích.
Berendschot

1

Bạn có thể thử điều này trong 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()
    }

1

nhanh chóng 4 và 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()    }

}


Đừng chỉ đăng mã - giải thích những gì nó làm! stackoverflow.com/help/how-to-answer
Nino Filiu

vui lòng tham khảo câu hỏi của bài đăng này. Bạn có thể tìm thấy câu trả lời của mình! cảm ơn bạn @NinoFiliu
Gulsan Borbhuiya

0

Sử dụng Chức năng này để tạo âm thanh trong Swift (Bạn có thể sử dụng chức năng này khi bạn muốn tạo âm thanh.)

Đầu tiên Thêm SpriteKit và 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")

0

Mã này phù hợp với tôi:

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

Đối với 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 đây là cách tôi thực hiện.

{

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

Bạn không thể chỉ import AVFoundation, chọn trình phát âm thanh ( var audioPlayer : AVAudioPlayer!) và phát âm thanh? ( 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] )
    }    

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.