使用 AVMutableVideoComposition 导出时出现视频方向问题

2023-12-19

这是我用来导出视频的功能:

- (void) videoOutput
{
//1 - Early exit if there's no video file selected
if (!self.videoAsset) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Please Load a Video Asset First"
                                                   delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    return;
}

// 2 - Create AVMutableComposition object. This object will hold your AVMutableCompositionTrack instances.
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];

// 3 - Video track
AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                    preferredTrackID:kCMPersistentTrackID_Invalid];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration)
                    ofTrack:[[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
                     atTime:kCMTimeZero error:nil];

// 3.1 - Create AVMutableVideoCompositionInstruction
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration);

// 3.2 - Create an AVMutableVideoCompositionLayerInstruction for the video track and fix the orientation.
AVMutableVideoCompositionLayerInstruction *videolayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
AVAssetTrack *videoAssetTrack = [[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

BOOL isVideoAssetPortrait_  = NO;
CGAffineTransform videoTransform = videoAssetTrack.preferredTransform;
if (videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0) {
    isVideoAssetPortrait_ = YES;
}
if (videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0) {

    isVideoAssetPortrait_ = YES;
}
if (videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0) {
    isVideoAssetPortrait_  = NO;
}
if (videoTransform.a == -1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == -1.0) {
    isVideoAssetPortrait_  = NO;
}
[videolayerInstruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero];
[videolayerInstruction setOpacity:0.0 atTime:self.videoAsset.duration];

// 3.3 - Add instructions
mainInstruction.layerInstructions = [NSArray arrayWithObjects:videolayerInstruction,nil];

AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];

CGSize naturalSize;
if(isVideoAssetPortrait_){
    naturalSize = CGSizeMake(videoAssetTrack.naturalSize.height, videoAssetTrack.naturalSize.width);
} else {
    naturalSize = videoAssetTrack.naturalSize;
}

mainCompositionInst.renderSize = naturalSize;
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
mainCompositionInst.frameDuration = CMTimeMake(1, 30);

// 4 - Get path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *myPathDocs =  [documentsDirectory stringByAppendingPathComponent:
                         [NSString stringWithFormat:@"FinalVideo-%d.mov",arc4random() % 1000]];
NSURL *url = [NSURL fileURLWithPath:myPathDocs];

// 5 - Create exporter
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition
                                                                  presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL=url;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
exporter.videoComposition = mainCompositionInst;
[exporter exportAsynchronouslyWithCompletionHandler:^{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self exportDidFinish:exporter];
    });
}];
}

问题是,我第一次使用这个函数导出肖像视频时,变量videoTransform (videoAssetTrack.preferredTransform) are:

videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0

和变量isVideoAssetPortrait_ equals YES。一切都是对的。但是,导出完成并保存到相机胶卷后,我使用了这个功能重新加载结果视频。这一次,视频转换改变:

videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0

And isVideoAssetPortrait_ equals NO。意思是,导出一次后,视频转换改变了它的值(方向从纵向 -> 横向)

我用谷歌搜索了很多关于 AV Foundation 视频方向的问题,但还没有找到解决方案。

感谢您阅读我的长篇解释。如果您有任何疑问,请告诉我。


视频轨道不存​​在纵向/横向这样的概念。它只有它的尺寸和为了正确呈现它而应用的变换。默认情况下,“肖像”视频按照相机生成的方式进行编码(比如说风景),并使用 90 度旋转来正确呈现它。

当您导出它时,它的方向不会改变,只是重新编码物理旋转,因此不需要旋转即可正确呈现它。 这就是为什么您第二次获得单位矩阵(这并不意味着它从纵向更改为横向),但这次它的自然大小也被交换,并且根据您的代码一切都应该没问题。

请指出后一种情况有什么问题。

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

