如何在 iOS Swift 中为 CMSampleBufferGetFormatDescription 创建一个AudioSampleBuffer

2024-03-10

我一直致力于 iOS Swift 中的视频压缩,并关注this https://stackoverflow.com/a/52346800/9250384所以的答案。它工作正常,直到我将这段代码的文件格式更改为.mp4

    let videoWriter = try! AVAssetWriter(outputURL: outputURL as URL, fileType: AVFileType.mov)

我需要输出是有原因的.mp4文件格式。所以当我这样做时,应用程序就会崩溃。并给我这个错误,

2020-04-27 18:20:52.573614+0500 BrightCaster[7847:1513728] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVAssetWriter addInput:] In order to perform passthrough to file type public.mpeg-4, please provide a format hint in the AVAssetWriterInput initializer'
*** First throw call stack:
(0x1b331d5f0 0x1b303fbcc 0x1bd53b2b0 0x102383c0c 0x102382164 0x1021897cc 0x1b6ca73bc 0x1b6caba7c 0x1b6daec94 0x1b7835080 0x1b7834d30 0x1e9d077b4 0x1b786a764 0x1b783eb68 0x1b783f070 0x1e9d468f4 0x1b783f1c0 0x1e9d468f4 0x1b9e21d9c 0x105173730 0x105181710 0x1b329b748 0x1b329661c 0x1b3295c34 0x1bd3df38c 0x1b73c822c 0x10230f8a0 0x1b311d800)
libc++abi.dylib: terminating with uncaught exception of type NSException

所以我搜索了SO并发现this https://stackoverflow.com/q/45539990/9250384与我的问题相关的问题。 但现在的问题是当我尝试添加它时answer https://stackoverflow.com/a/55073239/9250384对于我的函数,它给了我错误anAudioSampleBuffer 未定义。由于我对音频/视频领域完全陌生,我无法理解为什么它给了我这个。以及如何解决这个问题。 我在函数中添加的答案中的代码如下。

    //setup audio writer
    //let formatDesc = CMSampleBufferGetFormatDescription(anAudioSampleBuffer)
    //let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil, sourceFormatHint: formatDesc)
    let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil)
    audioWriterInput.expectsMediaDataInRealTime = false
    videoWriter.add(audioWriterInput)

评论部分不起作用。任何帮助将不胜感激谢谢。

整个转换函数如下

func convertVideoToLowQuailtyWithInputURL(inputURL: URL, outputURL: URL, completion: @escaping (Bool , _ url: String) -> Void) {

    let videoAsset = AVURLAsset(url: inputURL as URL, options: nil)
    let videoTrack = videoAsset.tracks(withMediaType: AVMediaType.video)[0]
    let videoSize = videoTrack.naturalSize
    let videoWriterCompressionSettings = [
        AVVideoAverageBitRateKey : Int(125000)
    ]

    let videoWriterSettings:[String : AnyObject] = [
        AVVideoCodecKey : AVVideoCodecH264 as AnyObject,
        AVVideoCompressionPropertiesKey : videoWriterCompressionSettings as AnyObject,
        AVVideoWidthKey : Int(videoSize.width) as AnyObject,
        AVVideoHeightKey : Int(videoSize.height) as AnyObject
    ]

    let videoWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoWriterSettings)
    videoWriterInput.expectsMediaDataInRealTime = true
    videoWriterInput.transform = videoTrack.preferredTransform
    let videoWriter = try! AVAssetWriter(outputURL: outputURL as URL, fileType: AVFileType.mov) // for now its converting in .mov I THINK SO.
    videoWriter.add(videoWriterInput)



    //setup video reader
    let videoReaderSettings:[String : AnyObject] = [
        kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) as AnyObject
    ]

    let videoReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings)
    var videoReader: AVAssetReader!

    do{

        videoReader = try AVAssetReader(asset: videoAsset)
    }
    catch {

        print("video reader error: \(error)")
        completion(false, "")
    }
    videoReader.add(videoReaderOutput)


    //setup audio writer
    //let formatDesc = CMSampleBufferGetFormatDescription(anAudioSampleBuffer) // this is giving me error here of un initilize, which I didn't I know.
    //let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil, sourceFormatHint: formatDesc)
    let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil)
    audioWriterInput.expectsMediaDataInRealTime = false
    videoWriter.add(audioWriterInput)
    //setup audio reader
    let audioTrack = videoAsset.tracks(withMediaType: AVMediaType.audio)[0]
    let audioReaderOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: nil)
    let audioReader = try! AVAssetReader(asset: videoAsset)
    audioReader.add(audioReaderOutput)
    videoWriter.startWriting()



    //start writing from video reader
    videoReader.startReading()
    videoWriter.startSession(atSourceTime: CMTime.zero)
    let processingQueue = DispatchQueue(label: "processingQueue1")
    videoWriterInput.requestMediaDataWhenReady(on: processingQueue, using: {() -> Void in
        while videoWriterInput.isReadyForMoreMediaData {
            let sampleBuffer:CMSampleBuffer? = videoReaderOutput.copyNextSampleBuffer();
            if videoReader.status == .reading && sampleBuffer != nil {
                videoWriterInput.append(sampleBuffer!)
            }
            else {
                videoWriterInput.markAsFinished()
                if videoReader.status == .completed {
                    //start writing from audio reader
                    audioReader.startReading()
                    videoWriter.startSession(atSourceTime: CMTime.zero)
                    let processingQueue = DispatchQueue(label: "processingQueue2")
                    audioWriterInput.requestMediaDataWhenReady(on: processingQueue, using: {() -> Void in
                        while audioWriterInput.isReadyForMoreMediaData {
                            let sampleBuffer:CMSampleBuffer? = audioReaderOutput.copyNextSampleBuffer()
                            if audioReader.status == .reading && sampleBuffer != nil {
                                audioWriterInput.append(sampleBuffer!)
                            }
                            else {
                                audioWriterInput.markAsFinished()
                                if audioReader.status == .completed {
                                    videoWriter.finishWriting(completionHandler: {() -> Void in
                                        completion(true, "\(videoWriter.outputURL)")
                                    })
                                }
                            }
                        }
                    })
                }
            }
        }
    })
}

