Как передать UIViewRepresentable с AVSampleBufferDisplayLayer в SwiftUIIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Как передать UIViewRepresentable с AVSampleBufferDisplayLayer в SwiftUI

Сообщение Anonymous »

Когда представление загружается на устройство, у меня просто черный экран. У меня очень похожий код, работающий с экземпляром 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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как передать UIViewRepresentable с AVSampleBufferDisplayLayer в SwiftUI
    Anonymous » » в форуме IOS
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Как изменить размер CALayer (AVSampleBufferDisplayLayer), чтобы он соответствовал UIView, завернутый в SwiftUI
    Anonymous » » в форуме IOS
    0 Ответы
    28 Просмотры
    Последнее сообщение Anonymous
  • SwiftUi UIViewRepresentable не получает обновления состояний через EnvironmentObject или ObservedObject
    Гость » » в форуме IOS
    0 Ответы
    27 Просмотры
    Последнее сообщение Гость
  • SwiftUI ScrollView не прокручивается до текстового поля при визуализации UIViewRepresentable
    Anonymous » » в форуме IOS
    0 Ответы
    27 Просмотры
    Последнее сообщение Anonymous
  • AVSampleBufferDisplayLayer не дает iPhone спать
    Anonymous » » в форуме IOS
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous

Вернуться в «IOS»