使用 AVMutableVideoComposition 导出时出现视频方向问题 的相关文章

  • 如何开始复杂级别的跨平台移动应用开发? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • .showsPhysics 内存泄漏

    我最近花了 5 个小时尝试调试 Spritekit 应用程序中的内存泄漏 应用程序启动后 我注意到内存使用量略有上升 我花了 5 个小时中的 3 个小时挖掘参考资料 了解强与弱的关系ARC https developer apple com
  • 检测 iPhone 是否在运行时运行调试/分发构建

    是否可以在运行时检测正在运行的应用程序是否是通过调试或分发进行编译的 在项目信息中 对于调试配置 添加 DEBUG 预处理器宏 在 GCC 4 2 预处理部分 在代码中 如果您想要包含或不包含某些代码用于调试版本 则可以使用 ifdef 来
  • AppStore 提交:错误 ITMS-9000:“无效的捆绑结构 - 不允许二进制文件‘MyApp.app/BuildAgent’

    我陷入了以下错误 我根本不明白 错误 ITMS 9000 无效的捆绑结构 不允许使用二进制文件 MyApp app BuildAgent 您的应用程序可能只包含一个可执行文件 当我使用 Xcode 从 Archive 导出到 IPA 时 我
  • React-native-vision-camera无法访问后面的普通摄像头

    我正在尝试在 iPhone 11 Pro 上使用 普通 相机 我使用反应本机视觉相机 当我运行这段代码时 const devices useCameraDevices const deviceBack devices back consol
  • 错误域=kAFAssistantErrorDomain 代码=209“(空)”

    我面临着一个问题SFSpeechRecognizer 启动应用程序几秒钟后 我开始收到错误消息 错误域 kAFAssistantErrorDomain 代码 209 空 和 错误 域 kAFAssistantErrorDomain 代码 2
  • Objective-C UILabel 作为超链接

    我正在尝试做一个UILabel一个链接UIWebView 我怎样才能做一个UILabel作为超链接 您可以使用 UITapGestureRecognizer 它将实现与您想要的类似的功能 UILabel myLabel UILabel al
  • iOS:生成pdf时绘制文本时如何设置字体?

    我在ios应用程序中使用drawpdf函数生成pdf 同时调用nsobject类中的drawtext函数 它根据我指定的框架和字符串清楚地绘制文本 我的代码是 void drawText NSString textToDraw inFram
  • 从命令行添加 Xcode 开发者帐户

    我正在尝试使用xcodebuild allowProvisioningUpdates在我只能通过命令行访问的计算机 Azure Devops macOS 托管计算机 上 不幸的是 根据man xcodebuild为了使用 allowProv
  • 用户验证 Facebook 后未调用应用程序打开 Url 方法

    我已将 ios 应用程序中的 facebook 升级到 3 0 并使用提供的代码https developers facebook com docs howtos login with facebook using ios sdk http
  • ReactiveCocoa 将 SignalProducers 合二为一

    我正在使用 ReactiveCocoa 并且我有几个 SignalProducers let center NSNotificationCenter defaultCenter let signalProducer1 center rac
  • UIView animateWithDuration:delay: 工作很奇怪

    我在使用 iPhone 动画块时遇到了一个奇怪的问题 这段代码 UIView animateWithDuration 2 delay 0 options 0 animations void controller setBackgroundC
  • 贴纸包会在模拟器上使 iMessage 崩溃,但在 iPhone 上不会崩溃

    按照 Apple 的在线说明和视频在 Xcode 中创建了一个贴纸包 所有图像的尺寸均正确且远低于文件大小阈值 如果我在我的实体 iPhone 上构建并运行贴纸包 一切都会完美运行 如果我在模拟器上构建并运行贴纸包 对于任何模拟的 iPho
  • 如何在代码中编辑约束

    我有一个以 100 开始宽度限制的网页 当用户单击按钮时 我想将约束更改为 200 我试过这个 NSLayoutConstraint constrain NSLayoutConstraint constraintWithItem self
  • UITableViewCell显示多种字体

    我想在 uitableviewcell 中以类似于 iPhone 地址簿的不同字体显示两个单词 例如 约翰Buchanan 您应该使用两个 UILable 或者您可以使用OH属性标签 https github com AliSoftware
  • 图像作为电子邮件附件

    我想构建一个应用程序 我可以在电子邮件中附加图像 打开图像并将其设置为我的壁纸 我想让它跨平台 所以你能告诉我是否可以使用phonegap 或者我是否必须为iphone和android构建一个本机应用程序 您好 如果您只想通过电子邮件附加图
  • TableViewController 的 viewDidLoad 未触发

    我一直在关注这个tutorial http www appcoda com ios programming sidebar navigation menu 有一个滑出式菜单 我添加了一个 TableViewController 它将显示文章
  • iOS:如何知道 reloadData() 已完成其任务?

    我想滚动到给定索引 self boldRowPath 但是当我调试时scrollToRow之前执行reloadData 如何知道reloadData已完成 func getAllTimeEvent self arrAllTimeEvent
  • 如何在 UICollectionView 中将行居中?

    我有一个UICollectionView与随机细胞 有什么方法可以让我将行居中吗 默认情况下它是这样的 x x x x x x x x x x x x x x 这是所需的布局 x x x x x x x x x x x x 我必须做这样的事
  • 像 TraceGL 一样分析 Objective C 中的代码路径?

    TraceGL 是一个非常简洁的项目 它允许 JS 程序员跟踪 Javascript 中的代码路径 它看起来像这样 我想为 Objective C 构建类似的东西 我知道运行时使跟踪方法调用变得相当容易 但是我如何跟踪控制流 例如 在上面的

