前置摄像头录制视频时,connection.isVideoMirrored设置为true,为什么传至服务端后播放时,视频方向不对?怎么调整视频数据的方向?
在前置摄像头录制视频时,如果你设置了 AVCaptureConnection
的 isVideoMirrored
属性为 true
,这会导致视频在本地预览时看起来是镜像的(与自拍效果一致)。然而,这种镜像效果只是本地预览中的视觉效果,并不会影响实际保存的视频数据。因此,当视频传至服务端后,播放器会按照原始未镜像的方向播放,导致播放方向与预期不符。
调整视频数据方向的原因:
- 设置
isVideoMirrored = true
仅影响本地预览,不会影响最终保存的视频文件的实际像素数据。 - 视频传到服务端后,因为没有反映镜像效果的方向信息,导致播放方向不对。
调整视频方向的解决方案:
- 通过 AVFoundation 原生方式调整视频方向。
- 使用 FFmpeg 重新编码并调整视频方向。
1. 原生实现方式(AVFoundation)
在视频录制完成后,可以通过 AVAsset
和 AVMutableVideoComposition
对视频进行处理,应用正确的方向调整。
原生调整视频方向的步骤:
- 使用
AVAsset
加载视频文件。 - 通过
AVMutableVideoComposition
应用旋转或镜像操作。 - 使用
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 命令行调整视频方向:
- 如果需要将视频水平翻转(镜像),可以使用
hflip
滤镜。 - 如果需要旋转视频,可以使用
transpose
滤镜。
常见的 FFmpeg 命令:
- 水平镜像(水平翻转):
ffmpeg -i input.mp4 -vf "hflip" output.mp4
- 旋转 90 度:
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4
- 垂直翻转:
ffmpeg -i input.mp4 -vf "vflip" output.mp4
- 同时进行旋转和水平镜像:
ffmpeg -i input.mp4 -vf "transpose=1,hflip" output.mp4
FFmpeg 命令解释:
-
hflip
:水平翻转(镜像)。 -
transpose
:-
transpose=1
:顺时针旋转 90 度。 -
transpose=2
:逆时针旋转 90 度。
-
总结
- 如果你希望在录制视频时前置摄像头的镜像效果在服务端播放时保持一致,建议:
- 在录制完成后使用原生方法 (
AVAssetExportSession
+AVMutableVideoComposition
) 或 FFmpeg 调整视频的方向。 - 原生方法 更适合集成在 iOS 应用中,而 FFmpeg 适用于后期批量处理或高效处理复杂视频调整的场景。
- 在录制完成后使用原生方法 (
网友评论