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

如何让AVFoundation相机画面拉伸旋转适配横向UIView

解决AVFoundation相机画面横向拉伸适配UIView的问题

要实现相机画面横向拉伸并适配你的LiveStreamView,需要从预览层的缩放模式、视频方向适配这两个核心点入手,以下是具体修改方案:

1. 完善LiveStreamView的配置

给LiveStreamView添加关联捕获会话的方法,并设置预览层的缩放与方向属性:

class LiveStreamView: UIView {
    
    override class var layerClass: AnyClass {
        return AVCaptureVideoPreviewLayer.self
    }
    
    var videoPreviewLayer: AVCaptureVideoPreviewLayer {
        return layer as! AVCaptureVideoPreviewLayer
    }
    
    // 添加关联捕获会话的方法
    func setup(with session: AVCaptureSession) {
        videoPreviewLayer.session = session
        // 设置画面拉伸模式:填充整个View,保持比例但会裁剪边缘
        videoPreviewLayer.videoGravity = .resizeAspectFill
        // 自动适配设备方向
        updateVideoOrientation()
    }
    
    // 更新视频方向以匹配界面方向
    func updateVideoOrientation() {
        guard let interfaceOrientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation else { return }
        let videoOrientation: AVCaptureVideoOrientation
        switch interfaceOrientation {
        case .portrait:
            videoOrientation = .portrait
        case .portraitUpsideDown:
            videoOrientation = .portraitUpsideDown
        case .landscapeLeft:
            videoOrientation = .landscapeRight
        case .landscapeRight:
            videoOrientation = .landscapeLeft
        default:
            videoOrientation = .portrait
        }
        videoPreviewLayer.connection?.videoOrientation = videoOrientation
    }
}

2. 调整AVFoundationHandler的初始化流程

设置会话预设分辨率,并确保捕获会话正常启动:

import Foundation
import AVFoundation
import UIKit

class AVFoundationHandler {
    let captureSession = AVCaptureSession()
    
    init() {
        configure()
    }
    
    func configure() {
        // 设置会话预设为高清分辨率,可根据需求调整
        captureSession.sessionPreset = .hd1920x1080
        
        guard let videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back),
              let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice),
              captureSession.canAddInput(videoDeviceInput) else { return }
        
        captureSession.addInput(videoDeviceInput)
        // 启动捕获会话
        captureSession.startRunning()
    }
}

3. 在ViewController中完成关联

在视图控制器里完成AVFoundationHandler与LiveStreamView的绑定,并处理屏幕旋转时的方向更新:

class ViewController: UIViewController {
    let liveStreamView = LiveStreamView()
    let avHandler = AVFoundationHandler()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupLiveStreamView()
    }
    
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        // 屏幕旋转时同步更新视频方向
        liveStreamView.updateVideoOrientation()
    }
    
    private func setupLiveStreamView() {
        liveStreamView.frame = view.bounds
        liveStreamView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(liveStreamView)
        // 关联捕获会话到预览层
        liveStreamView.setup(with: avHandler.captureSession)
    }
}

关键说明

  • videoGravity设置:
    • *.resizeAspectFill*:画面填充整个View,保持比例但会裁剪超出部分,适合全屏无黑边场景
    • *.resizeAspect*:保持画面比例,View剩余区域留黑边,适合完整显示画面的场景
  • 视频方向适配:通过监听界面方向,同步更新预览层的videoOrientation,确保画面旋转后显示正常
  • 会话预设:根据实际需求选择合适的分辨率,高分辨率会带来更高的性能消耗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:45:29