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

iOS端使用Swift将.mov/.mp4导出为HTTP Live Streaming(HLS)文件

在iPhone上用Swift本地生成HLS流文件(TS/fMP4 + M3U8清单)

在iOS本地完成HLS流生成无需依赖后端服务,核心依赖AVFoundation框架即可实现视频分片与M3U8清单生成。以下是具体实现方案:

1. 基础准备

确保项目导入AVFoundation框架,并获取必要权限:

  • 本地视频读取权限(如相册访问权限)
  • 沙盒文件写入权限(默认已具备,如需存储到共享目录需额外配置)

2. 核心实现步骤

2.1 加载源视频资源

从本地文件路径创建AVURLAsset,支持.mov/.mp4格式:

import AVFoundation

func loadSourceVideo(from url: URL) {
    let asset = AVURLAsset(url: url)
    // 预加载媒体轨道信息,避免后续导出等待
    asset.loadValuesAsynchronously(forKeys: ["tracks"]) {
        var error: NSError?
        let status = asset.statusOfValue(forKey: "tracks", error: &error)
        if status == .loaded {
            DispatchQueue.main.async {
                self.exportHLS(from: asset)
            }
        } else {
            print("视频资源加载失败:\(error?.localizedDescription ?? "未知错误")")
        }
    }
}

2.2 配置HLS导出参数

使用AVAssetExportSession配置导出规则,可指定分片格式、时长、输出目录等:

func exportHLS(from asset: AVURLAsset) {
    // 创建沙盒内的HLS输出目录(Documents下的HLSExport文件夹)
    guard let outputDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("HLSExport", isDirectory: true) else {
        print("输出目录创建失败")
        return
    }
    
    do {
        try FileManager.default.createDirectory(at: outputDir, withIntermediateDirectories: true)
    } catch {
        print("目录创建出错:\(error.localizedDescription)")
        return
    }
    
    // 输出的M3U8主清单路径
    let outputPlaylistURL = outputDir.appendingPathComponent("stream.m3u8")
    
    // 初始化导出会话,指定画质预设
    guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) else {
        print("导出会话初始化失败")
        return
    }
    
    // 配置HLS输出参数
    var outputSettings: [String: Any] = [:]
    
    // 选择分片格式:TS格式用AVFileType.hls,fMP4用AVFileType.hlsWithFragmentedMP4
    outputSettings[AVFileTypeKey] = AVFileType.hls.rawValue // 替换为AVFileType.hlsWithFragmentedMP4.rawValue可生成fMP4分片
    
    // 设置分片时长(单位:秒,建议5-15秒区间)
    outputSettings[AVAssetExportSessionHLSFragmentDurationKey] = 10
    
    // 单码率场景下无需生成主清单,多码率场景设为true
    outputSettings[AVAssetExportSessionHLSGenerateMasterPlaylistKey] = false
    
    exportSession.outputURL = outputPlaylistURL
    exportSession.outputSettings = outputSettings
    exportSession.shouldOptimizeForNetworkUse = true // 优化分片的网络传输特性
    
    // 执行导出
    exportSession.exportAsynchronously {
        switch exportSession.status {
        case .completed:
            print("HLS导出完成!文件目录:\(outputDir.path)")
            // 此处可添加批量上传所有文件到服务器的逻辑
        case .failed:
            print("导出失败:\(exportSession.error?.localizedDescription ?? "未知错误")")
        case .cancelled:
            print("导出被取消")
        default:
            break
        }
    }
}

3. 关键参数说明

  • 分片格式切换:
    • TS分片:AVFileTypeKey设为AVFileType.hls.rawValue,生成.ts后缀分片文件
    • fMP4分片:设为AVFileType.hlsWithFragmentedMP4.rawValue,生成.m4s后缀分片文件
  • 分片时长:通过AVAssetExportSessionHLSFragmentDurationKey设置,需根据视频内容和网络场景调整
  • 输出目录结构:导出完成后,目录内包含主M3U8清单、所有分片文件,多码率场景还会生成对应子清单与码率分片

4. 注意事项

  • 导出操作建议在后台线程执行,避免阻塞UI;可配合UIProgressView展示进度
  • 若源视频编码为AV1等AVFoundation不支持的格式,需先转码为H.264/H.265再执行HLS导出
  • 上传服务器时需将目录内所有文件完整上传,确保M3U8清单能正确关联分片文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:26:28