我无法用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文档以保存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) 我在AudioFileReadPackets中遇到了奇怪的行为,因为它已经在iOS 8中被弃用了.应该如何替换它?
我正在创建一个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
好的,所以经过一些建议我做了一些改变.基本上,这些是我正在采取的步骤:
但是,写入后,新文件的长度为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) 我正在使用 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)
如果我将音频转换为立体声,一切正常。
我有2个音频文件audioFile1.m4a和audioFile2.m4a.我想创建一个combined.m4a包含audioFile1.m4a和audioFile2.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) 我在哪里可以得到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 类型异常终止
你可以帮帮我吗?
假设我有一个持续时间为 10 秒的 AVAudioFile。我想将该文件加载到 AVAudioPCMBuffer 中,但我只想加载特定秒数/毫秒后或特定 AVAudioFramePosition 之后出现的音频帧。
它看起来不像 AVAudioFile 的readIntoBuffer方法给我那种精度,所以我假设我必须在 AVAudioBuffer 级别或更低级别工作?
我正在尝试使用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) 我们正在开发一个记录并保留麦克风输入的应用程序。使用的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(在我们的情况下,较低的质量是可以接受的),但是输出的大小在大小上是不可接受的。
录音中包含很大部分的背景噪音。
有什么建议么?
每当代码到达时
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 的真实设备上崩溃。我尝试寻找解决方案但找不到任何东西。
我对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
avaudiofile ×12
ios ×6
swift ×5
ios8 ×3
objective-c ×2
audio ×1
avasset ×1
avfoundation ×1
core-audio ×1