iPhone 扩展音频文件服务,mp3 -> PCM -> mp3

2024-02-24

我想使用 Core Audio 扩展音频文件服务框架来读取 mp3 文件,将其作为 PCM 进行处理,然后将修改后的文件作为 mp3 文件写回。我能够将 mp3 文件转换为 PCM,但无法将 PCM 文件作为 mp3 写回。

我已经跟踪并分析了 Apple ExtAudioFileConvertTest 示例,但也无法使其正常工作。故障点是当我设置输出文件的客户端格式(设置为规范的 PCM 类型)时。此操作失败并出现错误“fmt?”如果输出目标类型设置为 mp3。

是否可以在 iPhone 上执行 mp3 -> PCM -> mp3?如果我删除失败的行,为输出文件设置 kExtAudioFileProperty_ClientDataFormat,则代码会失败并显示“pkd?”当我稍后尝试写入输出文件时。所以基本上我有两个错误:

1)“fmt?”尝试为输出文件设置 kExtAudioFileProperty_ClientDataFormat 时

2)“PKD?”当尝试写入输出文件时

这是设置文件的代码:

NSURL *fileUrl = [NSURL fileURLWithPath:sourceFilePath];
OSStatus error = noErr;

//
// Open the file
//
error = ExtAudioFileOpenURL((CFURLRef)fileUrl, &sourceFile);

if(error){
    NSLog(@"AudioClip: Error opening file at %@.  Error code %d", sourceFilePath, error);
    return NO;
}

//
// Store the number of frames in the file
//
SInt64 numberOfFrames = 0;
UInt32 propSize = sizeof(SInt64);
error = ExtAudioFileGetProperty(sourceFile, kExtAudioFileProperty_FileLengthFrames, &propSize, &numberOfFrames);

if(error){
    NSLog(@"AudioClip: Error retreiving number of frames: %d", error);
    [self closeAudioFile];
    return NO;
}

frameCount = numberOfFrames;

//
// Get the source file format info
//
propSize = sizeof(sourceFileFormat);
memset(&sourceFileFormat, 0, sizeof(AudioStreamBasicDescription));

error = ExtAudioFileGetProperty(sourceFile, kExtAudioFileProperty_FileDataFormat, &propSize, &sourceFileFormat);

if(error){
    NSLog(@"AudioClip: Error getting source audio file properties: %d", error);
    [self closeAudioFile];
    return NO;
}

//
// Set the format for our read.  We read in PCM, clip, then write out mp3
//
memset(&readFileFormat, 0, sizeof(AudioStreamBasicDescription));

readFileFormat.mFormatID            = kAudioFormatLinearPCM;
readFileFormat.mSampleRate          = 44100;
readFileFormat.mFormatFlags         = kAudioFormatFlagsCanonical | kAudioFormatFlagIsNonInterleaved;
readFileFormat.mChannelsPerFrame    = 1;
readFileFormat.mBitsPerChannel      = 8 * sizeof(AudioSampleType);
readFileFormat.mFramesPerPacket     = 1;
readFileFormat.mBytesPerFrame       = sizeof(AudioSampleType);
readFileFormat.mBytesPerPacket      = sizeof(AudioSampleType);
readFileFormat.mReserved            = 0;

propSize = sizeof(readFileFormat);
error = ExtAudioFileSetProperty(sourceFile, kExtAudioFileProperty_ClientDataFormat, propSize, &readFileFormat);

if(error){
    NSLog(@"AudioClip: Error setting read format: %d", error);
    [self closeAudioFile];
    return NO;
}

//
// Set the format for the output file that we will write
//
propSize = sizeof(targetFileFormat);
memset(&targetFileFormat, 0, sizeof(AudioStreamBasicDescription));

targetFileFormat.mFormatID          = kAudioFormatMPEGLayer3;
targetFileFormat.mChannelsPerFrame  = 1;

//
// Let the API fill in the rest
//
error = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &propSize, &targetFileFormat);

