신속한 사운드 생성 및 재생


103

그래서 제가하고 싶은 것은 버튼을 눌렀을 때 재생되는 사운드를 신속하게 생성하고 재생하는 것입니다. Objective-C에서하는 방법을 알고 있지만 Swift에서하는 방법을 아는 사람이 있습니까?

Objective-C의 경우 다음과 같습니다.

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

그리고 그것을 재생하려면 다음을 수행합니다.

AudioServicesPlaySystemSound(Explosion);

내가 어떻게 할 수 있는지 아는 사람 있나요?


2
이 질문의 근원은 swift에서 C 함수를 호출하는 방법입니다. 이것도 궁금합니다.
— 67cherries 2014-06-04

이 줄은 사운드 URL을 만들 수 있습니다. var url :NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("mysoundname", ofType: "wav"))
— Connor

@connor 감사가 작동하는지하지만 대한 AudioServicesCreateSystemSoundID에 대한
— 야곱 은행

나는 그것에 대해 확실하지 않다. 나는 swift에서 objective-c api 만 호출 할 수있었습니다.
— Connor

답변:


83

다음은 작동하는 FlappySwift에 추가 한 코드입니다.

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

}

사용하기 직전에 audioPlayer를 선언 할 수있는 것처럼 보이지만 시뮬레이터에서는 작동하지 않았습니다. 당신처럼 맨 위에 선언해야 했어요.
— Adam Loving

당신이 바로 그것을 사용하기 전에 audioPlayer을 선언 할 수 있습니다 사랑 @ 아담,하지만 당신은 (좋은 답변 반대) 당신은 또한 그것을 선언 동일한 기능의 재생 ()를 호출해야합니다, 나는 선언 할 것 coinSound와 audioPlayer함께 let대신 var당신이 원하지 않기 때문에 나중에 이러한 개체를 변경합니다.
— fat32

3
Swift 2에서는 이런 식으로 실행해야합니다. do { (player object) } catch _ { }그렇지 않으면 버그가 발생합니다! :)
— ParisNakitaKejser

1
하지만주의! 플레이어에서 배경 음악을 일시 중지합니다. 짧은 사운드를 재생하려면 우리는 아래에 답을 사용해야합니다
— 니키타 Pronchik

Downvote -이 시스템 소리, 그것은 다른 API를 사용하지 않는
— 윌리엄 Entriken

119

이것은 다른 답변과 비슷하지만 약간 더 "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);
}

이것은 질문에있는 코드의 효과를 재현하는 사소한 예입니다. 을 확인해야합니다 import AudioToolbox. 이러한 종류의 코드에 대한 일반적인 패턴은 앱이 시작될 때 사운드를로드하고 SystemSoundID인스턴스 변수에 저장하고 앱 전체에서 사용한 다음 AudioServicesDisposeSystemSoundID완료되면 호출하는 것입니다. 그들과 함께.


1
또한 수입 AudioToolbox 필요
— 브로디 로버트슨을

AudioServicesDisposeSystemSoundID(mySound)나중에 메모리를 확보하기 위해 전화해야 합니까? 바로하면 사운드가 기본적으로 재생되지 않으므로 (즉시 정리 됨) dispatch_after10 초 후에 정리했습니다.
— owenfi

@owenfi 내 대답의 코드 조각은 질문의 코드 조각에 해당하는 Swift와 같습니다. AudioServices의 일반적인 패턴은 앱이 실행될 때 사운드를로드하고, 앱 전체에서 사용하고, 앱이 닫힐 때 사운드를 처리하는 것입니다.하지만 각 앱은 다릅니다.
— Matt Gibson

@ozgur Xcode의 오래된 버전을 사용하는 이유는 무엇입니까? "작동하지 않음"이 무엇을 의미하는지 알아야하며 특정 문제가있는 경우 새로운 질문을하는 것이 좋습니다.
— Matt Gibson

실제로 이것은 wav 파일을 재생하는 유일한 방법입니다. AVPlayer가 작동하지 않는 것 같습니다.
— Haitao

18

편리한 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)
        }
    }
}

그런 다음 앱의 어느 곳에서나 (기억하세요 import AudioToolbox)

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

"sound.mp3"재생


