From 7b3ecfffc59d2d980d9f7628365b64c20fe015be Mon Sep 17 00:00:00 2001 From: Runt <qingingrunt2010@qq.com> Date: Sun, 27 Jul 2025 09:42:03 +0000 Subject: [PATCH] 多个小窗缩放问题修复 --- LiveProject/activity/stream/LiveViewModel.swift | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 102 insertions(+), 8 deletions(-) diff --git a/LiveProject/activity/stream/LiveViewModel.swift b/LiveProject/activity/stream/LiveViewModel.swift index 347d761..bb31219 100644 --- a/LiveProject/activity/stream/LiveViewModel.swift +++ b/LiveProject/activity/stream/LiveViewModel.swift @@ -7,22 +7,57 @@ import UIKit import AVFoundation -class LiveViewModel{ +class LiveViewModel: ObservableObject { + @Published var pixelBuffer: CVPixelBuffer? + //let encoder = H264Encoder(width: 1080, height: 1920, fps: 30, bitrate: 1_000_000) + var frameIndex: Int64 = 0 + //let encodeQueue = DispatchQueue(label: "encoder.queue") + lazy var camera = CameraCapture() - lazy var renderer = MetalRenderer() + var timestamp = Int(Date().timeIntervalSince1970 * 1000) - func newWindowAction(device:DeviceInfo,completion: @escaping (Bool) -> Void = {b in}){ - switch device.type{ + func newWindowAction(minidata:MiniWindowData,completion: @escaping (Bool) -> Void = {b in}){ + switch minidata.streamType{ case StreamType.CAMERA: requestCameraPermission(mediaType: .video){ staus in if(staus){ - self.camera.onFrame = { buffer in - self.renderer.updateFrame(pixelBuffer: buffer) - print("画面更新") + var ts1 = Int(Date().timeIntervalSince1970 * 1000) + self.camera.onFrame = { [weak self] buffer in + guard let self = self else { return } + + let width = CVPixelBufferGetWidth(buffer) + let height = CVPixelBufferGetHeight(buffer) + + guard width > 0 && height > 0 else { + print("Invalid pixel buffer size: \(width)x\(height)") + return + } + if(minidata.size.width != CGFloat(width) || minidata.size.height != CGFloat(height)){ + minidata.size = CGSize(width:width,height:height); + } + self.frameIndex += 1 + let ts = Int(Date().timeIntervalSince1970 * 1000) + + self.timestamp = ts; + let cmTime = CMTimeMake(value: Int64(CACurrentMediaTime() * 1000), timescale: 1000); + //self.encoder.encode(pixelBuffer: buffer, pts: cmTime) + DispatchQueue.main.async { + minidata.pixelBuffer = buffer; + + } + //print("画面更新") } - self.camera.start() + DispatchQueue.global(qos: .userInitiated).async { + self.camera.start() + } print("启动相机") + /*self.encoder.onEncoded = { (data: Data, ctime: CMTime, isKey: Bool) in + let timestamp2 = Int(Date().timeIntervalSince1970 * 1000) + print("编码时间2 \(timestamp2 - self.timestamp)") + print("Encoded NALU size: \(data.count), key frame: \(isKey)") + + }*/ }else{ } @@ -30,9 +65,22 @@ } break; default: + completion(true) break; } } + + func closeWindowAction(miniData:MiniWindowData){ + switch miniData.streamType{ + case StreamType.CAMERA: + print("关闭相机") + camera.stop(); + break; + default: + break; + } + } + func requestCameraPermission(mediaType: AVMediaType,completion: @escaping (Bool) -> Void) { @@ -51,4 +99,50 @@ completion(false) } } + + func copyPixelBuffer(_ src: CVPixelBuffer) -> CVPixelBuffer? { + let width = CVPixelBufferGetWidth(src) + let height = CVPixelBufferGetHeight(src) + let pixelFormat = CVPixelBufferGetPixelFormatType(src) + + var dst: CVPixelBuffer? + let attrs: [String: Any] = [ + kCVPixelBufferIOSurfacePropertiesKey as String: [:] + ] + + let status = CVPixelBufferCreate( + kCFAllocatorDefault, + width, + height, + pixelFormat, + attrs as CFDictionary, + &dst + ) + + guard status == kCVReturnSuccess, let dstBuffer = dst else { + print("❌ 复制 PixelBuffer 失败") + return nil + } + + CVPixelBufferLockBaseAddress(src, .readOnly) + CVPixelBufferLockBaseAddress(dstBuffer, []) + + let planeCount = CVPixelBufferGetPlaneCount(src) + for i in 0..<planeCount { + let srcAddr = CVPixelBufferGetBaseAddressOfPlane(src, i) + let dstAddr = CVPixelBufferGetBaseAddressOfPlane(dstBuffer, i) + + let height = CVPixelBufferGetHeightOfPlane(src, i) + let bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(src, i) + + memcpy(dstAddr, srcAddr, height * bytesPerRow) + } + + CVPixelBufferUnlockBaseAddress(src, .readOnly) + CVPixelBufferUnlockBaseAddress(dstBuffer, []) + + return dstBuffer + } + + } -- Gitblit v1.9.1