SpatialExternalSurface, uygulamanızın resim veya video gibi içerikler çizebileceği Surface öğesini oluşturan ve yöneten bir alt uzay bileşenidir. SpatialExternalSurface, stereoskopik veya monoskopik içerikleri destekler.
Resim veya video içeriği için yüzey ekleme
Bu örnekte, Media3 Exoplayer ve SpatialExternalSurface kullanarak yan yana stereoskopik videonun nasıl yükleneceği gösterilmektedir:
@OptIn(ExperimentalComposeApi::class) @Composable fun SpatialExternalSurfaceContent() { val context = LocalContext.current Subspace { SpatialExternalSurface( modifier = SubspaceModifier .width(1200.dp) // Default width is 400.dp if no width modifier is specified .height(676.dp), // Default height is 400.dp if no height modifier is specified // Use StereoMode.Mono, StereoMode.SideBySide, or StereoMode.TopBottom, depending // upon which type of content you are rendering: monoscopic content, side-by-side stereo // content, or top-bottom stereo content stereoMode = StereoMode.SideBySide, ) { val exoPlayer = remember { ExoPlayer.Builder(context).build() } val videoUri = Uri.Builder() .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) // Represents a side-by-side stereo video, where each frame contains a pair of // video frames arranged side-by-side. The frame on the left represents the left // eye view, and the frame on the right represents the right eye view. .path("sbs_video.mp4") .build() val mediaItem = MediaItem.fromUri(videoUri) // onSurfaceCreated is invoked only one time, when the Surface is created onSurfaceCreated { surface -> exoPlayer.setVideoSurface(surface) exoPlayer.setMediaItem(mediaItem) exoPlayer.prepare() exoPlayer.play() } // onSurfaceDestroyed is invoked when the SpatialExternalSurface composable and its // associated Surface are destroyed onSurfaceDestroyed { exoPlayer.release() } } } }
Kodla ilgili önemli noktalar
- Oluşturduğunuz içerik türüne bağlı olarak
StereoModedeğeriniMono,SideBySideveyaTopBottomolarak ayarlayın:Mono: Resim veya video karesi, her iki göze de gösterilen tek bir aynı resimden oluşur.SideBySide: Resim veya video karesi, yan yana yerleştirilmiş bir çift resim veya video karesi içerir. Soldaki resim veya kare sol gözün görüşünü, sağdaki resim veya kare ise sağ gözün görüşünü temsil eder.TopBottom: Resim veya video karesi, dikey olarak üst üste yerleştirilmiş bir çift resim veya video karesi içerir. Üstteki resim veya kare sol göz görünümünü, alttaki resim veya kare ise sağ göz görünümünü temsil eder.
SpatialExternalSurfaceyalnızca dikdörtgen yüzeyleri destekler.- Bu
Surface, giriş etkinliklerini yakalamaz. StereoModedeğişikliklerini uygulama oluşturma veya video kod çözme ile senkronize etmek mümkün değildir.- Bu composable, diğer panellerin önünde oluşturulamadığından düzende başka paneller varsa
MovePolicykullanmamanız gerekir.
DRM korumalı video içeriği için yüzey ekleme
SpatialExternalSurface, DRM korumalı video akışlarının oynatılmasını da destekler. Bunu etkinleştirmek için korumalı grafik arabelleklerine dönüştürülen güvenli bir yüzey oluşturmanız gerekir. Bu sayede, içeriğin ekran kaydı alınamaz veya güvenli olmayan sistem bileşenleri tarafından içeriğe erişilemez.
Güvenli bir yüzey oluşturmak için SpatialExternalSurface composable'ında SpatialExternalSurfaceProtection parametresini SpatialExternalSurfaceProtection.Protected olarak ayarlayın. Ayrıca, bir lisans sunucusundan lisans alma işlemini gerçekleştirmek için Media3 Exoplayer'ı uygun DRM bilgileriyle yapılandırmanız gerekir.
Aşağıdaki örnekte, DRM korumalı bir video akışını oynatmak için SpatialExternalSurface ve ExoPlayer öğelerinin nasıl yapılandırılacağı gösterilmektedir:
@OptIn(ExperimentalComposeApi::class) @Composable fun DrmSpatialVideoPlayer() { val context = LocalContext.current Subspace { SpatialExternalSurface( modifier = SubspaceModifier .width(1200.dp) .height(676.dp), stereoMode = StereoMode.SideBySide, surfaceProtection = SpatialExternalSurfaceProtection.Protected ) { val exoPlayer = remember { ExoPlayer.Builder(context).build() } // Define the URI for your DRM-protected content and license server. val videoUri = "https://your-content-provider.com/video.mpd" val drmLicenseUrl = "https://your-license-server.com/license" // Build a MediaItem with the necessary DRM configuration. val mediaItem = MediaItem.Builder() .setUri(videoUri) .setDrmConfiguration( MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID) .setLicenseUri(drmLicenseUrl) .build() ) .build() onSurfaceCreated { surface -> // The created surface is secure and can be used by the player. exoPlayer.setVideoSurface(surface) exoPlayer.setMediaItem(mediaItem) exoPlayer.prepare() exoPlayer.play() } onSurfaceDestroyed { exoPlayer.release() } } } }
Kodla ilgili önemli noktalar
- Korumalı yüzey: Temel
Surface'nin DRM içeriğine uygun güvenli arabelleklerle desteklenmesi içinSpatialExternalSurfaceüzerindesurfaceProtection = SpatialExternalSurfaceProtection.Protectedayarının yapılması gerekir. - DRM Yapılandırması:
MediaItemöğesini DRM şeması (ör.C.WIDEVINE_UUID) ve lisans sunucunuzun URI'si ile yapılandırmanız gerekir. ExoPlayer, DRM oturumunu yönetmek için bu bilgileri kullanır. - Güvenli İçerik: Korunan bir yüzeyde oluşturma işlemi yapılırken video içeriğinin kodu çözülür ve güvenli bir yolda görüntülenir. Bu, içerik lisanslama şartlarının karşılanmasına yardımcı olur. Bu sayede içeriğin ekran görüntülerinde görünmesi de engellenir.