iOS 前置摄像头录制视频方向错误

2024-09-24  本文已影响0人  大成小栈

前置摄像头录制视频时,connection.isVideoMirrored设置为true,为什么传至服务端后播放时,视频方向不对?怎么调整视频数据的方向?

在前置摄像头录制视频时,如果你设置了 AVCaptureConnectionisVideoMirrored 属性为 true,这会导致视频在本地预览时看起来是镜像的(与自拍效果一致)。然而,这种镜像效果只是本地预览中的视觉效果,并不会影响实际保存的视频数据。因此,当视频传至服务端后,播放器会按照原始未镜像的方向播放,导致播放方向与预期不符。

调整视频数据方向的原因:

调整视频方向的解决方案:

  1. 通过 AVFoundation 原生方式调整视频方向
  2. 使用 FFmpeg 重新编码并调整视频方向

1. 原生实现方式(AVFoundation)

在视频录制完成后,可以通过 AVAssetAVMutableVideoComposition 对视频进行处理,应用正确的方向调整。

原生调整视频方向的步骤:

  1. 使用 AVAsset 加载视频文件。
  2. 通过 AVMutableVideoComposition 应用旋转或镜像操作。
  3. 使用 AVAssetExportSession 导出修改后的视频。

原生实现示例:

import AVFoundation

func adjustVideoOrientation(asset: AVAsset, outputURL: URL, completion: @escaping (Bool) -> Void) {
    // 获取视频轨道
    guard let videoTrack = asset.tracks(withMediaType: .video).first else {
        completion(false)
        return
    }

    // 创建一个 AVMutableComposition 对象
    let composition = AVMutableComposition()
    guard let compositionTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid) else {
        completion(false)
        return
    }

    // 插入视频轨道
    do {
        try compositionTrack.insertTimeRange(CMTimeRange(start: .zero, duration: asset.duration), of: videoTrack, at: .zero)
    } catch {
        completion(false)
        return
    }

    // 设置视频旋转和镜像的 transform
    let videoComposition = AVMutableVideoComposition()
    videoComposition.renderSize = videoTrack.naturalSize
    videoComposition.frameDuration = CMTime(value: 1, timescale: 30)

    let instruction = AVMutableVideoCompositionInstruction()
    instruction.timeRange = CMTimeRange(start: .zero, duration: asset.duration)

    let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: compositionTrack)

    // 获取视频的初始 transform
    var transform = videoTrack.preferredTransform

    // 设置镜像效果
    transform = transform.scaledBy(x: -1.0, y: 1.0) // 水平镜像
    transform = transform.translatedBy(x: -videoTrack.naturalSize.width, y: 0) // 调整位置

    layerInstruction.setTransform(transform, at: .zero)
    instruction.layerInstructions = [layerInstruction]
    videoComposition.instructions = [instruction]

    // 使用 AVAssetExportSession 导出调整后的视频
    let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)
    exportSession?.outputURL = outputURL
    exportSession?.outputFileType = .mp4
    exportSession?.videoComposition = videoComposition

    exportSession?.exportAsynchronously {
        completion(exportSession?.status == .completed)
    }
}

2. 使用 FFmpeg 调整视频方向

FFmpeg 是一个强大的多媒体处理工具,可以用来调整视频的旋转和镜像方向。相比原生实现,FFmpeg 具有更高的灵活性和效率。

使用 FFmpeg 命令行调整视频方向:

常见的 FFmpeg 命令:

  1. 水平镜像(水平翻转):
ffmpeg -i input.mp4 -vf "hflip" output.mp4
  1. 旋转 90 度:
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4
  1. 垂直翻转:
ffmpeg -i input.mp4 -vf "vflip" output.mp4
  1. 同时进行旋转和水平镜像:
ffmpeg -i input.mp4 -vf "transpose=1,hflip" output.mp4

FFmpeg 命令解释:


总结

上一篇下一篇

猜你喜欢

热点阅读