From b1093ce3ceb16140e34fb9d2fcdb8b77ef2415df Mon Sep 17 00:00:00 2001 From: Mozart Louis <5649571+madebymozart@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:26:11 -0500 Subject: [PATCH] Vertical PageView Sample (#50) * Initial implementation over vertical videos using SurfaceView * Rename + add ability to preload Surfaces * update gradle + viewpager sample included --- TextureViewtoSurfaceView/app/build.gradle | 4 +- .../app/src/main/AndroidManifest.xml | 3 + .../textureview_surfaceview/MainActivity.kt | 6 + .../examples/multi/MultiViewVideoPlayer.kt | 3 +- .../examples/multi/MultiViewVideoPlayerHDR.kt | 3 +- .../MultiViewVideoPlayerHDRTransformer.kt | 6 +- .../examples/single/SurfaceViewVideoPlayer.kt | 3 +- .../verticalpager/HDRVerticalPager.kt | 55 ++++ .../verticalpager/HDRVerticalPagerAdapter.kt | 13 + .../HDRVerticalPagerExtensions.kt | 16 + .../HDRVerticalPagerFragmentInterface.kt | 7 + .../HDRVerticalPagerFragmentSurfaceView.kt | 92 ++++++ .../HDRVerticalPagerFragmentTextureView.kt | 83 ++++++ .../app/src/main/res/layout/activity_main.xml | 281 ++++++++++-------- ...ragment_hdr_vertical_pager_surfaceview.xml | 17 ++ ...ragment_hdr_vertical_pager_textureview.xml | 17 ++ .../main/res/layout/hdr_vertical_pager.xml | 18 ++ .../app/src/main/res/values/strings.xml | 5 +- TextureViewtoSurfaceView/build.gradle | 4 +- TextureViewtoSurfaceView/gradle.properties | 4 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- 21 files changed, 507 insertions(+), 135 deletions(-) create mode 100644 TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPager.kt create mode 100644 TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerAdapter.kt create mode 100644 TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerExtensions.kt create mode 100644 TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentInterface.kt create mode 100644 TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentSurfaceView.kt create mode 100644 TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentTextureView.kt create mode 100644 TextureViewtoSurfaceView/app/src/main/res/layout/fragment_hdr_vertical_pager_surfaceview.xml create mode 100644 TextureViewtoSurfaceView/app/src/main/res/layout/fragment_hdr_vertical_pager_textureview.xml create mode 100644 TextureViewtoSurfaceView/app/src/main/res/layout/hdr_vertical_pager.xml diff --git a/TextureViewtoSurfaceView/app/build.gradle b/TextureViewtoSurfaceView/app/build.gradle index 6c9a8d0..ec61b6f 100644 --- a/TextureViewtoSurfaceView/app/build.gradle +++ b/TextureViewtoSurfaceView/app/build.gradle @@ -5,12 +5,12 @@ plugins { android { namespace 'com.android.textureview_surfaceview' - compileSdk 33 + compileSdk 34 defaultConfig { applicationId "com.android.textureview_surfaceview" minSdk 24 - targetSdk 33 + targetSdk 34 versionCode 1 versionName "1.0" diff --git a/TextureViewtoSurfaceView/app/src/main/AndroidManifest.xml b/TextureViewtoSurfaceView/app/src/main/AndroidManifest.xml index ab01770..3d5fa8d 100644 --- a/TextureViewtoSurfaceView/app/src/main/AndroidManifest.xml +++ b/TextureViewtoSurfaceView/app/src/main/AndroidManifest.xml @@ -32,5 +32,8 @@ + \ No newline at end of file diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/MainActivity.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/MainActivity.kt index 5a2e518..56f2385 100644 --- a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/MainActivity.kt +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/MainActivity.kt @@ -10,6 +10,7 @@ import com.android.textureview_surfaceview.examples.multi.MultiViewVideoPlayerHD import com.android.textureview_surfaceview.examples.single.SurfaceViewVideoPlayer import com.android.textureview_surfaceview.examples.single.SurfaceViewVideoPlayerHDR import com.android.textureview_surfaceview.examples.single.TextureViewVideoPlayer +import com.android.textureview_surfaceview.examples.verticalpager.HDRVerticalPager class MainActivity : AppCompatActivity() { @@ -54,5 +55,10 @@ class MainActivity : AppCompatActivity() { val intent = Intent(this, MultiViewVideoPlayerHDRTransformer::class.java) startActivity(intent) } + + binding.hdrVerticalViewpagerButton.setOnClickListener { + val intent = Intent(this, HDRVerticalPager::class.java) + startActivity(intent) + } } } \ No newline at end of file diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayer.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayer.kt index 976a606..a607255 100644 --- a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayer.kt +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayer.kt @@ -8,10 +8,11 @@ import android.os.Bundle import android.view.Surface import android.view.SurfaceHolder import android.view.TextureView +import androidx.appcompat.app.AppCompatActivity import com.android.textureview_surfaceview.Constants import com.android.textureview_surfaceview.databinding.MultiViewPlayerBinding -class MultiViewVideoPlayer : Activity(), SurfaceHolder.Callback, +class MultiViewVideoPlayer : AppCompatActivity(), SurfaceHolder.Callback, TextureView.SurfaceTextureListener { private lateinit var binding: MultiViewPlayerBinding diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayerHDR.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayerHDR.kt index e110abc..0881055 100644 --- a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayerHDR.kt +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayerHDR.kt @@ -8,11 +8,12 @@ import android.os.Bundle import android.view.Surface import android.view.SurfaceHolder import android.view.TextureView +import androidx.appcompat.app.AppCompatActivity import com.android.textureview_surfaceview.Constants import com.android.textureview_surfaceview.databinding.MultiViewPlayerHdrBinding import com.android.textureview_surfaceview.decoder.CustomVideoDecoder -class MultiViewVideoPlayerHDR : Activity() { +class MultiViewVideoPlayerHDR : AppCompatActivity() { private lateinit var binding: MultiViewPlayerHdrBinding private lateinit var assetFile: AssetFileDescriptor diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayerHDRTransformer.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayerHDRTransformer.kt index facab50..3de6049 100644 --- a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayerHDRTransformer.kt +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/multi/MultiViewVideoPlayerHDRTransformer.kt @@ -10,6 +10,7 @@ import android.view.Surface import android.view.SurfaceHolder import android.view.TextureView import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity import androidx.media3.common.MediaItem import androidx.media3.common.util.UnstableApi import androidx.media3.transformer.* @@ -20,7 +21,7 @@ import com.android.textureview_surfaceview.decoder.CustomVideoDecoder import java.util.* @UnstableApi -class MultiViewVideoPlayerHDRTransformer : Activity(), SurfaceHolder.Callback, +class MultiViewVideoPlayerHDRTransformer : AppCompatActivity(), SurfaceHolder.Callback, TextureView.SurfaceTextureListener, Transformer.Listener { private lateinit var binding: MultiViewPlayerHdrTransformerBinding @@ -145,5 +146,4 @@ class MultiViewVideoPlayerHDRTransformer : Activity(), SurfaceHolder.Callback, "Fallback applied: $fallbackTransformationRequest" ) } -} - +} \ No newline at end of file diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/single/SurfaceViewVideoPlayer.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/single/SurfaceViewVideoPlayer.kt index 85b98b4..affa200 100644 --- a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/single/SurfaceViewVideoPlayer.kt +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/single/SurfaceViewVideoPlayer.kt @@ -5,10 +5,11 @@ import android.media.MediaPlayer import android.os.Bundle import android.util.Log import android.view.SurfaceHolder +import androidx.appcompat.app.AppCompatActivity import com.android.textureview_surfaceview.Constants import com.android.textureview_surfaceview.databinding.SurfaceViewPlayerBinding -open class SurfaceViewVideoPlayer : Activity(), SurfaceHolder.Callback { +open class SurfaceViewVideoPlayer : AppCompatActivity(), SurfaceHolder.Callback { protected lateinit var binding: SurfaceViewPlayerBinding private lateinit var mediaPlayer: MediaPlayer diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPager.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPager.kt new file mode 100644 index 0000000..348c3e6 --- /dev/null +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPager.kt @@ -0,0 +1,55 @@ +package com.android.textureview_surfaceview.examples.verticalpager + +import android.os.Bundle +import android.util.Log +import androidx.appcompat.app.AppCompatActivity +import androidx.viewpager2.widget.ViewPager2 +import com.android.textureview_surfaceview.databinding.HdrVerticalPagerBinding + +class HDRVerticalPager : AppCompatActivity() { + + private lateinit var binding: HdrVerticalPagerBinding + private lateinit var viewPager: ViewPager2 + private lateinit var adapter: HDRVerticalPagerAdapter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = HdrVerticalPagerBinding.inflate(layoutInflater) + setContentView(binding.root) + + /// Set up view pager & adapter + setUpViewPager2() + } + + private fun setUpViewPager2() { + viewPager = binding.hdrVerticalViewpager + viewPager.offscreenPageLimit = 1 + adapter = HDRVerticalPagerAdapter(this) + viewPager.adapter = adapter + + viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageScrollStateChanged(state: Int) { + if (state != ViewPager2.SCROLL_STATE_DRAGGING) { + Log.w("Testing", "Making the happen on " + viewPager.currentItem) + return + } + + val position = viewPager.currentItem + + viewPager.findFragmentAtPosition( + supportFragmentManager, + position - 1 + )?.let { + (it as HDRVerticalPagerFragmentInterface).setSurfaceViewVisibility(true) + } + + viewPager.findFragmentAtPosition( + supportFragmentManager, + position + 1 + )?.let { + (it as HDRVerticalPagerFragmentInterface).setSurfaceViewVisibility(true) + } + } + }) + } +} \ No newline at end of file diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerAdapter.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerAdapter.kt new file mode 100644 index 0000000..edb960c --- /dev/null +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerAdapter.kt @@ -0,0 +1,13 @@ +package com.android.textureview_surfaceview.examples.verticalpager + +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.viewpager2.adapter.FragmentStateAdapter +import androidx.viewpager2.widget.ViewPager2 + +class HDRVerticalPagerAdapter(activity: AppCompatActivity) : FragmentStateAdapter(activity) { + override fun getItemCount() = 3 + override fun createFragment(position: Int) = HDRVerticalPagerFragmentSurfaceView.newInstance(position) +} + diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerExtensions.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerExtensions.kt new file mode 100644 index 0000000..640ec2a --- /dev/null +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerExtensions.kt @@ -0,0 +1,16 @@ +package com.android.textureview_surfaceview.examples.verticalpager + +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.viewpager2.widget.ViewPager2 + +fun ViewPager2.findCurrentFragment(fragmentManager: FragmentManager): Fragment? { + return fragmentManager.findFragmentByTag("f$currentItem") +} + +fun ViewPager2.findFragmentAtPosition( + fragmentManager: FragmentManager, + position: Int +): Fragment? { + return fragmentManager.findFragmentByTag("f$position") +} \ No newline at end of file diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentInterface.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentInterface.kt new file mode 100644 index 0000000..de18d1e --- /dev/null +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentInterface.kt @@ -0,0 +1,7 @@ +package com.android.textureview_surfaceview.examples.verticalpager + +interface HDRVerticalPagerFragmentInterface { + fun setSurfaceViewVisibility(visibility: Boolean) { + // Do nothing implementation + } +} diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentSurfaceView.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentSurfaceView.kt new file mode 100644 index 0000000..03aa76b --- /dev/null +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentSurfaceView.kt @@ -0,0 +1,92 @@ +package com.android.textureview_surfaceview.examples.verticalpager + +import android.content.res.AssetFileDescriptor +import android.os.Bundle +import android.view.LayoutInflater +import android.view.SurfaceHolder +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.android.textureview_surfaceview.Constants +import com.android.textureview_surfaceview.databinding.FragmentHdrVerticalPagerSurfaceviewBinding +import com.android.textureview_surfaceview.decoder.CustomVideoDecoder + +class HDRVerticalPagerFragmentSurfaceView : Fragment(), HDRVerticalPagerFragmentInterface, + SurfaceHolder.Callback { + + private lateinit var binding: FragmentHdrVerticalPagerSurfaceviewBinding + private var decoder: CustomVideoDecoder? = null + private var asset: AssetFileDescriptor? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val pos = arguments?.getInt(POSITION_ARG) + pos?.let { + when (it) { + 0 -> asset = context?.assets?.openFd(Constants.HDR_VERTICAL_VIDEO_1) + 1 -> asset = context?.assets?.openFd(Constants.HDR_VERTICAL_VIDEO_2) + 2 -> asset = context?.assets?.openFd(Constants.HDR_VERTICAL_VIDEO_3) + } + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentHdrVerticalPagerSurfaceviewBinding.inflate(layoutInflater) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.hdrVerticalViewpagerSurfaceView.setAspectRatio(9, 16) + binding.hdrVerticalViewpagerSurfaceView.holder.addCallback(this) + } + + override fun onResume() { + binding.hdrVerticalViewpagerSurfaceView.visibility = View.VISIBLE + super.onResume() + } + + override fun onPause() { + decoder?.stop() + binding.hdrVerticalViewpagerSurfaceView.visibility = View.INVISIBLE + super.onPause() + } + + companion object { + var POSITION_ARG = "position_arg" + + @JvmStatic + fun newInstance(position: Int) = HDRVerticalPagerFragmentSurfaceView().apply { + arguments = Bundle().apply { + putInt(POSITION_ARG, position) + } + } + } + + override fun surfaceCreated(holder: SurfaceHolder) { + asset?.let { + decoder = CustomVideoDecoder.buildWithAssetFile(it) + decoder?.setSurface(holder.surface) + decoder?.start(loop = true) + } + } + + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + } + + override fun surfaceDestroyed(holder: SurfaceHolder) { + decoder?.stop() + } + + override fun setSurfaceViewVisibility(visibility: Boolean) { + binding.hdrVerticalViewpagerSurfaceView.visibility = + when (visibility) { + false -> View.INVISIBLE + true -> View.VISIBLE + } + } +} \ No newline at end of file diff --git a/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentTextureView.kt b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentTextureView.kt new file mode 100644 index 0000000..12b5046 --- /dev/null +++ b/TextureViewtoSurfaceView/app/src/main/java/com/android/textureview_surfaceview/examples/verticalpager/HDRVerticalPagerFragmentTextureView.kt @@ -0,0 +1,83 @@ +package com.android.textureview_surfaceview.examples.verticalpager + +import android.content.res.AssetFileDescriptor +import android.graphics.SurfaceTexture +import android.os.Bundle +import android.view.* +import androidx.fragment.app.Fragment +import com.android.textureview_surfaceview.Constants +import com.android.textureview_surfaceview.databinding.FragmentHdrVerticalPagerTextureviewBinding +import com.android.textureview_surfaceview.decoder.CustomVideoDecoder + +class HDRVerticalPagerFragmentTextureView : + Fragment(), + HDRVerticalPagerFragmentInterface, + TextureView.SurfaceTextureListener { + + private lateinit var binding: FragmentHdrVerticalPagerTextureviewBinding + private var decoder: CustomVideoDecoder? = null + private var asset: AssetFileDescriptor? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val pos = arguments?.getInt(POSITION_ARG) + pos?.let { + when (it) { + 0 -> asset = context?.assets?.openFd(Constants.HDR_VERTICAL_VIDEO_1) + 1 -> asset = context?.assets?.openFd(Constants.HDR_VERTICAL_VIDEO_2) + 2 -> asset = context?.assets?.openFd(Constants.HDR_VERTICAL_VIDEO_3) + } + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentHdrVerticalPagerTextureviewBinding.inflate(layoutInflater) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.hdrVerticalViewpagerTextureView.surfaceTextureListener = this + binding.hdrVerticalViewpagerTextureView.setAspectRatio(9, 16) + } + + companion object { + var POSITION_ARG = "position_arg" + + @JvmStatic + fun newInstance(position: Int) = HDRVerticalPagerFragmentTextureView().apply { + arguments = Bundle().apply { + putInt(POSITION_ARG, position) + } + } + } + + override fun onSurfaceTextureAvailable( + surfaceTexture: SurfaceTexture, + width: Int, + height: Int + ) { + asset?.let { + decoder = CustomVideoDecoder.buildWithAssetFile(it) + decoder?.setSurface(Surface(surfaceTexture)) + decoder?.start(loop = true) + } + } + + override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) { + // TODO("Not yet implemented") + } + + override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean { + decoder?.stop() + return true + } + + override fun onSurfaceTextureUpdated(surface: SurfaceTexture) { + + } +} \ No newline at end of file diff --git a/TextureViewtoSurfaceView/app/src/main/res/layout/activity_main.xml b/TextureViewtoSurfaceView/app/src/main/res/layout/activity_main.xml index 0bbce72..f69015f 100644 --- a/TextureViewtoSurfaceView/app/src/main/res/layout/activity_main.xml +++ b/TextureViewtoSurfaceView/app/src/main/res/layout/activity_main.xml @@ -1,127 +1,164 @@ - - - - - - - - -