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

如何在视频A指定帧/时长后插入视频B?AVMutableComposition可行吗?

How to Insert Video B After a Specific Frame/Time in Video A (Using AVMutableComposition)

Great question—yes, AVMutableComposition absolutely supports this exact use case, and you don’t need to jump through hoops manually splitting Video A into two separate files first. The framework handles segmenting the original video clips based on time ranges, so you can build the desired timeline cleanly in code.

Here’s a step-by-step breakdown tailored to your scenario:

1. Capture the Key Time Point

When the user pauses Video A, record the exact pause time as a CMTime value. This is your insertion marker—let’s call it insertionTime.

2. Set Up Your Assets

First, get AVAsset instances for both Video A and Video B (you’d typically load these from the user’s media library or local file system):

let videoA = AVAsset(url: URL(fileURLWithPath: "path/to/videoA.mp4"))
let videoB = AVAsset(url: URL(fileURLWithPath: "path/to/videoB.mp4"))

3. Build the Composition Timeline

Create an AVMutableComposition and add segmented clips of Video A, followed by Video B, followed by the remaining part of Video A:

let composition = AVMutableComposition()

// Create mutable tracks for video and audio (match the original assets' media types)
guard let videoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid),
      let audioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid),
      let videoATrack = videoA.tracks(withMediaType: .video).first,
      let audioATrack = videoA.tracks(withMediaType: .audio).first,
      let videoBTrack = videoB.tracks(withMediaType: .video).first,
      let audioBTrack = videoB.tracks(withMediaType: .audio).first else {
    // Handle missing tracks error
    return
}

// Define time ranges for each segment
let videoAPreRange = CMTimeRange(start: .zero, end: insertionTime)
let videoBFullRange = CMTimeRange(start: .zero, end: videoB.duration)
let videoAPostRange = CMTimeRange(start: insertionTime, end: videoA.duration)

// Add segments to the composition tracks (video first, then audio)
do {
    try videoTrack.insertTimeRange(videoAPreRange, of: videoATrack, at: .zero)
    try videoTrack.insertTimeRange(videoBFullRange, of: videoBTrack, at: insertionTime)
    try videoTrack.insertTimeRange(videoAPostRange, of: videoATrack, at: insertionTime + videoB.duration)
    
    // Repeat for audio tracks to keep sync
    try audioTrack.insertTimeRange(videoAPreRange, of: audioATrack, at: .zero)
    try audioTrack.insertTimeRange(videoBFullRange, of: audioBTrack, at: insertionTime)
    try audioTrack.insertTimeRange(videoAPostRange, of: audioATrack, at: insertionTime + videoB.duration)
} catch {
    // Handle insertion error
    print("Error inserting tracks: \(error.localizedDescription)")
}

4. Export the Final Composition

Use AVAssetExportSession to render the composition into a single video file:

guard let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality) else {
    // Handle export session creation error
    return
}

exportSession.outputURL = URL(fileURLWithPath: "path/to/finalVideo.mp4")
exportSession.outputFileType = .mp4
exportSession.shouldOptimizeForNetworkUse = true

exportSession.exportAsynchronously {
    switch exportSession.status {
    case .completed:
        // Success! Use the output URL
        print("Export completed successfully")
    case .failed, .cancelled:
        // Handle failure/cancellation
        print("Export failed: \(exportSession.error?.localizedDescription ?? "Unknown error")")
    default:
        break
    }
}

Why This Works (And Why You Don’t Need to Split Video A)

Unlike some basic video merging examples that just append one clip to the end, AVMutableComposition operates on a timeline of time ranges. It doesn’t modify your original video files—it just references the segments you specify. So splitting Video A into "pre-insertion" and "post-insertion" segments is done entirely within the composition, no need to create separate physical files first.

This approach is efficient, flexible, and exactly what Apple’s AVFoundation framework is designed for.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:01:01