随机推荐

  • iOS 4 真的支持 ARC 吗? iOS 4.2 SDK 在链接时缺少与 ARC 相关的符号

    自从 ARC 首次宣布它是一个编译时的东西并且向后兼容 iOS 4 以来 我已经阅读和听说过它 我已经使用 Xcode 4 2 的自动重构成功地将我的项目重构为 ARC 并且当针对iOS 5 0 SDK 运行良好 但是 如果我尝试针对 iO
  • 你能在不调用 setState 的情况下强制 React 组件重新渲染吗?

    我有一个外部 组件的 可观察对象 我想监听它的更改 当对象更新时 它会发出更改事件 然后我想在检测到任何更改时重新渲染组件 拥有顶级的React render这是可能的 但在组件内它不起作用 这是有道理的 因为render方法只返回一个对象
  • 使用 ASP.NET Core 设置 azure-pipelines.yml“在存储库中找不到 Web 项目”

    我需要帮助来设置我的 azure pipelines yml 构建文件 因为我在任何地方都找不到任何好的教程 示例或其他类型的帮助 我遵循微软的这个教程https learn microsoft com en us azure devops
  • 合并和更新主键

    我查了一下 但没有找到解决这个看似简单的问题的方法 我有许多结构相同的表 想合并它们 唯一的问题是它们都有一个 id 字段作为主键 主键中会有很多重复项 id 最终是什么并不重要 如何合并所有表以免丢失任何数据 创建一个AUTO INCRE
  • Django注释来自另一个模型的字段值

    我想用另一个历史模型中的值来注释 MyModel 查询集 我的模型关系如下 class Stage models Model name models CharField class History models Model mymodel
  • 在编码的 ui 测试中传递命令行参数

    是否可以在编码的 ui 测试中传递命令行参数 在普通的 C 程序中 我们只需将参数与 exe 文件一起传递 例如 命令提示符中的 filename exe 2 7 但是这样的事情可以在编码的 ui 测试中完成吗 Thanks 不 你可以这样
  • ViewPager 中的可滚动 TextView

    我有一个TextView里面一个Fragment in a ViewPager我想把文字放在TextView可滚动 由于某种原因 这不起作用并且文本视图不滚动 这是我尝试过的 片段中的代码 public View onCreateView
  • PKPaymentAuthorizationViewController 不为零但未显示

    我试图显示一个 PKPaymentAuthorizationViewController 它不为零但没有显示 我以前工作过 但现在不再工作了 权利和商家 ID 看起来不错 这是我的初始化代码 没有无用的代码 PKPaymentRequest
  • 更改键盘快捷键以注释 Spyder 中的行[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我最近开始使用 Spyder IDE Python 3 6 但在习惯键盘快捷键方面遇到了一些困难 由于我使用 azerty 键盘 这很复杂
  • 使用 Kendo UI 数据源的授权标头拦截器

    我正在使用 Web api 并限制 Web api 通过令牌进行身份验证 因此为了填充数据源 我在数据源中使用请求标头 var abcDatasource new kendo data DataSource transport read u
  • .animate() - 旧版 jquery 版本 (Drupal) 冲突的队列模拟

    我正在寻找一个解决方案来推出 jquery 版本 Drupal 本身就包含该版本 它是旧版本 实际上没有任何问题 但有一个 D 我使用队列为 false 的 animate 函数 并且没有此属性 因为此属性在 jquery 1 7 中添加到
  • NSJSONSerialization 拆箱 NSNumber?

    我在用着NSJSONSerialization转动一个JSON将文档转换为核心基础类型 我的领域里有一个JSON这是一个 数字 有时是整数 有时是浮点数 现在 问题是何时NSJSONSerialization变成我的JSON进入一个NSDi
  • Git:存储但不拉取较少的文件

    我最近开始使用 LESS 当我对 Jenkins 和 Grunt 等自动化构建器进行一些研究时 似乎一个常见的建议是不要将 LESS 文件存储在存储库上 或者不要将它们放在实时服务器上 只是编译的 CSS 所以我希望能得到一些关于这方面的建
  • 使用 Javascript 更改页面

    我构建了一个 Phonegap 应用程序 我有 7 8 个页面 我需要使用 Javascript 在它们之间导航 我尝试过使用window open and window location但那些不起作用 如何使用 Javascript 更改
  • Intellisense 将 .c 文件视为 .cpp

    我正在使用 VS2010 进行 C 项目 我不断收到 Intellisense 错误IntelliSense a value of type void cannot be assigned to an entity of type Blah
  • 在 Eclipse“运行方式 -> Android 应用程序”构建中包含 Maven 依赖项

    我使用eclipse开发一个Android应用程序 Android 开发工具 ADT 插件 http developer android com guide developing eclipse adt html和maven android
  • 在 C# 中向通用列表的 FindAll 添加参数

    我有一个要通过整数参数过滤的对象列表 List
  • 如何更改引导导航菜单颜色?

    我想更改 主页 旋转 社交媒体 的颜色 但不知道如何更改 我花了几天时间弄清楚如何更改导航背景 但对颜色一无所知 因为我只想将灰色更改为白色并更改悬停颜色 我可以将颜色更改为白色 但悬停颜色将被忽略 有没有一种预期的方法来做到这一点 这是我
  • 如果条件失败,Laravel 会从模型中抛出错误

    我正在模型中进行所有验证 我的规则是 public static rules array VehicleNumber gt required unique vehicle NumberSeats gt required VehicleTyp
  • 使用 AVMutableVideoComposition 导出时出现视频方向问题

    这是我用来导出视频的功能 void videoOutput 1 Early exit if there s no video file selected if self videoAsset UIAlertView alert UIAler