您可以输出为 mp4,通过提供格式提示来传递音频(无转码),如下所示:

let audioTrack = videoAsset.tracks(withMediaType: AVMediaType.audio)[0]
let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil, sourceFormatHint: audioTrack.formatDescriptions[0] as! CMFormatDescription)

注意新位置audioTrack定义。

我想象苹果的.mov and .mp4实现需要知道压缩音频格式才能写入文件,但我想.mov可以在初始化后推断该信息,其中.mp4不是。也许是另一个AVFoundation Surprise!.

在您的情况下,我发现重新编写代码以从第一个样本缓冲区获取音频格式会很烦人,但后来我记得该格式可以从输入音轨中获得。

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

如何在 iOS Swift 中为 CMSampleBufferGetFormatDescription 创建一个AudioSampleBuffer 的相关文章

  • SwiftUI 检测用户何时截取屏幕截图或屏幕录制

    On UIViewController我们可以轻松地将观察者添加到控制器 喜欢 class ViewController UIViewController override func viewDidLoad super viewDidLoa
  • Swift 结构类型集

    说我有一个struct 可以是任何东西 struct Cube var x Int var y Int var z Int var width Int 然后我该如何创建一个Set这些点中 是否存在两个具有相同属性的对象 let points
  • 从软件查找服务返回无效结果

    我尝试通过 XCode 组织者提交 iOS 应用程序 但在身份验证后失败 组织者说 从软件查找服务返回的结果无效 我怎么解决这个问题 检查 iTunes Connect 中您的应用程序状态是否为 等待上传 您可以更改状态以按 准备上传二进制
  • 如何在 UITextView 中禁用放大功能

    我想摆脱 UITextView 中的放大和文本选择 但我需要电话号码 链接和地址检测器 我在用 void addGestureRecognizer UIGestureRecognizer gestureRecognizer if gestu
  • Draggable Boxview 不更新 Xamarin

    我的第一个问题是框视图生成在左上角 而不是我指定的设计网格第 10 行和网格第 3 列 第二个问题在于可拖动视图 在代码本地可拖动视图的第一部分中 它正确地调用了触摸事件 但也许它没有在GUI中更新
  • 与自定义键盘扩展进行通信,主机应用程序无法在设备中运行,但可以在模拟器中运行

    我正在使用自定义键盘扩展 这几乎完成了 但当我与扩展和我的主机应用程序通信数据时 我只是面临设备问题 该应用程序在设备中没有工作 但在模拟器中工作也是如此 我的代码如下 HostApp 视图控制器 void viewDidLoad defa
  • 定位精度定义 - iOS

    iOS 上返回的 准确性 或 不确定性 的统计意图是什么 即使是近似值 例如 Android 文档对其返回的精度数字进行了解释 从这个意义上讲 它大约是一个标准差 我们将准确度定义为 68 置信度的半径 换句话说 如果 您以该位置的纬度和经
  • 添加 AFNetworking 后出现 APPLE MACH-O 链接错误

    只是将 AFNetworking 添加到我的项目中 在 B R 后 我收到如下错误 Undefined symbols for architecture i386 SecCertificateCopyData referenced from
  • Swift 1.2 可选外部变量?

    由于 Swift 无法访问编译变量 因此我创建了一个指向编译变量的 Objective C extern 变量 编译变量转换器 h extern NSString const NetworkApiBasicAuthUsername 编译变量
  • “EXC_BAD_ACCESS”与“分段错误”。两者实际上相同吗?

    在我的前几个虚拟应用程序 用于学习时练习 中 我遇到了很多EXC BAD ACCESS 这以某种方式告诉我错误访问是 您正在触摸 访问一个不应该的对象 因为它尚未分配或释放 或者只是您无权访问它 查看此示例代码 该代码存在访问错误问题 因为
  • iOS - 在 UITabBar 上方获取所需的阴影

    我试图让我的标签栏阴影看起来像这张图片中看到的那样 这样做的最佳方法是什么 我正在使用 Objective C Thanks 您可以使用以下代码为任何 UI 对象提供阴影 tabBar layer shadowOffset CGSize w
  • Xcode 11 - 在 Catalyst Swift 中禁用调整大小模式

    We are 将我们基于 Swift 的 iOS 应用程序转换为 Mac兼容使用Catalyst在 Xcode 11 中 当用户使用时 我们在 UI 中面临一个问题resize应用程序窗口 那么我们可以禁用调整大小模式并为应用程序窗口提供修
  • 在 iOS Safari 上滚动后锚点失去点击能力

    使用它来获取点击次数 nav li a click function event event preventDefault target this attr href replace goToByScroll target 这是滚动功能 f
  • 是否可以对 UILabel 的文本颜色变化进行动画处理? [复制]

    这个问题在这里已经有答案了 UIView animateWithDuration 5 animations myLabel textColor UIColor redColor 标签文本颜色立即改变 Try this UIView tran
  • 在 Safari 中快速打开链接

    我目前正在我的应用程序中打开链接WebView 但我正在寻找一个打开链接的选项Safari反而 它不是 融入 Swift 但你可以使用标准UIKit方法来做到这一点 看看 UIApplication 的openUrl https devel
  • 如何设置 UINavigationbar 的渐变颜色?

    我想设置UINavigationbar backgroundColor渐变颜色 我想通过颜色数组设置它以创建渐变 理想情况下 作为内部的可访问方法UINavigationBar将其颜色更改为此渐变 有什么建议么 除了手动设置图像作为导航栏的
  • UIView 周围的虚线边框

    如何在周围添加虚线边框UIView 像这样的东西 如果您喜欢子层 还有另一种方法 在您的自定义视图的 init 中 输入以下内容 border 是 ivar border CAShapeLayer layer border strokeCo
  • 在后台继续下载

    我正在创建一个应用程序 其中我从服务器下载一些数据 在后台运行时 我希望连接继续运行 以便可以下载数据 我知道有方法应用程序委托 void applicationDidEnterBackground UIApplication applic
  • 如何将NSTextView的格式化内容转换为字符串

    我需要将 NSTextView 的内容从 Mac 应用程序传输到 iOS 应用程序 我使用 XML 作为传输文件格式 所以我需要将 NSTextView 的内容 文本 字体 颜色等 保存为字符串 有什么办法可以做到这一点吗 一种方法是存档
  • 使用自定义格式将字符串转换为 NSDate [重复]

    这个问题在这里已经有答案了 可能的重复 NSString 到 NSDate https stackoverflow com questions 1353081 nsstring to nsdate iPhone 如何将 yyyyMMddTh

