You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

适配iOS 16.0:更新视频正方形裁剪Swift函数以解决API废弃问题

解决iOS 16+视频正方形裁剪函数的API废弃警告

以下是适配iOS 16+的修改后代码,替换了所有废弃的API,并优化了异步资源加载逻辑:

func resizeVideoToSquare(inputURL: URL, completion: @escaping (URL?) -> Void) {
    let asset = AVAsset(url: inputURL)
    
    Task {
        do {
            // 异步加载视频轨道(替代废弃的tracks(withMediaType:))
            let videoTracks = try await asset.loadTracks(withMediaType: .video)
            guard let videoTrack = videoTracks.first else {
                completion(nil)
                return
            }
            
            // 异步获取视频原始尺寸(替代废弃的naturalSize)
            let videoSize = try await videoTrack.load(\.naturalSize)
            // 异步获取视频总时长(替代废弃的duration)
            let assetDuration = try await asset.load(\.duration)
            
            let squareSize = min(videoSize.width, videoSize.height)
            let outputSize = CGSize(width: squareSize, height: squareSize)
            
            let videoComposition = AVMutableVideoComposition()
            videoComposition.renderSize = outputSize
            videoComposition.frameDuration = CMTime(value: 1, timescale: 30)
            
            let instruction = AVMutableVideoCompositionInstruction()
            instruction.timeRange = CMTimeRange(start: .zero, duration: assetDuration)
            
            let transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
            let translationX = (videoSize.width - squareSize) / 2
            let translationY = (videoSize.height - squareSize) / 2
            let translation = CGAffineTransform(translationX: -translationX, y: -translationY)
            
            transformer.setTransform(translation, at: .zero)
            
            instruction.layerInstructions = [transformer]
            videoComposition.instructions = [instruction]
            
            let outputURL = URL.documentsDirectory.appendingPathComponent("squareVideo.mov")
            if FileManager.default.fileExists(atPath: outputURL.path) {
                try FileManager.default.removeItem(at: outputURL)
            }
            
            guard let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) else {
                completion(nil)
                return
            }
            
            exporter.outputURL = outputURL
            exporter.outputFileType = .mov
            exporter.videoComposition = videoComposition
            exporter.exportAsynchronously {
                if exporter.status == .completed {
                    completion(outputURL)
                } else {
                    print("视频导出失败: \(String(describing: exporter.error))")
                    completion(nil)
                }
            }
        } catch {
            print("加载视频资源失败: \(error.localizedDescription)")
            completion(nil)
        }
    }
}

关键API替换说明

  • 废弃的asset.tracks(withMediaType: .video):改用异步方法loadTracks(withMediaType:),通过try await异步获取轨道列表,避免主线程阻塞,符合AVFoundation在iOS16+的异步设计规范。
  • 废弃的videoTrack.naturalSize:改用videoTrack.load(\.naturalSize)异步加载视频原始尺寸,这是AVFoundation推荐的属性异步获取方式,确保资源加载完成后获取准确值。
  • 废弃的asset.duration:改用asset.load(\.duration)异步获取视频总时长,替代原同步属性,避免因资源未加载完成导致的错误值。

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 07:17:02