将 AVAssetWriter 与原始 NAL 单元结合使用

2024-02-10

我在 iOS 文档中注意到AVAssetWriterInput你可以通过nil为了outputSettings字典来指定输入数据不应重新编码。

用于对附加到输出的媒体进行编码的设置。传递 nil 来指定不应重新编码附加的样本。

我想利用此功能来传递原始 H.264 NAL 流,但我在将原始字节流调整为CMSampleBuffer我可以传递给 AVAssetWriterInputappendSampleBuffer方法。我的 NAL 流仅包含 SPS/PPS/IDR/P NAL (1, 5, 7, 8)。我尚未找到有关如何将预编码的 H264 数据与 AVAssetWriter 一起使用的文档或结论性答案。生成的视频文件无法播放。

我怎样才能正确地将NAL单元打包成CMSampleBuffers?我需要使用起始代码前缀吗?长度前缀?我是否需要确保每次只放置一个 NALCMSampleBuffer?我的最终目标是使用 H264/AAC 创建 MP4 或 MOV 容器。

这是我一直在玩的代码:

-(void)addH264NAL:(NSData *)nal
{
    dispatch_async(recordingQueue, ^{
        //Adapting the raw NAL into a CMSampleBuffer
        CMSampleBufferRef sampleBuffer = NULL;
        CMBlockBufferRef blockBuffer = NULL;
        CMFormatDescriptionRef formatDescription = NULL;
        CMItemCount numberOfSampleTimeEntries = 1;
        CMItemCount numberOfSamples = 1;


        CMVideoFormatDescriptionCreate(kCFAllocatorDefault, kCMVideoCodecType_H264, 480, 360, nil, &formatDescription);
        OSStatus result = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, NULL, [nal length], kCFAllocatorDefault, NULL, 0, [nal length], kCMBlockBufferAssureMemoryNowFlag, &blockBuffer);
        if(result != noErr)
        {
            NSLog(@"Error creating CMBlockBuffer");
            return;
        }
        result = CMBlockBufferReplaceDataBytes([nal bytes], blockBuffer, 0, [nal length]);
        if(result != noErr)
        {
            NSLog(@"Error filling CMBlockBuffer");
            return;
        }
        const size_t sampleSizes = [nal length];
        CMSampleTimingInfo timing = { 0 };
        result = CMSampleBufferCreate(kCFAllocatorDefault, blockBuffer, YES, NULL, NULL, formatDescription, numberOfSamples, numberOfSampleTimeEntries, &timing, 1, &sampleSizes, &sampleBuffer);

        if(result != noErr)
        {
            NSLog(@"Error creating CMSampleBuffer");
        }
        [self writeSampleBuffer:sampleBuffer ofType:AVMediaTypeVideo];
    });
}

请注意,我正在打电话CMSampleBufferSetOutputPresentationTimeStamp在样本缓冲区内writeSampleBuffer方法与我认为在我实际尝试附加它之前的有效时间。

任何帮助表示赞赏。


我设法在 VLC 中播放视频,但在 QuickTime 中却不行。我使用与上面发布的代码类似的代码将 H.264 NAL 放入 CMSampleBuffers 中。

我有两个主要问题:

  1. 我没有正确设置 CMSampleTimingInfo (正如我上面的评论所述)。
  2. 我没有正确打包原始 NAL 数据(不确定记录在哪里,如果有的话)。

为了解决#1,我设置timing.duration = CMTimeMake(1, fps);其中 fps 是预期帧速率。然后我设置timing.decodeTimeStamp = kCMTimeInvalid;意味着样本将按解码顺序给出。最后我设置了timing.presentationTimeStamp通过计算绝对时间,我也使用了startSessionAtSourceTime.

为了解决#2,通过反复试验,我发现以下面的形式给出我的 NAL 单位是有效的:

[7 8 5] [1] [1] [1]..... [7 8 5] [1] [1] [1]..... (repeating)

其中每个 NAL 单元都以 32 位起始码为前缀,等于0x00000001.

