Files
Luma/Sources/Shared/UI/Components/RTCVideoRendererView.swift
T
2026-07-30 20:07:51 +07:00

100 lines
2.8 KiB
Swift

import SwiftUI
import WebRTC
#if os(iOS)
import UIKit
struct RTCVideoRendererView: UIViewRepresentable {
let track: RTCVideoTrack?
var mirrored = false
var contentMode: UIView.ContentMode = .scaleAspectFill
func makeCoordinator() -> Coordinator {
Coordinator()
}
func makeUIView(context: Context) -> RTCMTLVideoView {
let view = RTCMTLVideoView(frame: .zero)
view.videoContentMode = contentMode
view.backgroundColor = .black
context.coordinator.update(track: track, renderer: view)
return view
}
func updateUIView(_ view: RTCMTLVideoView, context: Context) {
view.videoContentMode = contentMode
view.transform = mirrored
? CGAffineTransform(scaleX: -1, y: 1)
: .identity
context.coordinator.update(track: track, renderer: view)
}
static func dismantleUIView(_ view: RTCMTLVideoView, coordinator: Coordinator) {
coordinator.detach(renderer: view)
}
final class Coordinator {
private weak var track: RTCVideoTrack?
func update(track newTrack: RTCVideoTrack?, renderer: RTCMTLVideoView) {
guard track !== newTrack else { return }
track?.remove(renderer)
track = newTrack
newTrack?.add(renderer)
}
func detach(renderer: RTCMTLVideoView) {
track?.remove(renderer)
track = nil
}
}
}
#elseif os(macOS)
import AppKit
struct RTCVideoRendererView: NSViewRepresentable {
let track: RTCVideoTrack?
var mirrored = false
func makeCoordinator() -> Coordinator {
Coordinator()
}
func makeNSView(context: Context) -> RTCMTLNSVideoView {
let view = RTCMTLNSVideoView(frame: .zero)
view.wantsLayer = true
view.layer?.backgroundColor = NSColor.black.cgColor
context.coordinator.update(track: track, renderer: view)
return view
}
func updateNSView(_ view: RTCMTLNSVideoView, context: Context) {
view.layer?.setAffineTransform(
mirrored ? CGAffineTransform(scaleX: -1, y: 1) : .identity
)
context.coordinator.update(track: track, renderer: view)
}
static func dismantleNSView(_ view: RTCMTLNSVideoView, coordinator: Coordinator) {
coordinator.detach(renderer: view)
}
final class Coordinator {
private weak var track: RTCVideoTrack?
func update(track newTrack: RTCVideoTrack?, renderer: RTCMTLNSVideoView) {
guard track !== newTrack else { return }
track?.remove(renderer)
track = newTrack
newTrack?.add(renderer)
}
func detach(renderer: RTCMTLNSVideoView) {
track?.remove(renderer)
track = nil
}
}
}
#endif