iOS 后台视频合并

2023-11-22

Task:将传单图像合并到传单视频中。

Cases:

  • 创建传单[添加表情图像/文本..等]
  • 创建视频

Case1

  • 按后退按钮[用户将转到传单屏幕的应用程序列表],在此期间我们将 FlyerSnapShoot 合并到 FlyerVideo.and它工作得很好.
  • 转到手机图库,我们可以看到其中更新的视频。

Case2

  • 按iPhone Home按钮,我正在做与上面相同的事情,但面临以下问题error.

FAIL = Error Domain=AVFoundationErrorDomain Code=-11800“操作无法完成”UserInfo=0x17266d40 {NSLocalizedDescription=操作无法完成,NSUnderlyingError=0x172b3920“操作无法完成。(OSStatus 错误 -16980。) ", NSLocalizedFailureReason=发生未知错误 (-16980)}

Code:

- (void)modifyVideo:(NSURL *)src destination:(NSURL *)dest crop:(CGRect)crop
              scale:(CGFloat)scale overlay:(UIImage *)image
         completion:(void (^)(NSInteger, NSError *))callback {

    // Get a pointer to the asset
    AVURLAsset* firstAsset = [AVURLAsset URLAssetWithURL:src options:nil];

    // Make an instance of avmutablecomposition so that we can edit this asset:
    AVMutableComposition* mixComposition = [AVMutableComposition composition];

    // Add tracks to this composition
    AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

    // Audio track
    AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

    // Image video is always 30 seconds. So we use that unless the background video is smaller.
    CMTime inTime = CMTimeMake( MAX_VIDEO_LENGTH * VIDEOFRAME, VIDEOFRAME );
    if ( CMTimeCompare( firstAsset.duration, inTime ) < 0 ) {
        inTime = firstAsset.duration;
    }

    // Add to the video track.
    NSArray *videos = [firstAsset tracksWithMediaType:AVMediaTypeVideo];
    CGAffineTransform transform;
    if ( videos.count > 0 ) {
        AVAssetTrack *track = [videos objectAtIndex:0];
        [videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, inTime) ofTrack:track atTime:kCMTimeZero error:nil];
        transform = track.preferredTransform;
        videoTrack.preferredTransform = transform;
    }

    // Add the audio track.
    NSArray *audios = [firstAsset tracksWithMediaType:AVMediaTypeAudio];
    if ( audios.count > 0 ) {
        [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, inTime) ofTrack:[audios objectAtIndex:0] atTime:kCMTimeZero error:nil];
    }

    NSLog(@"Natural size: %.2f x %.2f", videoTrack.naturalSize.width, videoTrack.naturalSize.height);

    // Set the mix composition size.
    mixComposition.naturalSize = crop.size;

    // Set up the composition parameters.
    AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
    videoComposition.frameDuration = CMTimeMake(1, VIDEOFRAME );
    videoComposition.renderSize = crop.size;
    videoComposition.renderScale = 1.0;

    // Pass through parameters for animation.
    AVMutableVideoCompositionInstruction *passThroughInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    passThroughInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, inTime);

    // Layer instructions
    AVMutableVideoCompositionLayerInstruction *passThroughLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];

    // Set the transform to maintain orientation
    if ( scale != 1.0 ) {
        CGAffineTransform scaleTransform = CGAffineTransformMakeScale( scale, scale);
        CGAffineTransform translateTransform = CGAffineTransformTranslate( CGAffineTransformIdentity,
                                                                          -crop.origin.x,
                                                                          -crop.origin.y);
        transform = CGAffineTransformConcat( transform, scaleTransform );
        transform = CGAffineTransformConcat( transform, translateTransform);
    }

    [passThroughLayer setTransform:transform atTime:kCMTimeZero];

    passThroughInstruction.layerInstructions = @[ passThroughLayer ];
    videoComposition.instructions = @[passThroughInstruction];

    // If an image is given, then put that in the animation.
    if ( image != nil ) {

        // Layer that merges the video and image
        CALayer *parentLayer = [CALayer layer];
        parentLayer.frame = CGRectMake( 0, 0, crop.size.width, crop.size.height);

        // Layer that renders the video.
        CALayer *videoLayer = [CALayer layer];
        videoLayer.frame = CGRectMake(0, 0, crop.size.width, crop.size.height );
        [parentLayer addSublayer:videoLayer];

        // Layer that renders flyerly image.
        CALayer *imageLayer = [CALayer layer];
        imageLayer.frame = CGRectMake(0, 0, crop.size.width, crop.size.height );
        imageLayer.contents = (id)image.CGImage;
        [imageLayer setMasksToBounds:YES];

        [parentLayer addSublayer:imageLayer];

        // Setup the animation tool
        videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
    }

    // Now export the movie
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
    exportSession.videoComposition = videoComposition;

    // Export the URL
    exportSession.outputURL = dest;
    exportSession.outputFileType = AVFileTypeQuickTimeMovie;
    exportSession.shouldOptimizeForNetworkUse = YES;
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        callback( exportSession.status, exportSession.error );
    }];
}