随机推荐

  • 解析值时遇到意外字符错误:。路径 '',第 1 行,位置 1

    我有一个 ASP Net Core 2 1 应用程序 我遇到了与下面的链接中提到的相同的错误 解析值时遇到意外字符 路径 第 1 行 位置 1 https stackoverflow com questions 57678571 unexp
  • 当手势应用于 self.view 时,我们如何才能使表格视图工作?

    我已经在整个视图上应用了手势 并且我想与 self view 中的表格视图进行交互 我已经应用了自定义手势 如下所示 import TouchEvent h import
  • 如何获取泛型类型的实际类型?

    有一个具有泛型类型的类 class Action T 创建它的一些实例 放入列表中 val list List new Action String new Action Int 迭代一下 如何获取实例的实际类型 list foreach a
  • 获取 iPhone GO 按钮来提交表单

    有谁知道表单中包含哪些变量可以使 iPhone 虚拟键盘的 GO 按钮提交表单还是不提交表单 我一直在尝试缩小场景范围 这就是我发现的 如果 FORM 只有一个用户输入字段 Go 按钮会自动提交表单 如果 FORM 有多个用户输入字段 但没
  • 循环遍历字符串以查找多个索引

    我试图找出循环字符串并查找某个字母的所有索引的最有效方法 我用过 word or phrase indexOf letter 查找某个字母的单个索引 但该字母位于 word or phrase多次 最有效的方法是构建一个包含所有索引的数组
  • Swift 如何“按值传递”对象

    我对 Swift 还很陌生 我创建一个类 例如 class Fraction var a Int init a Int self a a func toString gt String return self a 我还在其他类中构建了一个函
  • 动态壁纸是否带有游戏引擎?

    我想开发一个动态壁纸 经过一番研究后 我得出结论 有两种选择可以创建一个 直接 就像 Android Developers 上所说的那样 http developer android com resources articles live
  • 用餐哲学家挨饿的可能性

    我需要检查解决哲学家就餐问题的算法是否保证满足以下所有条件 不存在僵局的可能性 没有挨饿的可能 我正在使用信号 http en wikipedia org wiki Semaphore 28programming 29放在筷子上即可解决问题
  • 如何从 Visual Studio 2017 中的 .NET Framework 4.5 控制台应用程序引用 .NET 标准库?

    我终于安装了 Visual Studio 2017 2 并试图让我的第一个项目正常运行 但遇到了一些问题 我希望在这里解决 我有一个非常简单的 NET 标准库 描述为以下项目文件
  • ActivatedRoute 订阅第一个子参数观察者

    我不确定这是否是实现此目的的最佳方法 如果您有其他意见请分享 我必须实现一个多收件箱系统 用户可以将多封电子邮件按不同的收件箱分组 例如 http localhost inbox personal 将显示电子邮件列表personal inb
  • 简单回溯暴力算法最坏情况下有效的数独谜题是什么?

    The 简单 幼稚的回溯暴力算法 数独的 直接深度优先搜索 是众所周知并已实现的 并且似乎不存在不同的实现 当我第一次写这个问题时 我想说我们可以完全标准化它 但措辞很糟糕 我认为这个人很好地描述了算法 https stackoverflo
  • 根据 pandas 数据框中的另一列获取子字符串

    您好 有没有办法根据另一列获取一列的子字符串 import pandas as pd x pd DataFrame name bernard brenden bern digit 2 3 3 x digit name 0 2 bernard
  • 为什么我的 JComponent 没有显示在背景 JFrame 的顶部?

    为什么我的 JComponent 没有显示在背景 JFrame 的顶部 请检查以下代码 class CounterFrame extends JFrame private static final long serialVersionUID
  • 如何在 Blazor 中使用 TagHelpers?

    我创建了一个标签助手 并想在我的 Blazor 示例项目中使用它 但是 当我想使用标签助手时 编译器会抱怨 CS0103 The name StartTagHelperWritingScope does not exist in the c
  • 使用方案时,浏览器如何确定 href 中的 URL 是否是相对的?

    假设我有以下链接标签 a href Phone number a 浏览器到底如何知道不加载相对位置 tel 15555555从当前服务器知道tel应该被解释为一个计划 检测主机相对 URL 或协议相关的 URL 似乎是微不足道的 我猜 HT
  • 将函数列表应用于数字

    据我了解 Scheme Racket 中的函数 如 map foldr 和 filter 可以做一些奇妙的事情 例如将函数应用于元素列表 是否可以将函数列表应用于单个元素 我想生成每个函数产生的值 然后找到它们的最大值 谢谢 对于第一部分
  • WSO2 EI/ESB:For 循环实现

    我想实现一个简单的 for loop 在 WSO2 Integration Studio 中 例如 我正在实现一个巴士路线 API 每辆巴士有 10 个不同的站点 我想从后端服务获取 10 个站点 一个正常的 for 循环是 for i 0
  • ”中的服务器错误

    我正在遵循一个教程 内容如下 1 添加 ASP NET Identity 之前的第一步是禁用应用程序服务器 IIS 的默认身份验证机制 因为该框架使用自己的身份验证机制 为此 请在 Web config 文件的 system web 部分添
  • 将 Spark 设置为 Hive 的默认执行引擎

    Hadoop 2 7 3 Spark 2 1 0 和 Hive 2 1 1 我正在尝试将 Spark 设置为配置单元的默认执行引擎 我将 SPARK HOME jars 中的所有 jar 上传到 hdfs 文件夹 并将 scala libr
  • 如何在 iOS Swift 中为 CMSampleBufferGetFormatDescription 创建一个AudioSampleBuffer

    我一直致力于 iOS Swift 中的视频压缩 并关注this https stackoverflow com a 52346800 9250384所以的答案 它工作正常 直到我将这段代码的文件格式更改为 mp4 let videoWrit