
-
visionOS 앱에서 몰입형 비디오 재생 지원하기
visionOS 앱에서 몰입형 비디오를 재생하는 방법을 알아보세요. 다양한 몰입형 렌더링 모드를 살펴보고, 이를 지원하는 프레임워크를 검토하며, 앱에서 몰입형 비디오를 렌더링하는 방법을 설명합니다. 이 비디오를 최대한 활용하려면 WWDC25에서 ‘visionOS를 위한 비디오 경험 살펴보기'를 먼저 시청하는 것이 좋습니다.
챕터
- 0:00 - 서론
- 1:24 - visionOS 26에서 지원되는 비디오 프로필
- 3:09 - Quick Look의 몰입형 비디오 재생
- 4:25 - AVKit을 통한 몰입형 비디오 재생
- 9:11 - 편안함 완화 감지
- 9:51 - RealityKit의 맞춤형 재생
- 11:48 - RealityKit의 점진적 몰입 모드
- 16:32 - RealityKit으로 공간 비디오 렌더링하기
- 21:16 - RealityKit의 편안함 완화 감지
- 22:57 - SwiftUI로 RealityKit 콘텐츠 통합하기
리소스
- AVFoundation
- AVKit
- HTTP Live Streaming Examples
- Playing immersive media with AVKit
- Playing immersive media with RealityKit
- RealityKit
관련 비디오
WWDC25
- 공간 웹의 새로운 기능
- Apple Immersive Video 기술에 대해 알아보기
- Apple Projected Media Profile 알아보기
- visionOS를 위한 비디오 경험 살펴보기
WWDC24
WWDC23
-
비디오 검색…
안녕하세요 저는 AVKit 팀의 미디어 애플리케이션 엔지니어인 Jamal입니다 저는 visionOS Spatial Media 팀의 SW 엔지니어 Michael입니다 제가 visionOS에서 가장 좋아하는 일은 비디오를 보는 것입니다 사용하는 플랫폼만의 독특한 방식으로요 visionOS 2에는 도킹 재생과 같은 놀라운 경험이 포함됩니다 공간 비디오도 마찬가지죠 visionOS 26에서는 모든 인기 미디어 프레임워크가 확장됐습니다 훑어보기, AVKit RealityKit과 같은 것들이죠 visionOS에서 더욱 몰입적인 미디어 프로필을 지원하고 훌륭한 몰입형 비디오 재생 경험을 선사하죠 오늘은 Jamal과 함께 애플리케이션에서 몰입형 비디오 재생을 지원하는 법을 알려드리죠 Jamal이 설명해 주겠습니다 고마워요, Michael 먼저, 다양한 유형의 비디오 프로필을 간략하게 살펴보겠습니다 그럼 AVKit에서 훑어보기와 새로운 API로 몰입형 미디어 재생을 지원하는 방법을 알려드릴게요 끝으로 Michael이 응용 프로그램을 통해 RealityKit으로 몰입형 재생 환경의 사용자 지정 방법을 알려 드리겠습니다 영상을 끝까지 보시면 visionOS 애플리케이션에서 몰입형 비디오 재생 경험을 구현하기 위해 필요한 핵심 정보를 모두 배우게 되실겁니다 visionOS 26에서 지원되는 다양한 유형의 비디오 프로필을 검토하는 것으로 시작하겠습니다
visionOS 1에서 애플리케이션의 주된 비디오 재생 방식은 2D/3D 비디오였습니다 공간 미디어를 통해 사람들은 매력적인 스테레오 콘텐츠를 촬영하고 창작물에 몰입했죠 visionOS 26에는 이제 180도 360도, 와이드 뷰 비디오를 위한 Apple Projected Media Profile 또는 APMP가 포함됩니다 궁극의 몰입형 경험을 위한 Apple Immersive Video도 있습니다 각 프로필은 독특함을 자랑합니다 관련 용어를 잘 모르신다면 “visionOS에서의 비디오 경험 탐색하기” 세션에서 알아보세요. 방금 나열한 모든 비디오 프로필을 지원하는 방법은 여러 가지가 있죠 이를 위해 애플리케이션에 적합한 기술을 선택하는 것은 뛰어난 몰입형 경험을 제공하는 데 중요합니다
훑어보기는 모든 종류의 미디어를 빨리 보는 이상적인 프레임워크죠 몰입형 미디어도 포함해서요 AVKit은 모든 플랫폼에서 친숙하고 일관된 비디오 경험을 제공합니다 동시에 재생 경험을 위한 향상된 제어 기능을 제공합니다 RealityKit은 독특한 몰입형 재생 경험이 필요한 애플리케이션을 위해 설계되었죠 비디오 게임 환경의 유형처럼요 마지막으로, 브라우저에서 몰입형 재생을 지원하려면 “공간 웹의 새로운 기능” 세션을 확인하세요 웹 콘텐츠의 몰입형 재생에 대한 자세한 설명을 들을 수 있습니다
그 후 visionOS 26에서 훑어보기와 AVKit에 사용하는 도구를 검토해 시작하실 수 있도록 도와드립니다 몰입형 비디오 재생 애플리케이션을 만들어보세요 훑어보기의 API 2개는 앱에서 신속 표시/미리 보기를 지원하죠 PreviewApplication API는 미디어 프레젠테이션용 프로세스 외부 창을 활성화하는 API입니다 앱 창에서 또는 모달 프레젠테이션 스타일로 미디어를 미리 보는 API인 QLPreviewController가 있죠 visionOS 26에서는 QLPreviewController가 향상되어 공간 사진과 비디오를 지원하죠 이와 함께 PreviewApplication은 이제 Apple Immersive Video와 Apple Projected Media Profile을 지원합니다 180도, 360도 및 와이드 뷰 비디오를 지원하죠
QLPreviewController와 PreviewApplication은 새 비디오 프로필의 프레젠 테이션과 전환을 관리할 수 있죠 또한 적절한 비디오 스타일로 미리 보기를 조정합니다 visionOS 26에서는 훑어보기 API를 이미 구현한 모든 애플리케이션이 자동으로 몰입형 미디어 프로필을 지원합니다 PreviewApplication 또는 QLPreviewController API를 구현하는 방법에 대해 자세히 알아보려면 WWDC23의 “공간 컴퓨팅을 위한 Quick Look 살펴보기” 비디오와 WWDC24의 “visionOS용 훑어보기의 새로운 기능”을 살펴보세요 다음으로 새로운 AVKit API에 대해 살펴보겠습니다 몰입형 비디오 재생을 완벽하게 지원하기 위해 도입했습니다 visionOS 26에서는 AVExperienceController API가 새로운 몰입형 경험으로의 전환을 달성하는 데 활용됩니다 AVExperienceController로 몰입형 경험으로의 전환을 하는 데에는 다양한 옵션이 있습니다 첫 번째 옵션은 Expanded을 사용하는 것입니다 Expanded 환경은 AVPlayerViewController를 UI 창 장면 전체를 사용하도록 허용합니다 이제 visionOS 26에서는 Expanded 기능을 구성하여 몰입형 비디오 재생을 구현할 수 있습니다 확장된 구성의 새로운 기능으로서 AutomaticTransitionToImmersive 속성을 사용해 자동 전환이 수행되는지 여부를 결정할 수 있습니다 몰입형 경험을 시작하죠 AutomaticTransitionToImmersive 속성을 사용해 시스템의 기본 동작이 선호될 때 기본값을 설정하고 아니면 아무것도 없을 때 자동 전환을 설정할 수 있습니다
몰입형 속성으로 자동 전환하기 위해 값으로 none을 설정하면 AVPlayerViewController로 하여금 몰입형 콘텐츠가 감지될 때 포털 처리를 허용할 수 있죠 동시에 Expanded 경험에서 AVExperienceController를 유지하죠 몰입형 경험으로의 전환을 자동 비활성화 하는 예는 다음과 같죠 몰입형 콘텐츠에 대해 포털 처리를 해야 할 때 말이죠 먼저 AVPlayerViewController를 생성해 몰입형 미디어 콘텐츠용으로 설정하겠습니다 그리고 experienceController에 추천 셋을 추가합니다 플랫폼에 적절한 경험을 포함하죠 Expanded을 보장하는 동안 말이죠 몰입형은 그 일부입니다 AutomaticTransitionToImmersive 속성이 초기 기본값이라는 것을 감안하여 이제 해당 속성의 값을 .none으로 지정해야 합니다 AVPlayerViewController가 응용 프로그램 보기 계층 구조에 있음을 이미 가정했기 때문이죠 AVExperienceController을 Expanded 경험에 전환할 준비가 되었습니다 새로운 Immersive API가 AVExperienceController 경험의 일부일 때, 이 경험으로 명시적으로 전환이 가능합니다 그저 자동 트리거에 의존하는 대신 말이죠 Expanded에서 한 것과 똑같습니다
몰입형 경험 API는 새로운 구성 API가 함께 제공되죠 앱이 어디에서 몰입형 비디오 재생 경험을 배치할지 정의할 수 있습니다 이 코드 조각은 구성 API로 몰입형 경험을 활용하는 방법을 보여줍니다 AVPlayerViewController가 뷰 계층에 추가되지 않았다고 가정해 구성 API로 이것을 지정해야 합니다 경험 컨트롤러 구성에 액세스하여 이를 수행하고 원하는 윈도우 UI 장면에 사용할 .over 함수에 배치 값을 제공합니다 일단 정의되면 AVExperienceController가 몰입형 경험으로 전환 준비가 됐죠 AVPlayerViewController가 이미 뷰 계층에 포함된 경우 AVExperienceController는 그것이 포함된 창 장면이 원하는 배치 장면인 것으로 가정합니다 이것이 바로 애플리케이션을 AVKit을 통해 몰입형 경험으로 전환하는 방법입니다 몰입형 경험에서 또는 몰입형 경험으로 전환 시 AVExperienceController가 애니메이션을 처리하고 경험 간에 전환합니다 이러한 전환은 언제든지 시작될 수 있습니다 사용자, 애플리케이션 로직 또는 시스템에 의해 시작되죠
따라서 AVExperienceController를 사용 시 전환이나 프레젠테이션 상태 변경을 모두 이해 해야죠 이렇게 하면 유연성이 생겨 응용 프로그램 활성 상태를 적절하게 처리할 수 있습니다 여기에 AVExperienceController의 Delegate Protocol이 솔루션이죠 프로토콜에는 3개의 대리자 메서드가 있습니다 didChangeAvailableExperiences는 사용 가능한 환경이 변경되었을 때 알림을 제공합니다 prepareForTransitionUsing은 AVExperienceController가 전환되려고 할 때 알림을 보내 앱이 마지막으로 준비하여 새로운 상태에 대비할 수 있습니다 그리고 didChangeTransitionContext는 새로운 환경으로의 전환이 완료되면 알림을 보냅니다
몰입형 경험은 제공되는 콘텐츠 유형에 따라 달라집니다 didChangeAvailableExperiences 메서드를 사용해 현 콘텐츠 유형에도 몰입형 경험이 가능한지 확인합니다 예를 들어, 2D 미디어 콘텐츠가 AVPlayerViewController에 제공되는 경우 몰입형 경험은 제공되지 않습니다 AVExperienceController와 위임 메서드 활용법에 대해 알고 싶다면 “AVKit를 사용하여 몰입형 미디어 재생하기” 샘플 코드를 보세요 이제 visionOS 26에서 몰입형 비디오 재생용 새 API 외에도 훑어보기와 AVKit는 불편감 완화 감지를 지원하죠 몰입형 비디오는 상당한 카메라 움직임을 보여줄 수 있어 시청자에게 불편함을 줄 수 있습니다 이 문제를 해결하기 위해 Apple Projected Media Profiles 콘텐츠에 동작 감지가 지원됩니다 이제 QuickLook과 AVKit가 재생 중에 높은 모션을 감지하죠 자동으로 몰입 수준을 낮습니다 시청자가 설정 앱에서 옵션을 조정할 수 있어 훑어보기와 AVKit가 시청자가 원하는 대로 정확하게 동작합니다 몰입감 높은 비디오 재생 경험을 제공하는 데에는 훑어보기와 AVKit가 참 유용합니다 더욱 맞춤화된 몰입형 경험을 바란다면 RealityKit가 이상적입니다 그 이유는 Michael이 설명해 드리겠습니다 고마워요, Jamal 네, RealityKit는 사용자 지정 비디오 재생에 맞는 프레임워크죠 몰입형 게임에 비디오를 포함하는 것과 같죠 또는 사용자 정의 인터페이스로 비디오를 렌더링하는 것과 같죠 visionOS 26에서는 RealityKit가 몰입형 비디오의 기본 재생입니다 이 섹션에서는 180도, 360도 그리고 와이드 뷰 영상과 Apple Immersive Video에 대한 새 진행형 몰입 모드를 살펴보시죠 그리고 전체 공간 스타일링을 갖춘 공간 비디오 렌더링도 보겠습니다 사진 앱처럼요 또한 비디오 불편감 완화책 적용을 감지하는 방법도 보여드리겠습니다 마지막으로, RealityKit를 사용하여 SwiftUI 장면에서 비디오를 재생하는 방법에 대해 알아보겠습니다 VideoPlayerComponent는 RealityKit의 강력한 비디오 렌더링 API입니다 RealityKit 엔티티에 첨부된 경우 자체 메시와 머티리얼을 생성합니다 AVPlayer의 현재 비디오와 구성 요소의 속성을 기반으로 하죠 VideoPlayerComponent가 몰입형 시청 모드로 비디오를 렌더링하는 데 이상적인 이유죠 메시 업데이트와 애니메이션이 자동으로 처리되기 때문입니다 developer.apple.com/kr/의 Destination Video 프로젝트에 이 비디오 도킹 예와 같습니다 “RealityKit 으로 공간 컴퓨팅 앱 강화하기”에서 VideoPlayerComponent에 대한 소개를 살펴보세요
visionOS 26에 VideoPlayerComponent는 이제 훑어보기와 AVKit가 지원하는 모든 동일한 몰입형 비디오 프로필을 지원합니다 Apple Projected Media Profile 비디오와 Apple Immersive Video로 시작하겠습니다 VideoPlayerComponent는 이 비디오 프로필에 세 가지 몰입형 모드를 지원합니다 포털 모드는 창 형식의 표현을 위해 비디오를 포털로 렌더링하죠 프로그레시브 모드는 Digital Crown으로 몰입 수준을 직접 조절하는 새 API입니다 주변 세계와 연결될 수 있도록 허용하죠 계속해서 영상을 즐기면서요 그리고 100% 몰입 상태에서 진행형 모드는 완전 몰입형 시청 모드와 동일합니다
visionOS 26부터는 Apple Projected Media Profile 비디오와 Apple Immersive Video에서는 전체 몰입형 시청 모드보다 점진적 모드가 더 선호됩니다 추가적인 유연성을 제공하고 불편감 완화를 지원하기 위해서죠 나중에 더 자세히 다루겠습니다 여기서는 포털 모드에서 180도 비디오를 렌더링하는 뷰를 만들고 공유 공간의 WindowGroup에 배치하겠습니다 포털 재생을 구성하려면 먼저 AVPlayerItem과 AVPlayer를 생성하는데 로컬 URL 또는 HTTP Live Streaming URL를 통해 플레이어로 VideoPlayerComponent를 초기화하죠 구성 요소의 desiredImmersiveViewingMode를 포털로 설정하고 구성 요소를 엔터티에 연결합니다 VideoPlayerComponent 메시의 높이는 기본적으로 1미터입니다 비디오 크기를 0.4미터로 조정해 SwiftUI 창 장면에 맞게 조정하고 마지막으로 엔터티를 장면에 추가합니다 이 비디오를 렌더링하려면 프로그레시브 모드를 사용하고 구성 요소의 desiredImmersiveViewingMode를 포털에서 프로그레시브로 설정합니다 프로그레시브 모드에서는 구성 요소가 규모를 제어하므로 스케일 작업은 효과가 없습니다 깔끔하게 하기 위해 이를 삭제하겠습니다 SwiftUI 장면을 렌더링할 때는 구성 요소를 프로그레시브로 업데이트하는 것으로는 부족합니다 메시가 확장될 때 창 장면 경계의 클리핑을 방지하려면 ImmersiveSpace에 새로운 ProgressiveVideoView를 넣습니다 그리고 프로그레시브 모드로 렌더링할 때 ImmersiveSpace는프로그레시브 몰입 스타일이어야 합니다 여기서 초기 몰입 수준은 1이며 전체 몰입에 해당합니다 저는 10%에서 100%까지 넓은 범위를 선택했습니다 사용자가 직접 몰입 수준을 정할 수 있습니다 0%이 있었다면 몰입이 사라질 때까지 다이얼을 낮출 수 있었겠죠 제 앱에 알맞은 동작은 아닙니다 SwiftUI의 ImmersionStyle과 구성 요소의 몰입형 시청 모드는 재생을 구성하는 데 중요합니다 RealityView 렌더링 시에는 항상 desiredImmersiveViewingMode와 ImmersionStyle가 일치하도록 구성해야 합니다 몰입 스타일에 대한 더 많은 정보를 원한다면 2024년 영상 “볼륨 및 몰입형 공간 자세히 알아보기”를 보세요 포털과 프로그레시브 모드 간 전환을 위해서는 SwiftUI 장면 전환 시 ImmersiveViewingModeDidChange 이벤트를 기다리죠 ImmersiveViewingModeWillTransition 및 DidTransition 이벤트는 애니메이션 전환 중 UI 가시성 전환 시, 신호를 보내 움직임과 스테레오 충돌을 줄입니다 이러한 이벤트가 실제로 수행되는 예를 보려면 developer.apple.com/kr/에서 RealityKit 샘플 코드로 몰입형 미디어 플레이하기를 살펴보세요 Apple Projected Media Profile 비디오 및 Apple Immersive Video 포털 렌더링을 검토합니다 desiredImmersiveViewingMode를 포털로 설정합니다 포털은 일반적으로 공유 공간의 SwiftUI WindowGroup에 있습니다 하지만 혼합된 몰입형 스타일의 몰입형 공간에서는 전용일 수 있죠 몰입형 렌더링의 경우 desiredImmersiveViewingMode를 프로그레시브로 설정하고 프로그레시브 ImmersionStyle인 ImmersiveSpace에 둡니다 이전에 작성한 코드와 같습니다 선호하는 시스템 동작을 얻으려면 desiredViewingMode를 켜지 마세요 viewingMode는 단안 영상에 대해 자동으로 모노가 되며, 스테레오는 스테레오 180 및 Apple Immersive video처럼 스테레오 비디오에 쓰죠 공간 비디오는 사람들이 좋아하는 스테레오 영상입니다 Apple 생태계 전반에서 이미 포착하셨을 수도 있어요 여기에는 더 편안하고 몰입감 있는 렌더링을 하는 공간 메타데이터가 있죠 Apple Projected Media Profile 비디오와 Apple Immersive Video와 같이 공간 비디오는 이제 RealityKit 에서 기본적으로 지원되며 전체 공간 스타일링 및 몰입형 모드로 렌더링합니다
공간 비디오를 위한 공간 스타일링이 구성되었으며 VideoPlayerComponent에 원하는 SpatialVideoMode 속성으로 구성됩니다 이 속성을 설정하여 공간 비디오를 렌더링하는 방법을 지정합니다 get-only spatialVideoMode 속성을 읽고 공간적 비디오가 어떻게 렌더링되는지 확인하세요 공간 비디오에 대한 공간 스타일링을 선택하려면 desiredSpatialVideoMode를 .spatial로 설정합니다
공간 렌더링은.portal 및 .full ImmersiveViewingModes를 모두 지원하죠 다른 몰입형 비디오 유형과 달리 공간 비디오 몰입형 렌더링은 항상 전체 몰입형 시청 모드로 구성됩니다 몰입형 공간 비디오는 고정된 크기로 렌더링되며 콘텐츠의 시야를 기준으로 합니다
desiredSpatialVideoMode를 기본값인 .screen으로 설정해 화면 메시에서 기존 스테레오로 공간 비디오를 렌더링합니다 SpatialVideoMode는 현재 비디오가 유효한 공간 비디오여야 업데이트됩니다 이름에서 알 수 있듯이 이 모드는 공간 비디오에만 적용됩니다 새로운 VideoPlayerEvent인 SpatialVideoModeDidChange를 구독하거나 'spatialVideoMode 속성을 직접 관찰합니다 spatialVideoMode 속성이 업데이트 및 시점을 확인 가능하기 때문이죠
포털 모드에서 공간 비디오로 렌더링하려면 먼저 공간 비디오가 있는 AVPlayer 로 VideoPlayerComponent를 만듭니다 desiredViewingMode를 스테레오로 설정합니다 이는 공간 비디오의 기본값이지만 명확하게 표현하려고 합니다 그 후 desiredSpatialVideoMode를 공간으로 설정합니다 원하는 ImmersiveViewingMode로 포털을 선택합니다 이전과 마찬가지로, 비디오 크기를 창 크기에 맞게 조정합니다 공간 모드에서는 몰입형 뷰 모드를 최대로 설정해 비디오를 확장할 수 있습니다 또한 스케일링 작업도 제거하겠습니다 몰입형 프레젠테이션 중에 구성 요소가 크기를 제어하기 때문이죠 이전에 예로 들었던 것처럼 클리핑을 방지하려면 뷰가 ImmersiveSpace에 있어야 합니다 몰입형 공간 비디오 렌더링은 다른 몰입형 비디오 유형과 같은 방식으로 헤드락되지 않습니다 그러면 엔티티의 위치를 설정해야 합니다 바닥에서 1.5미터 위, 1미터 앞을 선택하겠습니다 하지만 더 강력한 솔루션을 위해서는 헤드 앵커를 사용하여 엔터티를 뷰어 앞의 위치로 초기화합니다 마지막으로 ImmersiveSpatialVideoView를 ImmersiveSpace로 래핑하겠습니다 공간 비디오의 경우 혼합 ImmersionStyle을 사용해 패스스루를 통해 몰입형 모드를 렌더링합니다 공간 비디오가 시스템 환경에서도 렌더링되도록 하고 싶은데요, 이럴 땐 새 immersiveEnvironmentBehavior 장면 수정자, 공존 옵션을 함께 쓰세요
공간 비디오 포털을 검토하려면 원하는 SpatialVideoMode를 공간으로 구성해야 합니다 이후 공유 공간 또는 혼합된 ImmersionStyle 로 된 ImmersiveSpace에서 포털의 desiredImmersiveViewingMode를 구성해야 하죠 공간 비디오의 경우 시청 모드는 기본적으로 스테레오로 설정됩니다 공간 비디오 몰입 모드는 원하는 ImmersiveViewingMode를 전체 설정하죠 혼합된 ImmersionStyle로 ImmersiveSpace를 구성해 패스스루를 통해 렌더링합니다
공간 스타일링 없이 전통적인 스테레오로 렌더링하려면 desiredSpatialVideoMode를 화면으로 설정합니다 몰입형 시청 모드는 이 모드에서는 효과가 없습니다 공간 비디오는 또한 단안적으로 렌더링할 수 있습니다 모노 desiredViewingMode를 사용하면 되죠 이 모드에서 SpatialVideoMode나 ImmersiveViewingMode는 무효합니다 이러한 비몰입형 모드는 보통 공유 공간의 WindowGroup에 있죠 몰입형 비디오를 시청하는 것은 매우 몰입적인 경험입니다 즉, 영상 속 움직임이 많을 경우 재생이 매우 민감해질 수 있습니다 따라서 Apple Projected Media Profile 비디오의 경우 RealityKit는 재생 중에 자동으로 불편감 완화를 수행합니다 Jamal이 AVKit와 훑어보기에 대해 설명한 것과 같습니다
새 VideoComfortMitigationDidOccur 이벤트는 시스템에 의해 불편감 완화가 적용될 때 신호를 보냅니다 영상 속 움직임이 격할 때 반응하는 동작이죠 이 이벤트를 수신한 후에는 아무런 조치가 필요하지 않습니다 이는 단순히 특정 완화 조치가 적용되었다는 신호일 뿐입니다 reducedImmersion 완화는 진행형 렌더링 중에만 사용할 수 있습니다 그렇기 때문에 진행형 몰입형 시청 모드를 사용하는 것이 중요합니다 Apple Projected Media Profile 비디오는 전체 스타일 대신 몰입형을 쓰죠 포털 렌더링 중에는 완화가 발생하지 않습니다 포털 재생이 이미 대부분의 콘텐츠 시청에 편안하기 때문입니다 VideoPlayerComponent의 지원되는 동작 및 렌더링 스타일은 제시되는 특정 비디오 프로필에 따라 달라집니다 ContentTypeDidChange 이벤트를 사용해 VideoPlayerComponent에서 비디오 종류를 감지합니다 Apple Projected Media Profile 비디오처럼 새 유형을 포함하죠 비디오 유형이 변경될 때마다 반응합니다 어떤 시청 모드가 사용 가능한지 이해하기 위해서죠 불편감 완화나 UI 요소 업데이트 적용을 위해서요 VideoPlayerComponent 가 UI와 결합되거나 단순히 SwiftUI 장면에 표현된 경우 RealityKit 콘텐츠와 SwiftUI의 원활한 통합에 대한 팁이 있습니다 예를 들어 UI 옆에 미디어를 배치할 때에는 메시 크기 관리가 중요합니다 포털 모드에서는 playerScreenSize 속성에 의해 메시 크기가 반영되죠 엔터티의 로컬 좌표 공간에서 말이죠 포털 메시는 항상 높이 1미터로 만들어집니다 비디오 엔터티를 확장할 때 종횡비를 유지하기 위해 항상 X와 Y를 균일하게 조정합니다 창 장면에 1미터보다 낮은 높이가 있는 경우 메시가 장면 경계에 의해 잘릴 것입니다 해당 엔터티의 규모가 축소되지 않는 한 말이죠 장면에 맞게 비디오 크기를 조정하려면 GeometryReader3D를 사용해 창 크기에 따라 크기를 설정합니다 developer.apple.com/kr/에서 “RealityKit로 몰입형 미디어 재생하기” 샘플 프로젝트를 다시 참고해서 장면에 맞는 비디오 포털 스케일링의 예를 살펴보세요
또한 정렬에 대에 말씀드릴 점은 비디오 메시와 동일 평면에 있는 사용자 정의 UI에는 미정의된 정렬 동작이 있다는 것입니다 VideoPlayerComponent가 있는 동일 엔터티에 ModelSortGroupComponent를 추가하세요 그리고 planarUIPlacement 범주를 정의하는 ModelSortGroup을 사용해 동일 평면 UI에 대하여 엔터티를 명시적으로 정렬합니다 QuickLook이든 AVKit 또는 RealityKit이든 몰입형 비디오 재생에 사용할 프레임워크를 선택해 보세요 구축할 수 있는 도구를 갖추었으니 앱에 놀라운 경험을 더해 보세요
앱에서 몰입감 넘치는 경험을 만들어 보세요 360 APMP 비디오를 몰입형 게임에 추가하거나 Apple Immersive Video나 공간 비디오 등을 사용할 수도 있죠 새로운 APMP 비디오 유형을 살펴보려면 “Apple Projected Media Profile 알아보기” 비디오를 시청하세요 Apple Immersive Video에 대해 더 알고 싶으면 “Apple Immersive Video 기술에 대해 알아보기”를 시청하세요 이제 놀라운 몰입형 비디오 경험을 만들어 보세요!
-
-
5:03 - AVExperienceController - AutomaticTransitionToImmersive
struct ExpandedConfiguration { enum AutomaticTransitionToImmersive { case `default` case none } }
-
5:50 - Disable Automatic Transitions to immersive
import AVKit let controller = AVPlayerViewController() let experienceController = controller.experienceController experienceController.allowedExperiences = .recommended(including: [.expanded, .immersive]) experienceController.configuration.expanded.automaticTransitionToImmersive = .none await experienceController.transition(to: .expanded)
-
6:26 - AVExperienceController - Immersive
enum Experience { case immersive } struct Configuration { struct Placement { static var unspecified: Placement static func over(scene: UIScene) -> Placement } }
-
6:53 - Transition to immersive
import AVKit let controller = AVPlayerViewController() let experienceController = controller.experienceController experienceController.allowedExperiences = .recommended(including: [.immersive]) let myScene = getMyPreferredWindowUIScene() experienceController.configuration.placement = .over(scene: myScene) await experienceController.transition(to: .immersive)
-
8:13 - AVExperienceController.Delegate
func experienceController(_ controller: AVExperienceController, didChangeAvailableExperiences availableExperiences: AVExperienceController.Experiences) func experienceController(_ controller: AVExperienceController, prepareForTransitionUsing context: AVExperienceController.TransitionContext) async func experienceController(_ controller: AVExperienceController, didChangeTransitionContext context: AVExperienceController.TransitionContext)
-
12:52 - PortalVideoView
@main struct ImmersiveVideoApp: App { var body: some Scene { WindowGroup { PortalVideoView() } } }
-
13:03 - Portal Rendering
import AVFoundation import RealityKit import SwiftUI struct PortalVideoView: View { var body: some View { RealityView { content in guard let url = URL(string: "https://cdn.example.com/My180.m3u8") else { return } let player = AVPlayer(playerItem: AVPlayerItem(url: url)) let videoEntity = Entity() var videoPlayerComponent = VideoPlayerComponent(avPlayer: player) videoPlayerComponent.desiredImmersiveViewingMode = .portal videoEntity.components.set(videoPlayerComponent) videoEntity.scale *= 0.4 content.add(videoEntity) } } }
-
13:57 - Progressive Immersion Rendering
import AVFoundation import RealityKit import SwiftUI struct ProgressiveVideoView: View { var body: some View { RealityView { content in guard let url = URL(string: "https://cdn.example.com/My180.m3u8") else { return } let player = AVPlayer(playerItem: AVPlayerItem(url: url)) let videoEntity = Entity() var videoPlayerComponent = VideoPlayerComponent(avPlayer: player) videoPlayerComponent.desiredImmersiveViewingMode = .progressive videoEntity.components.set(videoPlayerComponent) content.add(videoEntity) } } }
-
14:20 - ProgressiveVideoView
import AVFoundation import RealityKit import SwiftUI @main struct ImmersiveVideoApp: App { var body: some Scene { ImmersiveSpace { ProgressiveVideoView() } .immersionStyle(selection: .constant(.progressive(0.1...1, initialAmount: 1.0)), in: .progressive) } }
-
17:22 - SpatialVideoMode
if let vpc = components.get[VideoPlayerComponent.self] { vpc.desiredSpatialVideoMode = .spatial }
-
18:32 - Spatial Video Portal Rendering
import AVFoundation import RealityKit import SwiftUI struct PortalSpatialVideoView: View { var body: some View { RealityView { content in let url = Bundle.main.url(forResource: "MySpatialVideo", withExtension: "mov")! let player = AVPlayer(url: url) let videoEntity = Entity() var videoPlayerComponent = VideoPlayerComponent(avPlayer: player) videoPlayerComponent.desiredViewingMode = .stereo videoPlayerComponent.desiredSpatialVideoMode = .spatial videoPlayerComponent.desiredImmersiveViewingMode = .portal videoEntity.components.set(videoPlayerComponent) videoEntity.scale *= 0.4 content.add(videoEntity) } } }
-
19:02 - Spatial Video Immersive Rendering
import AVFoundation import RealityKit import SwiftUI struct PortalSpatialVideoView: View { var body: some View { RealityView { content in let url = Bundle.main.url(forResource: "MySpatialVideo", withExtension: "mov")! let player = AVPlayer(url: url) let videoEntity = Entity() var videoPlayerComponent = VideoPlayerComponent(avPlayer: player) videoPlayerComponent.desiredViewingMode = .stereo videoPlayerComponent.desiredSpatialVideoMode = .spatial videoPlayerComponent.desiredImmersiveViewingMode = .full videoEntity.position = [0, 1.5, -1] videoEntity.components.set(videoPlayerComponent) content.add(videoEntity) } } }
-
19:46 - ImmersiveSpatialVideoView
import AVFoundation import RealityKit import SwiftUI @main struct SpatialVideoApp: App { var body: some Scene { ImmersiveSpace { ContentSimpleView() } .immersionStyle(selection: .constant(.mixed), in: .mixed) .immersiveEnvironmentBehavior(.coexist) } }
-
21:40 - Comfort Mitigation Event
switch event.comfortMitigation { case .reduceImmersion: // Default behavior break case .play: // No action break case .pause: // Show custom pause dialog break }
-
-
- 0:00 - 서론
이 비디오에서는 AVKit의 새로운 API와 몰입형 비디오 재생을 위한 Quick Look에 대해 다루고 RealityKit을 사용하여 몰입형 재생 환경을 사용자 지정하는 방법에 대해 자세히 설명합니다.
- 1:24 - visionOS 26에서 지원되는 비디오 프로필
visionOS 26에서는 180, 360, Wide FOV 비디오를 위한 APMP와 궁극의 몰입형 경험을 위한 Apple Immersive Video와 같은 새로운 비디오 프로필이 도입되었습니다. Quick Look, AVKit 또는 RealityKit을 활용하여 앱에서 재생할 수 있습니다.
- 3:09 - Quick Look의 몰입형 비디오 재생
visionOS 26의 Quick Look은 두 가지 API를 제공합니다. 바로 프로세스 외부 미디어 프레젠테이션을 위한 PreviewApplication과 앱 내 미디어 미리보기를 위한 QLPreviewController입니다. 두 API 모두 공간 사진 비디오, Apple Immersive Video, Apple Projected Media Profile을 지원하도록 업데이트되었습니다. 앱에서 이미 Quick Look API를 사용하고 있다면 이러한 새로운 몰입형 미디어 프로필을 자동으로 지원하게 됩니다.
- 4:25 - AVKit을 통한 몰입형 비디오 재생
AVKit은 확장형 및 몰입형 등 두 가지 주요 경험을 제공하는 ‘AVExperienceController’를 소개합니다. 이제 자동 전환을 비활성화하는 옵션과 함께 몰입형 재생을 위한 확장된 환경을 구성할 수 있습니다. 이를 통해 감지되면 몰입형 콘텐츠에 대한 ‘포털 처리’가 가능합니다. 새로운 Immersive experience API를 사용하여 몰입형 경험으로 명시적으로 전환하여 몰입형 비디오 재생의 배치를 정의하는 구성 API를 제공합니다. ‘AVExperienceController’는 경험 간의 애니메이션과 전환을 처리합니다. 컨트롤러의 델리게이트 프로토콜은 전환 및 표현 상태 변경을 모니터링하고 앱이 다양한 콘텐츠 유형과 사용자 상호작용에 적절하게 적응하도록 하는 데 필수적입니다.
- 9:11 - 편안함 완화 감지
visionOS 26에서는 Quick Look 및 AVKit에서 몰입형 비디오에 대한 편안함 완화 감지 기능을 도입합니다. 이 시스템은 시청자가 불편함을 느끼지 않도록 Apple Projected Media Profile 콘텐츠 중 움직임이 많은 콘텐츠 재생 시 몰입 수준을 자동으로 낮추며, 설정 앱에서 사용자 정의가 가능합니다.
- 9:51 - RealityKit의 맞춤형 재생
RealityKit은 visionOS에서 사용자 정의 몰입형 비디오 재생을 위한 필수 프레임워크이며, 특히 게임과 고유한 UI를 갖춘 앱에 적합합니다. visionOS 26에서 RealityKit의 VideoPlayerComponent는 180, 360, Wide FOV 형식을 포함한 몰입형 비디오의 기본 재생은 물론, Apple Immersive Video 및 사진 앱과 같은 공간 비디오 렌더링도 지원합니다. 이러한 구성 요소는 메시 업데이트와 애니메이션을 자동으로 처리하기 때문에 동적이고 몰입감 있는 비디오 경험을 만드는 데 이상적입니다.
- 11:48 - RealityKit의 점진적 몰입 모드
visionOS 26에서 ‘VideoPlayerComponent’는 Apple Projected Media Profile 및 Apple Immersive Video에 대한 세 가지 몰입형 모드를 지원합니다. 바로 포털형, 점진형, 전체형입니다. 포털 모드는 비디오를 포털에 표시합니다. visionOS 26의 새로운 기능인 점진형 모드를 사용하면 사용자가 Digital Crown을 사용하여 몰입도를 조절할 수 있고 편안함과 유연성이 뛰어납니다. 100% 전체 몰입형과 동일합니다. 재생을 구성하려면 ‘desiredImmersiveViewingMode’를 설정하세요. 점진형 모드의 경우, 점진형 ‘ImmersionStyle’과 함께 ‘ImmersiveSpace’를 사용하고 모드와 스타일을 일치시킵니다. 몰입형 시청 모드 이벤트는 전환하는 동안 UI 가시성을 전환할 시기를 알려 줍니다.
- 16:32 - RealityKit으로 공간 비디오 렌더링하기
RealityKit은 이제 기본적으로 공간 비디오를 지원하여 전체 공간 스타일링을 적용한 몰입형 렌더링이 가능합니다. ‘VideoPlayerComponent’의 ‘desiredSpatialVideoMode’ 속성을 사용하여 공간 스타일을 구성할 수 있습니다. 이 속성을 ‘.spatial’ 옵션으로 설정하면 공간 스타일링이 적용되어 ‘.portal’ 또는 ‘.full’ ImmersiveViewingModes 렌더링할 수 있습니다. ‘.full’ 모드는 콘텐츠의 시야에 따라 고정된 크기로 렌더링되는 몰입형 공간 비디오에 항상 사용됩니다. 기본 모드인 ‘.screen’은 화면 메시에서 전통적인 스테레오로 공간 비디오를 렌더링합니다. ‘SpatialVideoModeDidChange’ 이벤트를 구독하면 ‘spatialVideoMode’ 속성에 대한 업데이트를 모니터링할 수 있습니다. 공간 비디오 포털을 생성하려면 ‘desiredSpatialVideoMode’를 ‘.spatial’로 설정하고 ‘desiredImmersiveViewingMode’를 ‘.portal’로 설정합니다. 몰입형 공간 비디오 렌더링의 경우, 혼합된 몰입형 스타일과 ‘immersiveEnvironmentBehavior’에 대한 ‘coexist’ 옵션을 갖춘 ‘.full’ 모드를 사용하세요.
- 21:16 - RealityKit의 편안함 완화 감지
RealityKit은 Apple Projected Media Profile 비디오에서 격렬한 움직임을 자동으로 감지하고 편안함 완화를 적용합니다. 앱은 ‘VideoComfortMitigationDidOccur’ 이벤트를 통해 이러한 조정 사항에 대해 알림을 받습니다. ‘reducedImmersion’ 완화를 위해서는 점진형 렌더링이 필요하고 포털형 렌더링은 대부분의 콘텐츠에 이미 편안하게 적용되기 때문에 점진형 렌더링이 필요하지 않습니다. ‘ContentTypeDidChange’ 이벤트는 다양한 비디오 유형과 그에 따른 특정 시청 모드 및 완화 요구 사항에 적응하는 데 도움이 됩니다.
- 22:57 - SwiftUI로 RealityKit 콘텐츠 통합하기
RealityKit의 VideoPlayerComponent를 SwiftUI와 통합할 때 특히 포털 모드에서 종횡비를 유지하기 위해 비디오 엔티티의 X축과 Y축의 크기를 균일하게 조정해야 합니다. ‘GeometryReader3D’를 사용하여 사용 가능한 창 크기에 따라 비디오 크기를 조정하여 클리핑을 방지합니다. 비디오 메시와 동일한 평면에서 사용자 지정 UI의 정렬 동작은 정의되지 않습니다. 동일한 평면에 있는 사용자 지정 UI의 정렬 문제를 해결하려면 ‘planarUIPlacement’ 카테고리가 있는 ‘ModelSortGroupComponent’를 추가합니다.