我从 AppDelegate.m 调用这个函数

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
        // Clean up any unfinished task business by marking where you
        // stopped or ending the task outright.
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // Do the work associated with the task, preferably in chunks.
         [self goingToBg];

        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });

    NSLog(@"backgroundTimeRemaining: %f", [[UIApplication sharedApplication] backgroundTimeRemaining]);
}

在这个问题上做了很多RND,没有找到解决方案。

想要分享一些链接,希望它能够帮助堆栈社区,如果他们遇到同样的问题[要求]。

Link1: AVExportSession 在后台运行

与问题相关的引用[从上面的Link1复制]

遗憾的是,由于 AVAssetExportSession 使用 GPU 来完成其中的一些操作 工作,如果您使用的是 AVVideoComposition。

Link2: 在后台启动 AVAssetExportSession

与问题相关的引用[从上面的Link2复制]

您可以在后台启动 AVAssetExportSession。唯一的限制 在 AVFoundation 中要在后台执行工作,正在使用 AVVideoCompositions 或 AVMutableVideoCompositions。 AV视频作品 正在使用GPU,并且GPU不能在后台使用

后台任务的 URL:

苹果开发网址

雷文德利希网址

堆栈问题

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

iOS 后台视频合并 的相关文章

  • 如何在 RestKit 中为同一类提供两条发布路线

    由于我无法弄清楚如何为同一个类设置两个不同的 POST 资源路径 因此我尝试手动创建 RKObjectLoader 请求 但它似乎不断发送 GET 请求而不是 POST 即使我已将方法设置为邮政 这是我的代码 User user User
  • iOS 解决方案仅当图像尚未使用 SDWebImage 缓存在内存中时才加载带有动画的图像

    我已经为这个问题苦苦挣扎了几天 以前我使用 AFNetworking 类别来加载和缓存图像 但它的回调中没有提供缓存类型 所以我过去常常在每个控制器中跟踪哪些图像已经加载 我浏览了 SDWebImage 它提供了我正在寻找的东西 SDIma
  • 如何在我的 iOS 项目中添加和执行 .sql 文件?

    我找到了很多关于在 iOS 中使用 SQLite 数据库的教程 但没有找到任何直接引用 sql 文件的内容 谁能告诉我如何将现有的 SQL 数据库链接到我的应用程序 编辑 这是一个 MySQL 转储 我们有一个基于浏览器的抽认卡程序 现在我
  • iOS 外部附件框架:如何获取特定 MFI 设备的协议字符串

    我正在编写一个 iOS 应用程序 用于与 mini mPlay Drumi MP18B 小型蓝牙扬声器 进行通信 据我所知 showBluetoothAccessoryPickerWithNameFilter仅显示协议字符串添加到 Info
  • 在 iOS 中录制音频并永久保存

    我制作了 2 个 iPhone 应用程序 可以录制音频并将其保存到文件中并再次播放 其中之一使用 AVAudiorecorder 和 AVAudioplayer 第二个是苹果的在这里说话 http developer apple com l
  • iOS 中的等宽字体是什么?

    我想要在我的 iOS 应用程序中为 UILabel 使用等宽字体 不幸的是 我找不到一个 甚至 美国打字机 实际上也不是等宽的 XCode 中可用的等宽字体是什么 iOS 等宽字体 Courier Courier Bold Courier
  • 从 RemoteIO 保存音频的示例?

    我进行了搜索 但没有找到任何从 RemoteIO 音频单元保存音频的好示例或教程 我的设置 使用 MusicPlayer API 我有几个 AUSamplers gt MixerUnit gt RemoteIO 音频播放效果很好 我想添加将
  • 从 Core Data、iOS 获取最后插入的项目

    有没有办法获取核心数据数据库中最后插入的项目 这将返回最后插入的对象 setFetchLimit 1 和 setFetchOffset 所有条目数 1
  • 更改 UITextField 辅助功能描述

    有没有办法将 UITextField 的辅助功能标签设置为 文本字段 之外的其他内容 因此 我不想将其称为 文本字段 而是将其命名为 代码验证字段 我的建议是不要试图在内置语音输出上智取系统 对于盲人用户来说 文本字段正在编辑 相当于 该项
  • 在WKWebview中设置useragent

    如何在 WKWebView 中设置自定义用户代理字符串 我正在尝试嵌入我的应用程序的版本 以便我的服务器端可以看到可用的功能 我找到了以下方法 let userAgent MyApp 1 33 7 request setValue user
  • 从 NSError 返回 NSString

    我正在使用NSURLRequest我的 iPhone 应用程序中的类 调用它的方法返回一个NSString这对于连接正常时非常有用 但问题是我需要将 NSError 转换为 NSString 以便我可以将其返回或运行一些if 对此的声明 有
  • SecItemAdd 创建两个身份

    我正在为 iPhone 开发一个应用程序 需要证书来调用某些服务 因此我将证书添加到我的钥匙串中 执行以下操作 SecCertificateRef cert SecCertificateCreateWithData NULL bridge
  • 增加 NSData 的长度

    基本上 我有一个 46 个字符的 NSString 我将其转换为 NSData 我需要将字符串填充到 48 个字符 仅在 NSString 末尾添加 是行不通的 所以 我只是使用以下方法增加了 NSData 的长度 NSString str
  • NSMenuItem、自定义视图和 mouseUp 的奇怪问题:

    我在这里遇到了一个非常非常奇怪的 NSMenu 问题 我使用的大约一半的 NSMenuItems 通过 NSMenuItem 上的 setView 方法具有自定义视图 在此自定义视图中 我实现了 mouseUp 来捕获用户单击菜单项的时间
  • Swift 中 UIImages 的淡入淡出动画

    我有一组图像 我希望它们在登录屏幕的背景中淡出 我无法在 swift 中找到任何可以做到这一点的东西 有什么办法我可以做到吗 这是我当前的代码 override func viewDidLoad super viewDidLoad star
  • iOS 发送 iMessage 尽可能简单

    我希望能够以编程方式发送 iMessage 除了调用一个将文本发送到带有消息的号码的函数之外 无需执行任何其他操作 这两个消息都是文本框 我真的很感激一些示例代码 因为我在网上搜索过 但我发现没有任何帮助 这不适用于商业应用程序 仅适用于我
  • 如何使用 afnetworking 在后台上传任务

    我正在尝试使用 AFNetworking 上传大文件 并在应用程序处于后台时继续上传 我可以很好地上传文件 但是当我尝试使用后台配置时 应用程序崩溃并显示以下堆栈跟踪 异常 EXC BAD ACCESS 代码 1 地址 0x8000001f
  • iOS 对 Google 云消息传递的支持

    我在谷歌的开发者控制台中看到 GCM 允许为 iOS 生成 API 密钥 我在网上搜索了有关如何在 iOS 应用程序中通过 GCM 实现推送通知的任何类型的文档 但没有找到答案 真的有可能在 iOS 应用程序中使用 GCM 实现推送通知 j
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • 当设置 setVisibleXRangeMaximum 时,iOS-Charts X 轴值无限重复

    我正在尝试绘制一个图表 其中 x 轴是TimeIntervalY 轴是power consumption 由于每天都会有数据 因此将有太多数据无法显示 因此 我想一次显示 5 个值 我通过设置实现了这一点self chart setVisi