大概出于同样的原因,它无法在 QuickTime 中播放,我仍然无法将生成的 .mov 文件移动到相册(ALAssetLibrary method videoAtPathIsCompatibleWithSavedPhotosAlbum未能说明“电影无法播放”。希望对正在发生的事情有想法的人可以发表评论。谢谢!

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

将 AVAssetWriter 与原始 NAL 单元结合使用 的相关文章

  • 使用 JavaScript 捕获 iPhone 虚拟键盘中的“完成”按钮点击

    我想知道是否有一种方法可以使用 JavaScript 捕获 iPhone 虚拟键盘的完成按钮事件 基本上 我只是希望能够在用户单击 完成 时调用 JS 函数 我无法跟踪单击的 完成 按钮 它没有注册任何clicks or keypresse
  • Metallib:读取模块时出错:无效的位码签名

    我有以下 Filter metal 文件 include
  • CIGaussianBlur 有时会改变图像方向

    在我的 iOS 应用程序中 我想在 UIImage 上应用一个滤镜 CIGaussianBlur 当它获得具有大高度的图像时 它会旋转图像 CIContext context CIContext contextWithOptions nil
  • 从 .Plist 加载数组

    我正在尝试从 Plist 中的数组加载数组 但它不起作用 该 plist 看起来像这样 这是我正在使用的代码 NSString path NSBundle mainBundle pathForResource DiseaseProperty
  • 在 iOS 上使用 MDCBottomNavigationBar 切换视图控制器

    我正在尝试创建一个使用 Material Design 库的底部导航功能的 iOS 应用程序 我可以获得带有底部导航栏的视图控制器来编译和显示 但我无法添加其他视图控制器并在单击不同选项卡时在它们之间切换 我将所有内容简化为两个文件 一个是
  • 如何在应用程序中从 Xcode 的“支持文件”组访问文件?

    我有一个应用程序 现在我几乎已经完成了 在数据输入流程结束时发送电子邮件 发送两个 pdf 文件 其中一个是根据输入的数据生成的 另一个是静态文件 在每个实例中都相同 第一个 pdf 生成正常 它已保存到应用程序的 文档 文件夹中 并且我已
  • iOS 9 + Xcode 7 的 Segue 上的应用程序导致整个设备崩溃

    更新 我已经在这一年中使用了我的一个 DTS 目前与 Apple 支持工程师合作 根据他的建议 我还为此创建了一个错误报告 随着时间的推移 我将更新此线程 希望能产生最终的解决方案 不知何故 我找到了一种方法来创建一个可以真正重新启动模拟器
  • 如何检查 iOS/iPadOS 是否启用了深色模式?

    从 iOS iPadOS 13 开始 提供深色用户界面风格 类似于 macOS Mojave 中引入的深色模式 如何检查用户是否启用了系统范围的深色模式 For iOS 13 您可以使用此属性来检查当前样式是否为深色模式 if availa
  • Facebook 登录 - 如果存在用户帐户(并且未安装应用程序)登录失败

    我刚刚在测试我的应用程序时发现了这个问题 它真的开始让我烦恼 那么环境是这样的 没有安装 Facebook 应用程序 用户登录 iOS 系统帐户 在设置 gt Facebook 下 当我的应用程序第一次尝试对用户进行身份验证时 它会提供这面
  • 如何设置 AWS Appsync 请求超时限制 || AWSAppSync 客户端不提供回调

    我正在使用 AWS Appsync 来开发当前的应用程序 并面临一个严重的问题 即每当我在 Appsync 客户端中触发查询时 当互联网连接速度较慢时 请求永远不会以回调结束 我在互联网上查了一下 关于这个主题的信息来源有限 而且发现这个问
  • Xcode如何将目标打包为.framework(而不是.a库)

    我有一个通用框架项目 其中包含一个库作为其主要目标 在产品下是带有 lib 前缀和 a 扩展名的库 请参阅下面的屏幕截图 我正在使用一个第三方项目 其中包含一个框架作为其目标 并且在 产品 下是具有 framework 扩展名的框架 请参阅
  • 如何使用AVAssetWriter将h264流写入视频?

    我想将 h 264 流从服务器传输到视频文件 但是当我使用assetwrite finishwrite XCode 报告 Video var mobile Applications DE4196F1 BB77 4B7D 8C20 7A5D6
  • 如何重置(即取消缩放)UIScrollView?

    我有一个 UIScrollView 其中包含图像和分段控件 该控件允许用户在 ScrollView 内切换图像 如果我只是将图像交换到 UIImageView 内部 它将以放大状态显示新图像 如何将 UIScrollView 重置回未放大状
  • 保留rootViewController?

    我想知道是否有人可以帮助我解决下面代码中的内存管理问题 我对 rootController 特别感兴趣 当我执行 initWithRootViewController 时它是否会被保留 或者它是否 这是我的猜测 通过窗口 addSubVie
  • 捕获 SwiftUI 中的错误

    我在某些视图中有一个按钮 它调用 ViewModel 中可能引发错误的函数 Button action do try self taskViewModel createInstance name self name catch Databa
  • iPad 上的 Cordova 锁定方向失败

    我正在使用 cordova 3 5 0 0 2 6 最后一个稳定版本 我在锁定 iPad 设备的方向时遇到问题 在 iPhone 上它可以正常工作 但在 iPad 上方向未锁定 我想锁定整个应用程序而不仅仅是页面 这是我当前的 config
  • 如何比双击更快地识别单击?

    我有一个UITableView与我添加单击的行and双击手势 let doubleTap UITapGestureRecognizer target self action doubleTap doubleTap numberOfTapsR
  • CoreGraphics 在 iPhone4 上比在 3G/3GS 上慢

    我有一个用 CoreGraphics 绘制的图表 该图表可以水平滚动 并且当我们滚动它时就会绘制它 问题是 在 3G 3GS 上 滚动的速度和性能良好 但在 iPhone 4 上却比预期慢 我认为这是与 iPhone 4 的高分辨率有关的问
  • 无法在 Swift 的 Storyboard 中加载 UIViewController XIB 文件

    我读了使用 XCode 故事板实例化使用 XIB 进行设计的视图控制器 https stackoverflow com questions 9155719 using xcode storyboard to instantiate view
  • 如何将 PhoneGap 调试控制台与 CLI 集成?

    PhoneGap 网站上的此页面http docs phonegap com en 3 3 0 guide cli index md html The 20Command Line 20Interface http docs phonega

随机推荐