标签: avaudiofile

如何用AVAudioPCMBuffer播放声音

我无法用AVAudioPCMBuffer播放声音(尽管我可以使用AVAudioFile).我收到了这个错误.

错误:AVAudioBuffer.mm:169: - [AVAudioPCMBuffer initWithPCMFormat:frameCapacity:]:必需条件为false:isCommonFormat

这是我下面的代码,我非常感谢你的帮助.

import UIKit
import AVFoundation

class ViewController: UIViewController {

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

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    audioEngine.attachNode(audioFilePlayer)

    let filePath: String = NSBundle.mainBundle().pathForResource("test", ofType: "mp3")!
    let fileURL: NSURL = NSURL(fileURLWithPath: filePath)!
    let audioFile = AVAudioFile(forReading: fileURL, error: nil)
    let audioFormat = audioFile.fileFormat
    let audioFrameCount = UInt32(audioFile.length)
    let audioFileBuffer = AVAudioPCMBuffer(PCMFormat: audioFormat, frameCapacity: audioFrameCount)

    var mainMixer …
Run Code Online (Sandbox Code Playgroud)

swift ios8 avaudiopcmbuffer avaudiofile avaudioplayernode

7
推荐指数
1
解决办法
5975
查看次数

SWIFT - 是否可以从AVAudioEngine或AudioPlayerNode保存音频?如果有,怎么样?

我一直在寻找Swift文档以保存AVAudioEngine的音频输出,但我找不到任何有用的提示.
有什么建议吗?

解决方案 我找到了解决方法,这要归功于matt的答案.这里有一个示例代码,说明如何在通过AVAudioEngine传递音频之后保存音频(我认为在技术上它是之前的)

newAudio = AVAudioFile(forWriting: newAudio.url, settings: nil, error: NSErrorPointer()) 
//Your new file on which you want to save some changed audio, and prepared to be bufferd in some new data...

var audioPlayerNode = AVAudioPlayerNode() //or your Time pitch unit if pitch changed   

//Now install a Tap on the output bus to "record" the transformed file on a our newAudio file.
audioPlayerNode.installTapOnBus(0, bufferSize: (AVAudioFrameCount(audioPlayer.duration)), format: opffb){
        (buffer: AVAudioPCMBuffer!, time: AVAudioTime!)  in 

        if (self.newAudio.length) …
Run Code Online (Sandbox Code Playgroud)

avasset swift avaudioengine avaudiofile avaudioplayernode

6
推荐指数
1
解决办法
2942
查看次数

AudioFileReadPackets在iOS8中已弃用

我在AudioFileReadPackets中遇到了奇怪的行为,因为它已经在iOS 8中被弃用了.应该如何替换它?

objective-c ios ios8 avaudiofile

5
推荐指数
1
解决办法
1306
查看次数

即使文件存在,AVAudioFile.length也为0

我正在创建一个AVAudioFile,用于将声音写入声音文件.如果文件已经存在,我想将framePosition移动到文件的末尾,以便在最后继续写入,而不是替换现有文件.

我做了一些测试,尝试将文件中的缓冲区读入一个具有不同URL的新文件,以便它不会覆盖原始文件.当我尝试将缓冲区读入新文件时,我遇到了崩溃:

let audioFile = try AVAudioFile(forReading: [URL to existing .caf file])
let audioFrameCount = AVAudioFrameCount(UInt32(audioFile.length))
let audioBuffer = AVAudioPCMBuffer(PCMFormat: audioFile.processingFormat, frameCapacity: audioFrameCount)

let newAudioFile = try AVAudioFile(forWriting: [another URL], settings: self.engine.mainMixerNode.outputFormatForBus(0).settings)
try newAudioFile.readIntoBuffer(audioBuffer, frameCount: audioFrameCount!) <-- CRASHES ON THIS LINE
Run Code Online (Sandbox Code Playgroud)

崩溃日志:因未捕获的异常'com.apple.coreaudio.avfaudio'而终止应用程序,原因:'error -50'

伙计,我真的很讨厌CoreAudio崩溃日志.他们绝对没有告诉我!

是不是可以将数据读入为写入而创建的文件中?

UPDATE

好的,所以经过一些建议我做了一些改变.基本上,这些是我正在采取的步骤:

  1. 检查文件是否已存在.
  2. 如果是,打开它进行读取并获取音频缓冲区.
  3. 创建一个用于写入的新文件(使用相同的文件URL)
  4. 使用writeFromBuffer将缓冲区从旧文件写入新文件
  5. 将新文件的framePosition移动到最后,以便我可以继续写入/记录它.

但是,写入后,新文件的长度为0.

这是我的代码:

//Check if a file already exists. If so continue to record at the end of it
var audioBuffer : AVAudioPCMBuffer!
var audioFrameCount : AVAudioFrameCount!
if (NSFileManager.defaultManager().fileExistsAtPath(self.audioRecordURL.path!)) …
Run Code Online (Sandbox Code Playgroud)

core-audio swift avaudioengine avaudiofile

5
推荐指数
1
解决办法
1377
查看次数

将单声道 AVAudioPCMBuffer 写入立体声 AVAudioFile

我正在使用 AVAudioEngine 录制音频,并将其保存为声音文件。

用户可以选择导入音频文件,然后如果愿意,可以在此文件的末尾继续录制。我通过将导入的文件读入 AVAudioPCMBuffer 来获取音频数据,然后将其写入要录制的文件中。如果导入的文件是立体声的(因为我正在写入的文件也是立体声的),这非常有用。但是,如果导入的文件是单声道的,当我尝试将 AVAudioPCMBuffer 写入文件时,代码会崩溃,仅仅是因为通道数不匹配。

是否可以将处理格式设置为立体声的单声道 AVAudioPCMBuffer 读入 av AVAudioFile 中?我可以将缓冲区转换为立体声吗?

以下是我如何从导入的文件中获取音频缓冲区的示例:

let existingAudioFile = try AVAudioFile(forReading: existingFileUrl)
var audioFrameCount = AVAudioFrameCount(existingAudioFile.length)
let audioBuffer = AVAudioPCMBuffer(PCMFormat: existingAudioFile.processingFormat, frameCapacity: audioFrameCount) //Mono
try existingAudioFile.readIntoBuffer(audioBuffer)
Run Code Online (Sandbox Code Playgroud)

这就是我使用 AVAudioEngine 创建 AVAudioFile 的地方:

self.audioFile = try AVAudioFile(forWriting: self.audioRecordURL, settings: self.engine.mainMixerNode.outputFormatForBus(0).settings) //This is in stereo
Run Code Online (Sandbox Code Playgroud)

最后,这就是我将音频缓冲区写入文件的方式:

try self.audioFile.writeFromBuffer(audioBuffer)
Run Code Online (Sandbox Code Playgroud)

如果我将音频转换为立体声,一切正常。

ios avaudioengine avaudiopcmbuffer avaudiofile

5
推荐指数
0
解决办法
1744
查看次数

在级联2音频文件期间,trackWithMediaType始终返回空数组

我有2个音频文件audioFile1.m4aaudioFile2.m4a.我想创建一个combined.m4a包含audioFile1.m4aaudioFile2.m4a一个接一个的级联音频.我使用下面的代码,我的问题tracksWithMediaType总是返回空数组.audioIds包含音频文件名.

    NSError *error = nil;
    BOOL ok = NO;


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,    NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];