随机推荐

  • 仅调用一次函数

    我有 3 个 div Mask Intro Container 因此 如果您单击 蒙版 介绍 将被隐藏 而 容器 将出现 问题是我只想加载一次 而不是每次刷新页面或每次单击菜单或链接等时加载 我怎样才能做到这一点 这是我现在使用的脚本 do
  • CSS,覆盖所有选择下拉菜单的高度?

    我将如何引用 以便我可以覆盖所有选择框 以便我可以覆盖默认高度 当我使用类创建元素时我很熟悉 但我对此不确定 100 JS 解决方案 使用 jquery select height 120px 100 JS 解决方案 无 jquery va
  • 捕获组字符数限制

    假设我有这样的文字 AAAA1 AAA11 AA111AA A1111 AAAAA AAAA1111 我想找到所有符合这 3 个条件的事件 大写字母 1 至 4 次 数字1到4次 最大字符数为 5 所以比赛将是 AAAA1 AAA11 AA
  • 将数据流管道的输出写入分区目标

    我们有一个流事件源 每秒有数千个事件 这些事件都标有一个 ID 用于标识该事件属于我们数以万计的客户中的哪一个 我们希望使用此事件源来填充数据仓库 在流模式下 但是 我们的事件源不是持久的 因此我们还希望将原始数据存档在 GCS 中 以便我
  • HTML5 Canvas 使黑色透明

    我有大量黑色背景的图像 例如 是否有可能通过Javascript忽略黑色 000000 并将其绘制在画布上 出现这样的情况 基本上是尝试获取黑色像素并使其成为 Alpha 通道 因此 您需要遍历所有像素并更改所有黑色像素的 alpha 值
  • Java.util.scanner 错误处理

    我正在帮助一个朋友解决java问题 然而 我们遇到了障碍 我们使用 Java Util Scanner nextInt 从用户那里获取一个号码 不断询问用户是否提供了其他信息 唯一的问题是 我们不知道如何进行错误处理 我们尝试过的 do i
  • 使用 Google 广告通过 PhoneGap 应用获利(使用 PhoneGap Build 构建)

    在 AdMob 上 有不再有 HTML5 应用程序的选项 以及 AdSense 移动应用 甚至是基于 webview 的应用 明确提及 被禁止 如何使用 Google 广告通过 PhoneGap 应用 使用 PhoneGap Build 构
  • 未捕获的引用错误:尝试在 Chrome 中的另一个 Worker 中创建 Worker 时未定义 Worker

    This link says 如果工人们愿意的话 他们可以产生更多的工人们 所谓的副工 必须与父页面托管在同一源中 另外 子工作人员的 URI 是相对于父工作人员的 URI 进行解析的 位置而不是所属页面的位置 这使得更容易 工作人员跟踪他
  • 缩放 matplotlib 中的插图,无需重新绘制数据

    我正在处理一些 matplotlib 图 需要有一个缩放的插图 这是可能的zoomed inset axes来自axes grid1工具包 参见示例here import matplotlib pyplot as plt from mpl
  • 高效交易,记录锁定

    我有一个存储过程 它选择 1 条记录 可以从不同 PC 上的多个不同应用程序调用存储过程 这个想法是 存储过程带回需要处理的下一条记录 如果两个应用程序同时调用存储过程 则不应带回同一条记录 我的查询如下 我正在尝试尽可能高效地编写查询 s
  • 如何在 JavaFX 中添加 UTF-8 以实现非英语支持?

    我想在 JavaFX 中添加 UTF 8 波斯语字符 但是当我添加带有波斯语内容的标签时 它会显示一些奇怪的结果 我是否必须使用特定的插件或配置来处理此问题 波斯语是从右到左吗 在这种情况下 您希望使用 JavaFX 版本RTL 支持 那就
  • AddFavorite JS 不适用于 chrome

    我正在开发一个带有书签功能的网站 我正在使用这个功能window external AddFavorite location href document title 对于 chrome 和 IE 它在 IE 中工作正常 但对于 chrome
  • C# .Net 4.5 PropertyGrid:如何隐藏属性

    问题很简单 我希望这有一个简单的解决方案 我想在属性 Element 在我的 PropertyGrid 对象中 为零时隐藏 Browsable false public class Question public int Element g
  • 无法使用 go 和 docker 连接到 mysql 服务器 - 拨号 tcp 127.0.0.1:3306: connect: 连接被拒绝

    我在我的 Mac 上安装了 Mysql 社区服务器 它已设置并正在运行 我可以使用 Navicat for MySQL 在 localhost 3306 上连接到它 但是 每当我尝试从使用 docker compose 运行的 go 应用程
  • 将项目添加到 Endless Scroll RecyclerView 中,进度条位于底部

    我遵循 Vilen 对 SO 的出色回答 将不确定的进度条作为 RecyclerView 网格中的页脚关于如何使用 ProgressBar 实现无限滚动回收器视图 我自己实现了它并且它有效 但我想扩展这个例子 我想在 recyclervie
  • 如何使用 HttpsUrlConnection 代替 DefaultHttpClient

    DefaultHttpClient ThreadSafeClientConnManager HttpParams HttpProtocolParams SchemeRegistry SSLSocketFactory NameValuePai
  • 解决 PermGen 问题的各种选项

    我正在研究 Java 6 18 VM 上垃圾收集的各种选项 并且想要一些指导 我们在 JBoss 上运行应用程序 在重新部署期间偶尔会出现臭名昭著的 PermGen 错误 互联网上有很多关于解决或缓解此问题的最佳方法的相互矛盾和过时的信息
  • Facebook 错误“应用程序未设置:仍处于开发模式”

    我知道已经有很多与此相关的问题 但我找不到一个可以准确回答我当前问题的问题 实际上 2 天前 我的应用程序完美运行 Facebook 登录和注册 但现在它显示以下错误 我已经完成了所有必需的步骤 并且运行完美 登录 Facebook 开发者
  • Kestrel服务器:如何将不同的端口绑定到不同的控制器?

    Kestrel 有没有办法监听 2 个端口 例如80和81 并为每个端口指定不同的控制器 我遇到的情况是 有 2 个控制器 一个用于需要基于令牌的身份验证的最终用户请求 另一个控制器用于基于机器的代理 我想在其中强制执行基于客户端证书的身份
  • iOS 后台视频合并

    Task 将传单图像合并到传单视频中 Cases 创建传单 添加表情图像 文本 等 创建视频 Case1 按后退按钮 用户将转到传单屏幕的应用程序列表 在此期间我们将 FlyerSnapShoot 合并到 FlyerVideo and它工作