Когда представление загружается на устройство, у меня просто черный экран. У меня очень похожий код, работающий с экземпляром Storyboard и использующий UIViewController, но мне нужно уйти от этого, поскольку я работаю с VisionOS и хотел бы абстрагировать его до использования RealityKit и VideoPlayerLayer, но для прототипирования и итерации других задач я бы например, этот AVSampleBufferDisplayLayer для работы... что в конечном итоге мне придется передать AVSampleBufferVideoRenderer в VideoPlayerLayer, поэтому работа этой реализации помогает я погружаюсь в рендеринг RealityKit.
Вот код, я собрал все в один файл для удобства отладки и вопросов.
Спасибо ты!
struct MirrorView: View {
var body: some View {
VStack {
LayerView()
}
}
}
struct LayerView: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
print("LayerUIView is being created")
return LayerUIView()
}
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext) {
print("LayerUIView is being updated")
}
}
class LayerUIView: UIView {
private let networking = Networking()
private let displayLayer = AVSampleBufferDisplayLayer()
private var subscriptions = Set()
private var sampleBufferTask: Task?
override init(frame: CGRect) {
super.init(frame: frame)
print("LayerUIView initialized")
setupVideoLayer()
setupNetworking()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
layer.frame = bounds
}
private func setupVideoLayer() {
displayLayer.frame = bounds
displayLayer.videoGravity = .resizeAspect
layer.addSublayer(displayLayer)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleFailedToDecodeNotification(_:)),
name: .AVSampleBufferDisplayLayerFailedToDecode,
object: displayLayer
)
}
@objc private func handleFailedToDecodeNotification(_ notification: Notification) {
if let error = notification.userInfo?[AVSampleBufferDisplayLayerFailedToDecodeNotificationErrorKey] {
print("Failed to decode sample buffer. Error: \(error)")
} else {
print("Failed to decode sample buffer. No error information available.")
}
}
private func setupNetworking() {
networking.startAdvertising()
print("Networking is connected: \(networking.isConnected)")
startSampleBufferTask()
}
// MARK: - Task Management
private func startSampleBufferTask() {
sampleBufferTask = Task {
for await sampleBuffer in networking.sampleBuffers {
let formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer)
print("Format Description: \(String(describing: formatDescription))")
let presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
print("Presentation Timestamp: \(presentationTimeStamp)")
let duration = CMSampleBufferGetDuration(sampleBuffer)
print("Duration: \(duration)")
DispatchQueue.main.async {
self.displayLayer.sampleBufferRenderer.enqueue(sampleBuffer)
}
}
}
}
private func stopSampleBufferTask() {
sampleBufferTask?.cancel()
sampleBufferTask = nil
}
}
#Preview {
MirrorView()
}
Я создал версию UIKit и успешно загрузил ее как устройство iOS в AVP.
Вот ViewController, выполняющий этот код:
Вот ViewController, выполняющий этот код:
р>
class ViewController: UIViewController { //, VideoDecoderAnnexBAdaptorDelegate {
// MARK: - Properties
private let networking = Networking()
private let displayLayer = AVSampleBufferDisplayLayer()
private var subscriptions = Set()
private var sampleBufferTask: Task?
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupVideoLayer()
setupNetworking()
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .allButUpsideDown
}
override var shouldAutorotate: Bool {
return true
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { _ in
// Adjust layout for new orientation
self.displayLayer.frame = self.view.bounds
}, completion: nil)
}
// MARK: - Setup Methods
private func setupVideoLayer() {
displayLayer.frame = view.bounds
displayLayer.videoGravity = .resizeAspect
displayLayer.backgroundColor = UIColor.black.cgColor
view.layer.addSublayer(displayLayer)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleFailedToDecodeNotification(_:)),
name: .AVSampleBufferDisplayLayerFailedToDecode,
object: displayLayer
)
}
@objc private func handleFailedToDecodeNotification(_ notification: Notification) {
if let error = notification.userInfo?[AVSampleBufferDisplayLayerFailedToDecodeNotificationErrorKey] {
print("Failed to decode sample buffer. Error: \(error)")
} else {
print("Failed to decode sample buffer. No error information available.")
}
}
private func setupNetworking() {
networking.startAdvertising()
print("Networking is connected: \(networking.isConnected)")
startSampleBufferTask()
}
// MARK: - Task Management
private func startSampleBufferTask() {
sampleBufferTask = Task {
for await sampleBuffer in networking.sampleBuffers {
let formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer)
print("Format Description: \(String(describing: formatDescription))")
let presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
print("Presentation Timestamp: \(presentationTimeStamp)")
let duration = CMSampleBufferGetDuration(sampleBuffer)
print("Duration: \(duration)")
DispatchQueue.main.async {
self.displayLayer.sampleBufferRenderer.enqueue(sampleBuffer)
}
}
}
}
private func stopSampleBufferTask() {
sampleBufferTask?.cancel()
sampleBufferTask = nil
}
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... to-swiftui
Как передать UIViewRepresentable с AVSampleBufferDisplayLayer в SwiftUI ⇐ IOS
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
SwiftUI ScrollView не прокручивается до текстового поля при визуализации UIViewRepresentable
Anonymous » » в форуме IOS - 0 Ответы
- 27 Просмотры
-
Последнее сообщение Anonymous
-