    CMTime nextClipStartTime = kCMTimeZero;
    //Create AVMutableComposition Object.This object will hold our multiple AVMutableCompositionTrack.
    AVMutableComposition *composition = [[AVMutableComposition alloc] init];

    AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

    for (int i = 0; i< [audioIds count]; i++) {
        NSString *audioFileName = [audioIds objectAtIndex:i];

        //Build the filename with path

        NSString *soundOne = …
Run Code Online (Sandbox Code Playgroud)

audio avaudiorecorder ios avaudiofile

5
推荐指数
0
解决办法
131
查看次数

如何搜索“com.apple.coreaudio.avfaudio”的错误代码?

我在哪里可以得到com.apple.coreaudio.avfaudio错误代码的信息,例如:

由于未捕获的异常“com.apple.coreaudio.avfaudio”而终止应用程序,原因:“错误 -50”

将 PCM 缓冲区写入AVAudioFile. 缓冲区来自AVAudioEngine的输出节点。

在此处输入图片说明

错误:

*终止应用程序由于未捕获的异常'com.apple.coreaudio.avfaudio',理由是: '错误-50' *第一掷调用堆栈:(0x18eb46fe0 0x18d5a8538 0x18eb46eb4 0x1a8d051cc 0x1a8d731dc 0x1000d45e0 0x1000d4820 0x1a8d14654 0x1a8d146c0 0x1a8d8c26c 0x1a8d8c1fc 0x100ae5a10 0x100af1a84 0x100b001f8 0x100ae7a60 0x100af3128 0x100ae9634 0x100af5630 0x100af6f48 0x18dc0968c 0x18dc0959c 0x18dc06cb4) libc++abi.dylib:以未捕获的 NSException 类型异常终止

你可以帮帮我吗?

avaudioengine avaudiofile

5
推荐指数
1
解决办法
3108
查看次数

从某个时间开始将 AVAudioFile 读入缓冲区

假设我有一个持续时间为 10 秒的 AVAudioFile。我想将该文件加载到 AVAudioPCMBuffer 中,但我只想加载特定秒数/毫秒后或特定 AVAudioFramePosition 之后出现的音频帧。

它看起来不像 AVAudioFile 的readIntoBuffer方法给我那种精度,所以我假设我必须在 AVAudioBuffer 级别或更低级别工作?

objective-c ios avaudioengine avaudiofile avaudioplayernode

5
推荐指数
1
解决办法
801
查看次数

AVAudioFile无法在AVAudioEngine中播放

我正在尝试使用AVAudioEngine播放AVAudioFile。该代码主要是从Apple Developer在线视频中获取和改编的,但是没有回放。已经花了一些时间浏览这些论坛,但是似乎没有任何启示。

我有两种方法。第一个调用标准打开文件对话框,打开音频文件,分配一个AVAudioBuffer对象(稍后将使用)并用音频数据填充它。第二个设置AVAudioEngine和AVAudioPlayerNode对象,连接所有内容并播放文件。下面列出了这两种方法。

- (IBAction)getSoundFileAudioData:(id)sender {


    NSOpenPanel* openPanel = [NSOpenPanel openPanel];

    openPanel.title = @"Choose a .caf file";
    openPanel.showsResizeIndicator = YES;
    openPanel.showsHiddenFiles = NO;
    openPanel.canChooseDirectories = NO;
    openPanel.canCreateDirectories = YES;
    openPanel.allowsMultipleSelection = NO;
    openPanel.allowedFileTypes = @[@"caf"];

    [openPanel beginWithCompletionHandler:^(NSInteger result){
       if (result == NSFileHandlingPanelOKButton) {
        NSURL*  theAudioFileURL = [[openPanel URLs] objectAtIndex:0];

        // Open  the document.

        theAudioFile = [[AVAudioFile alloc] initForReading:theAudioFileURL error:nil];

        AVAudioFormat *format = theAudioFile.processingFormat;
        AVAudioFrameCount capacity = (AVAudioFrameCount)theAudioFile.length;

        theAudioBuffer = [[AVAudioPCMBuffer alloc] 
             initWithPCMFormat:format frameCapacity:capacity];
        NSError *error;
        if (![theAudioFile readIntoBuffer:theAudioBuffer error:&error])  { …
Run Code Online (Sandbox Code Playgroud)

avaudioengine avaudiopcmbuffer avaudiofile

4
推荐指数
1
解决办法
685
查看次数

将AVAudioPCMBuffer写入压缩的AVAudioFile中

我们正在开发一个记录并保留麦克风输入的应用程序。使用的AVAudioRecorder是不是一种选择,因为需要实时音频处理。

AVAudioEngine 之所以使用,是因为它提供了对输入音频的低级访问。

let audioEngine  = AVAudioEngine()
let inputNode = audioEngine.inputNode
let inputFormat = inputNode.inputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: AVAudioFrameCount(inputFormat.sampleRate * sampleInterval), format: inputFormat) { (buffer: AVAudioPCMBuffer, time: AVAudioTime) -> Void in
    // sound preprocessing
    // writing to audio file
    audioFile.write(buffer.floatChannelData![0])
})
Run Code Online (Sandbox Code Playgroud)

我们的问题是录音量很大。对于5个小时的录制,输出的音频文件为1.2GB .caf格式。

let audioFile = AVAudioFile(forWriting: recordingPath, settings: [:], commonFormat: .pcmFormatFloat32, interleaved: isInterleaved)
Run Code Online (Sandbox Code Playgroud)

是否有压缩音频文件的好方法?

默认采样频率为44100Hz。我们将使用AVAudioMixerNode将输入下采样到20Khz(在我们的情况下,较低的质量是可以接受的),但是输出的大小在大小上是不可接受的。

录音中包含很大部分的背景噪音。

有什么建议么?

avfoundation ios swift avaudiofile

3
推荐指数
1
解决办法
1198
查看次数

在音频引擎输入节点上安装 Tap 时出错

每当代码到达时 inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) {[weak self] (buffer:AVAudioPCMBuffer, when:AVAudioTime),应用程序就会因以下错误而崩溃

由于未捕获的异常“com.apple.coreaudio.avfaudio”而终止应用程序,原因:“所需条件为假:format.sampleRate == hwFormat.sampleRate”

在添加另一个之前,我已经厌倦了移除水龙头,并且我确保我不会添加多个水龙头。奇怪的是,该应用程序在低于 12 的 iOS 上运行良好,并且在所有模拟器上运行良好。

它仅在使用 iOS 12 的真实设备上崩溃。我尝试寻找解决方案但找不到任何东西。

audio-recording ios swift avaudioengine avaudiofile

3
推荐指数
1
解决办法
1119
查看次数

AVAudioEngine AVAudioPlayerNode的时间管理和回调不正确

我对iOS8中的新音频引擎存在严重问题.我有一个使用AVAudioPlayer构建的应用程序,我试图找到一种迁移到新架构的方法,但是我遇到了以下问题(我相信你会同意,这是一个严重的基本障碍) :

我的头文件:

AVAudioEngine *engine;
AVAudioMixerNode *mainMixer;
AVAudioPlayerNode *player;
Run Code Online (Sandbox Code Playgroud)

我的m文件(在viewDidLoad中):

engine = [[AVAudioEngine alloc] init];
player = [[AVAudioPlayerNode alloc] init];

[engine attachNode:player];

NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp3"]];

AVAudioFile *file = [[AVAudioFile alloc] initForReading:fileUrl error:nil];

NSLog(@"duration: %.2f", file.length / file.fileFormat.sampleRate);

[player scheduleFile:file atTime:nil completionHandler:^{
    AVAudioTime *nodeTime = player.lastRenderTime;
    AVAudioTime *playerTime = [player playerTimeForNodeTime:nodeTime];

    float secs = (float)playerTime.sampleTime / file.fileFormat.sampleRate;

    NSLog(@"finished at: %.2f", secs);
}];

mainMixer = [engine mainMixerNode];

[engine connect:player to:mainMixer format:file.processingFormat];
[engine startAndReturnError:nil];

[player play];
Run Code Online (Sandbox Code Playgroud)

上面的代码初始化引擎和节点,然后开始播放我正在使用的任何文件.首先,它打印出音乐文件的持续时间,然后,在完成播放后,在回调函数中,它打印播放器的当前时间.这两个应该是相同的或者在最坏的情况下,彼此非常非常接近,但事实并非如此,这两个值之间的差异非常大,例如 …

avaudioplayer ios8 avaudioengine avaudiofile avaudioplayernode

2
推荐指数
1
解决办法
887
查看次数