SpriteKit 게임에서 이것을 실행하면 사운드가 재생되기 전에 항상 지연이 발생합니다. 안에 넣어도 DispatchQueue.global(qos: .userInitiated).async {}.
— Jon Kantner

NSBundle로 대체되었습니다 Bundle. Bundle.main.url(forResource: fileName, withExtension: fileExtension)대신 사용
— diachedelic

14

이것은 SystemSoundID라는 파일에서 생성 됩니다 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
}

코드를 컴파일하려고 했습니까? "Extression의 유형 '관리되지 않는 <CFURL>!'을 (를) 변환 할 수 없습니다."라는 오류가 발생합니다. 이 줄에서 'CFString' "을 입력하려면"let soundURL = CFBundleCopyResourceURL (CFBundleGetMainBundle (), "Cha-Ching", "aiff", nil) "
— bpolat

예, 저를 위해 컴파일됩니다. 참조 github.com/acani/Chats/blob/master/Chats/Chats/...
— ma11hew28

2
제공된 Obj-C 예제가 AudioToolBox Framework
— eharo2

@JochenBedersdorfer, Core Foundation 개체가 자동으로 메모리를 관리하기 때문에 오류가 발생할 수 있습니다.
— XCool

8

클래스 및 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)
    }
}

용법:

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

2
나는이 대답을 좋아한다. 또한 시스템 사운드이기 때문에 AVAudioPlayer가 콘솔에 xcode 8에 대한 시스템 메시지를 표시하지 않습니다.
— TPot

내가 똑같은 일을하고 있고, 소리가 재생되지만 볼륨이 너무 낮습니다. 들을 수 없습니다
— 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()
    }
}

최신 Swift의 AVAudioPlayer (contentsOf : soundURL)입니다.
— 박스형

5

이 코드는 저에게 효과적입니다. AVAudioPlayer에 Try and Catch 사용

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"는 OSX의 시스템 사운드이지만 XCode 내에서 "named"를 클릭하면이 함수가 사운드를 검색하는 위치를 볼 수 있습니다 (빠른 도움말 창에서). "지원 파일"폴더에있을 수 있습니다.


4
문제는 iOS에 관한 것입니다.
— rmaddy

사실 ... 시뮬레이터에서 만들 수 없습니다. 현재까지 사용 가능한 문서 없음
— philippe

4

새로운 Swift 2.0에 따르면 do try catch를 사용해야합니다. 코드는 다음과 같습니다.

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

이것은 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
코드를 설명해주세요. 코드 전용 답변은 설명보다 가치가 떨어집니다.
— Vincent

@Vincent +1, 실제로 궁금하고 연산자입니다. 이것은 사운드와 메모리 사이에서 참조 될 수 있습니다.
— elia

당신은 그 수입 AudioToolbox를 추가하려면 위의 코드를 추가 할 필요가
— 모하마드 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

이 질문에 대한보다 업데이트 된 접근 방식을 살펴 보겠습니다.

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
코드는 스위프트 사에 벌금을 작동하지만 분명히 방출 된 소리는 미디어 볼륨 따르지 않는
— 데이비드 바 가스

1

Matt Gibson의 솔루션이 저에게 효과적이었습니다. 여기에 신속한 3 버전이 있습니다.

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

1

스위프트 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])
    }
}
}

또는

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

일하다 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

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

이 코드가 왜 도움이되는지 자세히 설명해주세요.
— Berendschot

1

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

스위프트 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()    }

}


단순히 코드를 게시하지 말고 그것이 무엇을하는지 설명하십시오! stackoverflow.com/help/how-to-answer
— Nino Filiu

이 게시물의 질문을 참조하십시오. 답을 찾을 수 있습니다! 당신에게 @NinoFiliu 감사합니다
— Gulsan Borbhuiya

0

이 기능을 사용하여 Swift에서 소리를냅니다. (이 기능은 소리를 내고 싶은 곳에서 사용할 수 있습니다.)

먼저 SpriteKit 및 AVFoundation 프레임 워크를 추가합니다.

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

이 코드는 나를 위해 작동합니다.

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

대한 스위프트 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은 여기에 내가하는 방법입니다.

{

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

그냥 import AVFoundation, 오디오 플레이어 ( var audioPlayer : AVAudioPlayer!)를 선택 하고 사운드를 재생할 수 없습니까? ( 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] )
    }    

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.