if(error){
    NSLog(@"AudioClip: Error getting target file format info: %d", error);
    [self closeAudioFile];
    return NO;
}

//
// Create our target file
//
NSURL *writeURL = [NSURL fileURLWithPath:targetFilePath];

error = ExtAudioFileCreateWithURL( (CFURLRef)writeURL, kAudioFileMP3Type, 
                                  &targetFileFormat, NULL,
                                  kAudioFileFlags_EraseFile, 
                                  &targetFile);

if(error){
    NSLog(@"AudioClip: Error opening target file for writing: %d", error);
    [self closeAudioFile];
    return NO;
}


//
// Set the client format for the output file the same as our client format for the input file
//
propSize = sizeof(readFileFormat);
error = ExtAudioFileSetProperty(targetFile, kExtAudioFileProperty_ClientDataFormat, propSize, &readFileFormat);

if(error){
    NSLog(@"AudioClip: Error, cannot set client format for output file: %d", error);
    [self closeAudioFile];
    return NO;
}

以及读取/写入的代码:

NSInteger framesToRead = finalFrameNumber - startFrameNumber;

while(framesToRead > 0){
    //
    // Read frames into our data
    //
    short *data = (short *)malloc(framesToRead * sizeof(short));
    if(!data){
        NSLog(@"AudioPlayer: Cannot init memory for read buffer");
        [self notifyDelegateFailure];
        [self closeAudioFile];
        return;
    }

    AudioBufferList bufferList;
    OSStatus error = noErr;
    UInt32 loadedPackets = framesToRead;

    bufferList.mNumberBuffers = 1;
    bufferList.mBuffers[0].mNumberChannels = 1;
    bufferList.mBuffers[0].mData = data;
    bufferList.mBuffers[0].mDataByteSize = (framesToRead * sizeof(short));

    NSLog(@"AudioClip: Before read nNumberBuffers = %d, mNumberChannels = %d, mData = %p, mDataByteSize = %d",
          bufferList.mNumberBuffers, bufferList.mBuffers[0].mNumberChannels, bufferList.mBuffers[0].mData,
          bufferList.mBuffers[0].mDataByteSize);

    error = ExtAudioFileRead(sourceFile, &loadedPackets, &bufferList);

    if(error){
        NSLog(@"AudioClip: Error %d from ExtAudioFileRead", error);
        [self notifyDelegateFailure];
        [self closeAudioFile];
        return;
    }

    //
    // Now write the data to our file which will convert it into a mp3 file
    //

    NSLog(@"AudioClip: After read nNumberBuffers = %d, mNumberChannels = %d, mData = %p, mDataByteSize = %d",
          bufferList.mNumberBuffers, bufferList.mBuffers[0].mNumberChannels, bufferList.mBuffers[0].mData,
          bufferList.mBuffers[0].mDataByteSize);

    error = ExtAudioFileWrite(targetFile, loadedPackets, &bufferList);

    if(error){
        NSLog(@"AudioClip: Error %d from ExtAudioFileWrite", error);
        [self notifyDelegateFailure];
        [self closeAudioFile];
        return;
    }

    framesToRead -= loadedPackets;
}

Apple 不提供 MP3 编码器,仅提供解码器。源文档有点过时,但据我所知它仍然是最新的:http://developer.apple.com/library/ios/#documentation/MusicAudio/Conceptual/CoreAudioOverview/SupportedAudioFormatsMacOSX/SupportedAudioFormatsMacOSX.html%23//apple_ref/doc/uid/TP40003577-CH7-SW1 http://developer.apple.com/library/ios/#documentation/MusicAudio/Conceptual/CoreAudioOverview/SupportedAudioFormatsMacOSX/SupportedAudioFormatsMacOSX.html%23//apple_ref/doc/uid/TP40003577-CH7-SW1

