iOS 将 m4a 转换为 WAV 的代码
iOS Code to Convert m4a to WAV
有人有任何代码片段可以说明如何将 M4a 文件转换为 WAV 文件吗?我知道有些库可以反过来转换。
谢谢。
AVFoundation 框架中的 AVAssetReader 和 AVAssetWriter 可用于读取 AAC 文件并将该数据作为 WAV/RIFF 文件写入 iOS 设备。 Apple 开发者网站上有示例代码。这不仅仅是一个简短的片段。
如果其他人需要一些代码来执行此操作,请在 Swift
func convertAudioFile(sourceURL: CFURLRef, destinationURL:
CFURLRef, outputFormat: OSType ,
outputSampleRate: Float64) -> OSStatus
{
var error : OSStatus = noErr
var destinationFile : ExtAudioFileRef = nil
var sourceFile : ExtAudioFileRef = nil
var srcFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
var dstFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
var audioConverter : AudioConverterRef = nil
audioConverter = AudioConverterRef.init()
ExtAudioFileOpenURL(sourceURL, &sourceFile)
var thePropertySize: UInt32 = UInt32(strideofValue(srcFormat))
ExtAudioFileGetProperty(sourceFile, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat)
dstFormat.mSampleRate = (outputSampleRate == 0 ? srcFormat.mSampleRate : outputSampleRate) //Set sample rate
dstFormat.mFormatID = outputFormat
dstFormat.mChannelsPerFrame = 1
dstFormat.mBitsPerChannel = 16
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame
dstFormat.mFramesPerPacket = 1
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger // little-endian
//Create destination file
ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, nil,
AudioFileFlags.EraseFile.rawValue, &destinationFile)
ExtAudioFileSetProperty(sourceFile, kExtAudioFileProperty_ClientDataFormat, thePropertySize, &dstFormat)
ExtAudioFileSetProperty(destinationFile, kExtAudioFileProperty_ClientDataFormat, thePropertySize, &dstFormat)
var size : UInt32 = UInt32(strideofValue(audioConverter))
ExtAudioFileGetProperty(destinationFile, kExtAudioFileProperty_AudioConverter, &size, &audioConverter)
var canResume : UInt32 = 0
size = UInt32(strideofValue(canResume))
error = AudioConverterGetProperty(audioConverter, kAudioConverterPropertyCanResumeFromInterruption, &size, &canResume)
let bufferByteSize : UInt32 = 32768
var srcBuffer = [UInt8](count: 32768, repeatedValue: 0)
var sourceFrameOffset : ULONG = 0
print("Converting audio file")
while(true){
var fillBufList = AudioBufferList(
mNumberBuffers: 1,
mBuffers: AudioBuffer(
mNumberChannels: 2,
mDataByteSize: UInt32(srcBuffer.count),
mData: &srcBuffer
)
)
var numFrames : UInt32 = 0
if(dstFormat.mBytesPerFrame > 0){
numFrames = bufferByteSize / dstFormat.mBytesPerFrame
}
ExtAudioFileRead(sourceFile, &numFrames, &fillBufList)
if(numFrames == 0){
error = noErr;
break;
}
sourceFrameOffset += numFrames
error = ExtAudioFileWrite(destinationFile, numFrames, &fillBufList)
}
ExtAudioFileDispose(destinationFile)
ExtAudioFileDispose(sourceFile)
let audioAsset = AVURLAsset.init(URL: destinationURL, options: nil)
if(audioAsset.duration.seconds < 5.0){
error = -2500
}
return error;
这是对@O2U 回答的编辑。如上代码实际上并没有将其转换为 wave 文件。请在第 //Create destination file
ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, nil,
AudioFileFlags.EraseFile.rawValue, &destinationFile)
行的上述代码中使用 "kAudioFileWAVEType" 而不是 "kAudioFileCAFType"
只是为了更新 Swift 3:
func convertAudio(_ url: URL, outputURL: URL) {
var error : OSStatus = noErr
var destinationFile: ExtAudioFileRef? = nil
var sourceFile : ExtAudioFileRef? = nil
var srcFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
var dstFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
ExtAudioFileOpenURL(url as CFURL, &sourceFile)
var thePropertySize: UInt32 = UInt32(MemoryLayout.stride(ofValue: srcFormat))
ExtAudioFileGetProperty(sourceFile!,
kExtAudioFileProperty_FileDataFormat,
&thePropertySize, &srcFormat)
dstFormat.mSampleRate = 44100 //Set sample rate
dstFormat.mFormatID = kAudioFormatLinearPCM
dstFormat.mChannelsPerFrame = 1
dstFormat.mBitsPerChannel = 16
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame
dstFormat.mFramesPerPacket = 1
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked |
kAudioFormatFlagIsSignedInteger
// Create destination file
error = ExtAudioFileCreateWithURL(
outputURL as CFURL,
kAudioFileWAVEType,
&dstFormat,
nil,
AudioFileFlags.eraseFile.rawValue,
&destinationFile)
print("Error 1 in convertAudio: \(error.description)")
error = ExtAudioFileSetProperty(sourceFile!,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat)
print("Error 2 in convertAudio: \(error.description)")
error = ExtAudioFileSetProperty(destinationFile!,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat)
print("Error 3 in convertAudio: \(error.description)")
let bufferByteSize : UInt32 = 32768
var srcBuffer = [UInt8](repeating: 0, count: 32768)
var sourceFrameOffset : ULONG = 0
while(true){
var fillBufList = AudioBufferList(
mNumberBuffers: 1,
mBuffers: AudioBuffer(
mNumberChannels: 2,
mDataByteSize: UInt32(srcBuffer.count),
mData: &srcBuffer
)
)
var numFrames : UInt32 = 0
if(dstFormat.mBytesPerFrame > 0){
numFrames = bufferByteSize / dstFormat.mBytesPerFrame
}
error = ExtAudioFileRead(sourceFile!, &numFrames, &fillBufList)
print("Error 4 in convertAudio: \(error.description)")
if(numFrames == 0){
error = noErr;
break;
}
sourceFrameOffset += numFrames
error = ExtAudioFileWrite(destinationFile!, numFrames, &fillBufList)
print("Error 5 in convertAudio: \(error.description)")
}
error = ExtAudioFileDispose(destinationFile!)
print("Error 6 in convertAudio: \(error.description)")
error = ExtAudioFileDispose(sourceFile!)
print("Error 7 in convertAudio: \(error.description)")
}
这是 MSCottWaller Swift 3 回答的 Objective-C 版本。您需要@import AudioToolbox。
-(void) convertAudio:(NSURL*)url outputURL:(NSURL*)outputURL
{
OSStatus error = noErr;
ExtAudioFileRef destinationFile = nil;
ExtAudioFileRef sourceFile = nil;
AudioStreamBasicDescription srcFormat;
AudioStreamBasicDescription dstFormat;
ExtAudioFileOpenURL((__bridge CFURLRef)url, &sourceFile);
UInt32 thePropertySize = sizeof(srcFormat); //UInt32(MemoryLayout.stride(ofValue: srcFormat));;
ExtAudioFileGetProperty(sourceFile, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat);
dstFormat.mSampleRate = 44100; //Set sample rate
dstFormat.mFormatID = kAudioFormatLinearPCM;
dstFormat.mChannelsPerFrame = 1;
dstFormat.mBitsPerChannel = 16;
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame;
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame;
dstFormat.mFramesPerPacket = 1;
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
// Create destination file
error = ExtAudioFileCreateWithURL(
(__bridge CFURLRef)outputURL,
kAudioFileWAVEType,
&dstFormat,
nil,
kAudioFileFlags_EraseFile,
&destinationFile);
NSLog(@"Error 1 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
error = ExtAudioFileSetProperty(sourceFile,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat);
NSLog(@"Error 2 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
error = ExtAudioFileSetProperty(destinationFile,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat);
NSLog(@"Error 3 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
const UInt32 bufferByteSize = 32768;
UInt8 srcBuffer[bufferByteSize];// = [UInt8](repeating: 0, count: 32768)
memset(srcBuffer, 0, bufferByteSize);
unsigned long sourceFrameOffset = 0;
while(true)
{
AudioBufferList fillBufList;
fillBufList.mNumberBuffers = 1;
fillBufList.mBuffers[0].mNumberChannels = 2;
fillBufList.mBuffers[0].mDataByteSize = bufferByteSize;
fillBufList.mBuffers[0].mData = &srcBuffer;
UInt32 numFrames = 0;
if(dstFormat.mBytesPerFrame > 0){
numFrames = bufferByteSize / dstFormat.mBytesPerFrame;
}
error = ExtAudioFileRead(sourceFile, &numFrames, &fillBufList);
NSLog(@"Error 4 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
if(numFrames == 0)
{
error = noErr;
break;
}
sourceFrameOffset += numFrames;
error = ExtAudioFileWrite(destinationFile, numFrames, &fillBufList);
NSLog(@"Error 5 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
}
error = ExtAudioFileDispose(destinationFile);
NSLog(@"Error 6 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
error = ExtAudioFileDispose(sourceFile);
NSLog(@"Error 7 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
}
我只是将文件的扩展名更改为 .wav 并删除了 .m4a 文件并且它起作用了。
func getDirectory() -> URL {
let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentDirectory = path[0]
return documentDirectory
}
let date = Date().timeIntervalSince1970
fileName = getDirectory().appendingPathComponent("\(date).m4a")
wavFileName = getDirectory().appendingPathComponent("\(date).wav")
try! FileManager.default.copyItem(at: fileName, to: wavFileName)
try! FileManager.default.removeItem(at: fileName)
我什至播放了 .wav 文件,它工作正常。
audioPlayer = try! AVAudioPlayer(contentsOf: wavFileName)
audioPlayer.play()
像这样将文件扩展名从 .m4a 转换为 .wav 有什么缺点吗?
我试图在 Swift 5.
中将 m4a 转换为 Wav 格式
以上所有代码都已过时且无法正常工作。
完成一些调整后,这里是工作示例
func convertAudio(_ url: URL, outputURL: URL) {
var error : OSStatus = noErr
var destinationFile : ExtAudioFileRef? = nil
var sourceFile : ExtAudioFileRef? = nil
var srcFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
var dstFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
ExtAudioFileOpenURL(url as CFURL, &sourceFile)
var thePropertySize: UInt32 = UInt32(MemoryLayout.stride(ofValue: srcFormat))
ExtAudioFileGetProperty(sourceFile!,
kExtAudioFileProperty_FileDataFormat,
&thePropertySize, &srcFormat)
dstFormat.mSampleRate = 44100 //Set sample rate
dstFormat.mFormatID = kAudioFormatLinearPCM
dstFormat.mChannelsPerFrame = 1
dstFormat.mBitsPerChannel = 16
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame
dstFormat.mFramesPerPacket = 1
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked |
kAudioFormatFlagIsSignedInteger
// Create destination file
error = ExtAudioFileCreateWithURL(
outputURL as CFURL,
kAudioFileWAVEType,
&dstFormat,
nil,
AudioFileFlags.eraseFile.rawValue,
&destinationFile)
reportError(error: error)
error = ExtAudioFileSetProperty(sourceFile!,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat)
reportError(error: error)
error = ExtAudioFileSetProperty(destinationFile!,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat)
reportError(error: error)
let bufferByteSize : UInt32 = 32768
var srcBuffer = [UInt8](repeating: 0, count: 32768)
var sourceFrameOffset : ULONG = 0
while(true){
var fillBufList = AudioBufferList(
mNumberBuffers: 1,
mBuffers: AudioBuffer(
mNumberChannels: 2,
mDataByteSize: UInt32(srcBuffer.count),
mData: &srcBuffer
)
)
var numFrames : UInt32 = 0
if(dstFormat.mBytesPerFrame > 0){
numFrames = bufferByteSize / dstFormat.mBytesPerFrame
}
error = ExtAudioFileRead(sourceFile!, &numFrames, &fillBufList)
reportError(error: error)
if(numFrames == 0){
error = noErr;
break;
}
sourceFrameOffset += numFrames
error = ExtAudioFileWrite(destinationFile!, numFrames, &fillBufList)
reportError(error: error)
}
error = ExtAudioFileDispose(destinationFile!)
reportError(error: error)
error = ExtAudioFileDispose(sourceFile!)
reportError(error: error)
}
func reportError(error: OSStatus) {
// Handle error
print(error)
}
有人有任何代码片段可以说明如何将 M4a 文件转换为 WAV 文件吗?我知道有些库可以反过来转换。
谢谢。
AVFoundation 框架中的 AVAssetReader 和 AVAssetWriter 可用于读取 AAC 文件并将该数据作为 WAV/RIFF 文件写入 iOS 设备。 Apple 开发者网站上有示例代码。这不仅仅是一个简短的片段。
如果其他人需要一些代码来执行此操作,请在 Swift
func convertAudioFile(sourceURL: CFURLRef, destinationURL:
CFURLRef, outputFormat: OSType ,
outputSampleRate: Float64) -> OSStatus
{
var error : OSStatus = noErr
var destinationFile : ExtAudioFileRef = nil
var sourceFile : ExtAudioFileRef = nil
var srcFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
var dstFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
var audioConverter : AudioConverterRef = nil
audioConverter = AudioConverterRef.init()
ExtAudioFileOpenURL(sourceURL, &sourceFile)
var thePropertySize: UInt32 = UInt32(strideofValue(srcFormat))
ExtAudioFileGetProperty(sourceFile, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat)
dstFormat.mSampleRate = (outputSampleRate == 0 ? srcFormat.mSampleRate : outputSampleRate) //Set sample rate
dstFormat.mFormatID = outputFormat
dstFormat.mChannelsPerFrame = 1
dstFormat.mBitsPerChannel = 16
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame
dstFormat.mFramesPerPacket = 1
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger // little-endian
//Create destination file
ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, nil,
AudioFileFlags.EraseFile.rawValue, &destinationFile)
ExtAudioFileSetProperty(sourceFile, kExtAudioFileProperty_ClientDataFormat, thePropertySize, &dstFormat)
ExtAudioFileSetProperty(destinationFile, kExtAudioFileProperty_ClientDataFormat, thePropertySize, &dstFormat)
var size : UInt32 = UInt32(strideofValue(audioConverter))
ExtAudioFileGetProperty(destinationFile, kExtAudioFileProperty_AudioConverter, &size, &audioConverter)
var canResume : UInt32 = 0
size = UInt32(strideofValue(canResume))
error = AudioConverterGetProperty(audioConverter, kAudioConverterPropertyCanResumeFromInterruption, &size, &canResume)
let bufferByteSize : UInt32 = 32768
var srcBuffer = [UInt8](count: 32768, repeatedValue: 0)
var sourceFrameOffset : ULONG = 0
print("Converting audio file")
while(true){
var fillBufList = AudioBufferList(
mNumberBuffers: 1,
mBuffers: AudioBuffer(
mNumberChannels: 2,
mDataByteSize: UInt32(srcBuffer.count),
mData: &srcBuffer
)
)
var numFrames : UInt32 = 0
if(dstFormat.mBytesPerFrame > 0){
numFrames = bufferByteSize / dstFormat.mBytesPerFrame
}
ExtAudioFileRead(sourceFile, &numFrames, &fillBufList)
if(numFrames == 0){
error = noErr;
break;
}
sourceFrameOffset += numFrames
error = ExtAudioFileWrite(destinationFile, numFrames, &fillBufList)
}
ExtAudioFileDispose(destinationFile)
ExtAudioFileDispose(sourceFile)
let audioAsset = AVURLAsset.init(URL: destinationURL, options: nil)
if(audioAsset.duration.seconds < 5.0){
error = -2500
}
return error;
这是对@O2U 回答的编辑。如上代码实际上并没有将其转换为 wave 文件。请在第 //Create destination file
ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, nil,
AudioFileFlags.EraseFile.rawValue, &destinationFile)
只是为了更新 Swift 3:
func convertAudio(_ url: URL, outputURL: URL) {
var error : OSStatus = noErr
var destinationFile: ExtAudioFileRef? = nil
var sourceFile : ExtAudioFileRef? = nil
var srcFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
var dstFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
ExtAudioFileOpenURL(url as CFURL, &sourceFile)
var thePropertySize: UInt32 = UInt32(MemoryLayout.stride(ofValue: srcFormat))
ExtAudioFileGetProperty(sourceFile!,
kExtAudioFileProperty_FileDataFormat,
&thePropertySize, &srcFormat)
dstFormat.mSampleRate = 44100 //Set sample rate
dstFormat.mFormatID = kAudioFormatLinearPCM
dstFormat.mChannelsPerFrame = 1
dstFormat.mBitsPerChannel = 16
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame
dstFormat.mFramesPerPacket = 1
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked |
kAudioFormatFlagIsSignedInteger
// Create destination file
error = ExtAudioFileCreateWithURL(
outputURL as CFURL,
kAudioFileWAVEType,
&dstFormat,
nil,
AudioFileFlags.eraseFile.rawValue,
&destinationFile)
print("Error 1 in convertAudio: \(error.description)")
error = ExtAudioFileSetProperty(sourceFile!,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat)
print("Error 2 in convertAudio: \(error.description)")
error = ExtAudioFileSetProperty(destinationFile!,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat)
print("Error 3 in convertAudio: \(error.description)")
let bufferByteSize : UInt32 = 32768
var srcBuffer = [UInt8](repeating: 0, count: 32768)
var sourceFrameOffset : ULONG = 0
while(true){
var fillBufList = AudioBufferList(
mNumberBuffers: 1,
mBuffers: AudioBuffer(
mNumberChannels: 2,
mDataByteSize: UInt32(srcBuffer.count),
mData: &srcBuffer
)
)
var numFrames : UInt32 = 0
if(dstFormat.mBytesPerFrame > 0){
numFrames = bufferByteSize / dstFormat.mBytesPerFrame
}
error = ExtAudioFileRead(sourceFile!, &numFrames, &fillBufList)
print("Error 4 in convertAudio: \(error.description)")
if(numFrames == 0){
error = noErr;
break;
}
sourceFrameOffset += numFrames
error = ExtAudioFileWrite(destinationFile!, numFrames, &fillBufList)
print("Error 5 in convertAudio: \(error.description)")
}
error = ExtAudioFileDispose(destinationFile!)
print("Error 6 in convertAudio: \(error.description)")
error = ExtAudioFileDispose(sourceFile!)
print("Error 7 in convertAudio: \(error.description)")
}
这是 MSCottWaller Swift 3 回答的 Objective-C 版本。您需要@import AudioToolbox。
-(void) convertAudio:(NSURL*)url outputURL:(NSURL*)outputURL
{
OSStatus error = noErr;
ExtAudioFileRef destinationFile = nil;
ExtAudioFileRef sourceFile = nil;
AudioStreamBasicDescription srcFormat;
AudioStreamBasicDescription dstFormat;
ExtAudioFileOpenURL((__bridge CFURLRef)url, &sourceFile);
UInt32 thePropertySize = sizeof(srcFormat); //UInt32(MemoryLayout.stride(ofValue: srcFormat));;
ExtAudioFileGetProperty(sourceFile, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &srcFormat);
dstFormat.mSampleRate = 44100; //Set sample rate
dstFormat.mFormatID = kAudioFormatLinearPCM;
dstFormat.mChannelsPerFrame = 1;
dstFormat.mBitsPerChannel = 16;
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame;
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame;
dstFormat.mFramesPerPacket = 1;
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
// Create destination file
error = ExtAudioFileCreateWithURL(
(__bridge CFURLRef)outputURL,
kAudioFileWAVEType,
&dstFormat,
nil,
kAudioFileFlags_EraseFile,
&destinationFile);
NSLog(@"Error 1 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
error = ExtAudioFileSetProperty(sourceFile,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat);
NSLog(@"Error 2 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
error = ExtAudioFileSetProperty(destinationFile,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat);
NSLog(@"Error 3 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
const UInt32 bufferByteSize = 32768;
UInt8 srcBuffer[bufferByteSize];// = [UInt8](repeating: 0, count: 32768)
memset(srcBuffer, 0, bufferByteSize);
unsigned long sourceFrameOffset = 0;
while(true)
{
AudioBufferList fillBufList;
fillBufList.mNumberBuffers = 1;
fillBufList.mBuffers[0].mNumberChannels = 2;
fillBufList.mBuffers[0].mDataByteSize = bufferByteSize;
fillBufList.mBuffers[0].mData = &srcBuffer;
UInt32 numFrames = 0;
if(dstFormat.mBytesPerFrame > 0){
numFrames = bufferByteSize / dstFormat.mBytesPerFrame;
}
error = ExtAudioFileRead(sourceFile, &numFrames, &fillBufList);
NSLog(@"Error 4 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
if(numFrames == 0)
{
error = noErr;
break;
}
sourceFrameOffset += numFrames;
error = ExtAudioFileWrite(destinationFile, numFrames, &fillBufList);
NSLog(@"Error 5 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
}
error = ExtAudioFileDispose(destinationFile);
NSLog(@"Error 6 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
error = ExtAudioFileDispose(sourceFile);
NSLog(@"Error 7 in convertAudio: %d - %@", error, [NSError errorWithDomain:NSOSStatusErrorDomain code:error userInfo:nil].description);
}
我只是将文件的扩展名更改为 .wav 并删除了 .m4a 文件并且它起作用了。
func getDirectory() -> URL {
let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentDirectory = path[0]
return documentDirectory
}
let date = Date().timeIntervalSince1970
fileName = getDirectory().appendingPathComponent("\(date).m4a")
wavFileName = getDirectory().appendingPathComponent("\(date).wav")
try! FileManager.default.copyItem(at: fileName, to: wavFileName)
try! FileManager.default.removeItem(at: fileName)
我什至播放了 .wav 文件,它工作正常。
audioPlayer = try! AVAudioPlayer(contentsOf: wavFileName)
audioPlayer.play()
像这样将文件扩展名从 .m4a 转换为 .wav 有什么缺点吗?
我试图在 Swift 5.
中将 m4a 转换为 Wav 格式以上所有代码都已过时且无法正常工作。 完成一些调整后,这里是工作示例
func convertAudio(_ url: URL, outputURL: URL) {
var error : OSStatus = noErr
var destinationFile : ExtAudioFileRef? = nil
var sourceFile : ExtAudioFileRef? = nil
var srcFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
var dstFormat : AudioStreamBasicDescription = AudioStreamBasicDescription()
ExtAudioFileOpenURL(url as CFURL, &sourceFile)
var thePropertySize: UInt32 = UInt32(MemoryLayout.stride(ofValue: srcFormat))
ExtAudioFileGetProperty(sourceFile!,
kExtAudioFileProperty_FileDataFormat,
&thePropertySize, &srcFormat)
dstFormat.mSampleRate = 44100 //Set sample rate
dstFormat.mFormatID = kAudioFormatLinearPCM
dstFormat.mChannelsPerFrame = 1
dstFormat.mBitsPerChannel = 16
dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame
dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame
dstFormat.mFramesPerPacket = 1
dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked |
kAudioFormatFlagIsSignedInteger
// Create destination file
error = ExtAudioFileCreateWithURL(
outputURL as CFURL,
kAudioFileWAVEType,
&dstFormat,
nil,
AudioFileFlags.eraseFile.rawValue,
&destinationFile)
reportError(error: error)
error = ExtAudioFileSetProperty(sourceFile!,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat)
reportError(error: error)
error = ExtAudioFileSetProperty(destinationFile!,
kExtAudioFileProperty_ClientDataFormat,
thePropertySize,
&dstFormat)
reportError(error: error)
let bufferByteSize : UInt32 = 32768
var srcBuffer = [UInt8](repeating: 0, count: 32768)
var sourceFrameOffset : ULONG = 0
while(true){
var fillBufList = AudioBufferList(
mNumberBuffers: 1,
mBuffers: AudioBuffer(
mNumberChannels: 2,
mDataByteSize: UInt32(srcBuffer.count),
mData: &srcBuffer
)
)
var numFrames : UInt32 = 0
if(dstFormat.mBytesPerFrame > 0){
numFrames = bufferByteSize / dstFormat.mBytesPerFrame
}
error = ExtAudioFileRead(sourceFile!, &numFrames, &fillBufList)
reportError(error: error)
if(numFrames == 0){
error = noErr;
break;
}
sourceFrameOffset += numFrames
error = ExtAudioFileWrite(destinationFile!, numFrames, &fillBufList)
reportError(error: error)
}
error = ExtAudioFileDispose(destinationFile!)
reportError(error: error)
error = ExtAudioFileDispose(sourceFile!)
reportError(error: error)
}
func reportError(error: OSStatus) {
// Handle error
print(error)
}