使用 Swift for MacOS 播放音频文件

Posted

技术标签:

【中文标题】使用 Swift for MacOS 播放音频文件【英文标题】:Play an audio file using Swift for MacOS 【发布时间】:2018-10-09 19:32:07 【问题描述】:

我正在尝试使用 AVAudioFile、AVAudioEngine 和 AVAudioPlayerNode 简单地播放文件(在主包中或磁盘上)。

这是我正在做的事情:

import Foundation
import AppKit
import AudioToolbox
import AVFoundation

struct readFile 
    static var arrayFloatValues:[Float] = []
    static var points:[CGFloat] = []


class AudioAnalisys : NSObject 

class func open_audiofile() 
    let audioEngine: AVAudioEngine = AVAudioEngine()
    let audioPlayer: AVAudioPlayerNode = AVAudioPlayerNode()

    //get where the file is
    let url = Bundle.main.url(forResource: "TeamPlaylist", withExtension: "mp3")
    //put it in an AVAudioFile
    let audioFile = try! AVAudioFile(forReading: url!)
    //Get the audio file format
    //let format = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: file.fileFormat.channelCount, interleaved: false)
    let audioFormat = audioFile.processingFormat
    let audioFrameCount = UInt32(audioFile.length)
    //how many channels?
    print(audioFile.fileFormat.channelCount)
    print(audioFrameCount)
    //Setup the buffer for audio data
    let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: UInt32(audioFile.length))
    //put audio data in the buffer
    try! audioFile.read(into: audioFileBuffer!)
    //readFile.arrayFloatValues = Array(UnsafeBufferPointer(start: audioFileBuffer!.floatChannelData?[0], count:Int(audioFileBuffer!.frameLength)))

    //Init engine and player
    let mainMixer = audioEngine.mainMixerNode
    audioEngine.attach(audioPlayer)
    audioEngine.connect(audioPlayer, to:mainMixer, format: audioFileBuffer!.format)
    audioPlayer.scheduleBuffer(audioFileBuffer!, completionHandler: nil)
    audioEngine.prepare()
    do 
        try audioEngine.start()
        print("engine started")
     catch let error 
        print(error.localizedDescription)
    
    audioPlayer.play()

    

我可以看到频道数,即 FrameCount。 我什么都听不见。我究竟做错了什么? 这是我在控制台中得到的:

2 17414784 可选(0x00006080000006c0) 2018-10-09 21:21:02.161593+0200 频谱[1668:327525] [AudioHAL_Client] AudioHardware.cpp:666:AudioObjectGetPropertyData: AudioObjectGetPropertyData: 没有给定 ID 0 的对象 发动机启动 2018-10-09 21:21:02.594136+0200 频谱[1668:327593] MessageTracer:回退到默认白名单

【问题讨论】:

【参考方案1】:

答案如下: Can't play file from documents in AVAudioPlayer

导致:

 import Foundation
 import AppKit
 import AudioToolbox
 import AVFoundation

 struct readFile 
    static var arrayFloatValues:[Float] = []
    static var points:[CGFloat] = []
 

let audioEngine: AVAudioEngine = AVAudioEngine()
let audioPlayer: AVAudioPlayerNode = AVAudioPlayerNode()

class AudioAnalisys : NSObject 

class func open_audiofile() 
    //get where the file is
    let url = Bundle.main.url(forResource: "TeamPlaylist", withExtension: "mp3")
    //put it in an AVAudioFile
    let audioFile = try! AVAudioFile(forReading: url!)
    //Get the audio file format
    //let format = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: file.fileFormat.channelCount, interleaved: false)
    let audioFormat = audioFile.processingFormat
    let audioFrameCount = UInt32(audioFile.length)
    //how many channels?
    print(audioFile.fileFormat.channelCount)
    print(audioFrameCount)
    //Setup the buffer for audio data
    let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: UInt32(audioFile.length))
    //put audio data in the buffer
    try! audioFile.read(into: audioFileBuffer!)
    //readFile.arrayFloatValues = Array(UnsafeBufferPointer(start: audioFileBuffer!.floatChannelData?[0], count:Int(audioFileBuffer!.frameLength)))

    //Init engine and player
    let mainMixer = audioEngine.mainMixerNode
    audioEngine.attach(audioPlayer)
    audioEngine.connect(audioPlayer, to:mainMixer, format: audioFileBuffer!.format)
    audioPlayer.scheduleBuffer(audioFileBuffer!, completionHandler: nil)
    audioEngine.prepare()
    do 
        try audioEngine.start()
        print("engine started")
     catch let error 
        print(error.localizedDescription)
    
    audioPlayer.play()

   

【讨论】:

以上是关于使用 Swift for MacOS 播放音频文件的主要内容,如果未能解决你的问题,请参考以下文章

将音频播放速度提高 3 倍 - Swift

在 macOS 的 swift 5 中声明 ExtAudioFileRef 的正确方法

使用 Swift 通过 iPhone 扬声器强制播放音频文件

使用不同的 swift 文件播放音频

使用 Swift 播放随机音频文件

在 Swift 中使用 EZAudio 框架播放音频文件