我认为你最好的选择可能是使用 AAC。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iPhone 扩展音频文件服务,mp3 -> PCM -> mp3 的相关文章

  • 在代码中创建时 UISearchDisplayController 不工作?

    我正在开发一个选项卡栏应用程序 其中一个选项卡有一个连接到 UISearchBar 的 UISearchDisplayController 所有这些都已连接到 NIB 中并且正在工作 当我点击搜索栏时 范围 和 取消 按钮会飞入等 并且搜索
  • 如何在 Objective-C 中运行时查找字符串常量?

    我的公司开发了一个广告 SDK 可以协调其他广告网络 在运行时 它通过使用检查其他广告网络是否存在NSClassFromString 并发送这些类消息 如果存在 这对于 Objective C 对象来说效果很好 但是如何在运行时加载字符串常
  • 我们可以在 Tiff 文件中添加自定义键或如何在 Tiff 文件的图像属性中添加温度数据

    我想在选定点添加图像的温度数据 它是否有任何预定义的属性 或者我们是否可以在 Tiff 文件中创建自定义 私钥来存储图像的温度数据 Answer 使用 TIFF 库文档在 TIFF 文件中创建您自己的自定义键 在文档中 他提到了如何创建和使
  • iOS 中tableview 的动态搜索

    I ve a tableview和我实现搜索方法的文本字段 现在 当我在其中写入一些值时textfield然后点击搜索按钮 然后在tableview 但是 我希望它是动态的 意味着我开始输入的那一刻textfield它应该开始搜索而不点击任
  • 如何在 Xcode 中找到特定函数(如 eclipse 的调用层次结构)的所有调用函数?

    我如何在 XCode 中找到特定函数的所有调用函数 例如 eclipse 的调用层次结构 自 XCode 4 4 发布以来 此功能就存在并称为 显示相关项目 有多种方法可以访问弹出菜单 使您可以查看所有呼叫者和被呼叫者等 最快的方法是 在代
  • 错误:Phonegap 中的白名单拒绝

    我是移动开发新手 我正在使用 Phonegap Cordova 创建跨平台应用程序 我的代码在 Android 上运行良好 但当我将其移植到 iPhone 时 它 显示错误 143 2003 ERROR whitelist rejectio
  • 如何解决 Xcode 7 中的 No Type or Protocol Named 错误?

    我试图passing从第二个开始的值class我正在使用的头等舱protocol and delegate过程 每当我运行我的程序时 我都会遇到以下问题 No Type or Protocol Named locateMeDelegate
  • 添加新行后,UITableView rollToRow 不再适用于 iOS 11

    我注意到一个奇怪的 UITableView 行为似乎只发生在 iOS 11 设备上 插入新行后 更改数据源然后调用 reloadData UITableView调用时不会滚动到该行scrollToRow or scrollToBottom
  • UITableView 滚动缓慢

    编辑 我在英语记录上做了相同的代码 滚动速度仍然像往常一样快 并且工作正常 但是当我获取阿拉伯语数据时 滚动又变慢了 这是阿拉伯数据的问题吗 我有大约 100 条记录 我的 tableview 滚动非常慢 谁能告诉我这段代码有什么问题 为什
  • NSString 到 Double 问题

    可能很简单 但我不明白 我有一个 NSString50 81114我想把它转换成双 目前我正在使用 string doubleValue 但这是作为50 811140000002这是怎么回事 Disco 由于精度有限double无法存储50
  • NSData initWithBytesNoCopy:length:freeWhenDone 的行为:

    我想要一个固定长度的可变内容共享数据缓冲区 这就是我如何创建它 void buffer malloc length initialize buffer content NSData sharedData NSData alloc initW
  • 如何通过 HTTP POST 发送充满对象的 NSArray?

    我在 iPhone 端有一个产品 购物清单 由具有名称 product id 等的产品对象组成 我希望将此列表发送到服务器 在那里我将服务器上的列表与 iphone 中的列表进行比较 以合并所做的更改并将合并的列表发送回 iphone 如何
  • iPhone SDK-从我的应用程序中启动 youtube 应用程序

    我正在开发一个使用 UIWebView 来显示 youtube 视频列表的应用程序 为了播放视频 我使用 YouTube 嵌入功能 当用户单击视频缩略图时它会打开 YouTube 应用程序 效果很好 我希望当我单击网页视图上 YouTube
  • 有人知道如何在android中实现像Unfold(这是iphone中的应用程序)这样的效果吗?

    我怎样才能实现这个效果呢 任何建议都会对我有帮助 None
  • 删除 GameCenter 排行榜 - iTunes Connect

    我的游戏目前有四个不同难度的排行榜 但是这将在新的更新中改变 我不再想使用所有这些 而只想使用其中之一 如何将新版本设置为仅使用这个新排行榜并隐藏其他排行榜 以便用户看不到它们 Thanks 根据 iTunes Connect 的数据 一旦
  • ASIHTTP:上传 UIImage?

    有人可以告诉我如何在 Objective c 中使用 ASIHTTPRequest 对象上传 UIImage 对象吗 我需要将其转换为 NSData 对象吗 这是头像上传网址 E g UIImage toUpload UIImage ima
  • 获取实体中某个值的最大值

    我正在尝试获取核心数据中实体中属性的最大值 苹果有一个很好的例子here http developer apple com library mac documentation Cocoa Conceptual CoreData Articl
  • 显示来自 weburl iphone sdk 的 pdf

    我正在开发一个项目 我想显示网站上的 pdf 我有 pdf 的 url 知道如何做到这一点 我还想创建网站上 pdf 的缩略图 您可以在您的设备中显示 pdf 文件 直接将 url 传递给 UIWebView UIWebView webVi
  • 在 iOS 7 中创建 UUID 和 UDID

    我想创建 UUID 我下面有可以创建 UUID 的代码 如何在 iOS7 中创建具有多个供应商相同 ID 的 UDID NSString stringWithNewUUID CFUUIDRef uuidObj CFUUIDCreate ni
  • 使用其他应用程序打开 pdf

    我正在应用程序中显示 pdf 文件 我想在 nag bar 上显示 打开方式 选项 显示 iPhone 上安装的可以打开相同 pdf 的应用程序 如果用户选择任何应用程序 例如 pdf 查看器 则应该使用 pdf 查看器应用程序打开 pdf

