신속한 사운드 생성 및 재생


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을 선언 할 수 있습니다 사랑 @ 아담,하지만 당신은 (좋은 답변 반대) 당신은 또한 그것을 선언 동일한 기능의 재생 ()를 호출해야합니다, 나는 선언 할 것 coinSoundaudioPlayer함께 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.