随机推荐

  • C 中标量类型和聚合类型有什么区别?

    我读过一本书 叫 Pointers On C 在那本书中 有一种类型称为标量类型 我知道算术类型和指针类型统称为标量类型 但我想知道标量类型和聚合类型有什么区别以及什么场合使用它们 C11 6 2 5 类型 p21 Arithmetic t
  • 禁用 UITextField 的简单方法?

    有没有一种简单的方法来禁用UITextField在代码中 我的应用程序有 12 个UITextField默认情况下都是打开的 但是当我的段控制中检测到更改时 我想禁用一些UITextField取决于用户选择的细分 只需知道如何禁用它或使其不
  • Flutter:没有为该类型定义 getter

    我被页面路由困住了 这是 main dart 中的代码 import package test routes router gr dart import package flutter material dart import packag
  • 删除 Android 导航和顶部栏,

    我正在尝试在已取得 root 权限的 Android 设备上实现 Kiosk 应用程序 并且我需要完全禁用导航和状态栏 这些命令在 adb shell 中工作 禁用 service call activity 42 s16 com andr
  • 获取android中已安装的应用程序列表

    我正在尝试为 Android 开发一个应用程序启动器应用程序 我刚开始 但这里有一个问题 如何获取 Android 中所有已安装应用程序的列表 在您的活动中使用这些方法来获取已安装应用程序的列表 private ArrayList
  • 为什么 JavaScript: new Date(year, Month, 0).getDate() 返回该月的天数?

    我知道这个小小的 JavaScript 代码 var whatever new Date year month 0 getDate 返回特定年份的特定月份的天数 但我似乎不明白其背后的逻辑 在我们提到年份和月份之后 那个零到底在做什么 请解
  • Ruby on Rails 移动应用程序

    我正在尝试开发一个 Ruby on Rails 应用程序 它将检测客户端 即连接到服务器的移动设备 浏览器 并呈现适当的布局 我尝试使用以下链接 但仍然无法连接 有什么建议 http www arctickiwi com blog mobi
  • 我如何在 spring security acl 中检查我的对象权限而不是使用 hasPermission 注释

    有没有办法直接从我的代码检查我的类对象权限 而不是使用注释模型 PostAuthorize hasPermission returnObject WRITE public BaseData getSingle Long id 假设您打算使用
  • CLOB 中是否保留转义序列?

    我们使用Java和Oracle进行开发 我在 Oracle 数据库中有一个表 其中有一个 CLOB 列 某些 XYZ 应用程序会在此列中转储文本文件 文本文件有多行 通过 Java 应用程序读取相同的 CLOB 文件时 转义序列 换行符等
  • 创建视图实例时 Backbone.js 不是构造函数错误

    我是backbone js 的新用户 正在测试如何使用它 最近几天我正在测试如何使用路由通过集合更改视图数据 在当前情况下 我遇到了一个问题 当我尝试在 router js 中创建 ScheduleView 实例时 控制台会记录以下错误消息
  • 为什么 Docker 服务停止了?

    我将 Ubuntu 作为 Windows 10 上的子系统运行 我刚刚按照以下步骤在 Linux 上安装 Docker https docs docker com install linux docker ce ubuntu https d
  • Cucumber 运行程序类的 Intellij IDEA 运行配置

    我是 Intellij IDEA 的新手 我有一个基于 POM 的 cucumber selenium 项目 我在其中为每个功能文件创建了 cucumber runner 类 在使用 Eclipse 时 我能够通过右键单击来执行这些运行程序
  • MySQL Git Bash winpty mysqldump stdout 不是 tty 并且 stdin 不是 tty

    请帮助使用 MySQL Git Bash winpty mysqldump winpty mysqldump 在 Git Bash 中不起作用 这里是错误的详细信息 Git Bash winpty mysqldump u root p em
  • Python for 循环变慢并最终挂起

    我对 Python 完全陌生 截至半小时前 并尝试编写一个简单的脚本来枚举 SMTP 服务器上的用户 用户文件是一个简单的用户名列表 每行一个 该脚本运行良好 但随着循环的每次迭代 它都会变慢 直到循环 14 左右 它似乎完全挂起 没有错误
  • 使用Python(smtplib)发送邮件时指定发件人

    我有一段非常简单的代码 仅用于测试 import smtplib import time server smtp myprovider com recipients email protected cdn cgi l email prote
  • 如果使用 == 的语句给出了意外的结果[重复]

    这个问题在这里已经有答案了 private void refineWords for String word words Log i word word if word s word t word am word is word are w
  • 抽象工厂、工厂方法、构建器

    看起来这个问题似乎是一个骗局 但请耐心等待 我保证我已经阅读了相关帖子 以及GOF book https rads stackoverflow com amzn click com 0201633612 在读完所有内容后 我仍然不清楚何时使
  • node.js socket.io 如何发送到特定客户端?

    我想向特定客户端 发出 一条消息 该消息是根据不同客户端中收到的另一条消息而选择的 我该如何执行此操作 我正在考虑将每个客户加入他们自己的 房间 然后进行广播 有没有更好的办法 socket io 1 0 及以上版本的更新 io to so
  • 如何运行多个异步函数然后执行回调?

    在我的 Node js 代码中 我需要进行 2 或 3 个 API 调用 每个调用都会返回一些数据 所有 API 调用完成后 我想将所有数据收集到一个 JSON 对象中以发送到前端 我知道如何使用 API 回调来执行此操作 下一个调用将在上
  • iPhone 扩展音频文件服务,mp3 -> PCM -> mp3

    我想使用 Core Audio 扩展音频文件服务框架来读取 mp3 文件 将其作为 PCM 进行处理 然后将修改后的文件作为 mp3 文件写回 我能够将 mp3 文件转换为 PCM 但无法将 PCM 文件作为 mp3 写回 我已经跟踪并分析