Skip to content

Commit

Permalink
Vertical PageView Sample (#50)
Browse files Browse the repository at this point in the history
* Initial implementation over vertical videos using SurfaceView

* Rename + add ability to preload Surfaces

* update gradle + viewpager sample included
  • Loading branch information
madebymozart authored Nov 16, 2023
1 parent c1cfc52 commit b1093ce
Show file tree
Hide file tree
Showing 21 changed files with 507 additions and 135 deletions.
4 changes: 2 additions & 2 deletions TextureViewtoSurfaceView/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
3 changes: 3 additions & 0 deletions TextureViewtoSurfaceView/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@
<activity android:name=".examples.multi.MultiViewVideoPlayer" />
<activity android:name=".examples.multi.MultiViewVideoPlayerHDR" />
<activity android:name=".examples.multi.MultiViewVideoPlayerHDRTransformer" />
<activity
android:name=".examples.verticalpager.HDRVerticalPager"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -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() {

Expand Down Expand Up @@ -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)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand All @@ -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
Expand Down Expand Up @@ -145,5 +146,4 @@ class MultiViewVideoPlayerHDRTransformer : Activity(), SurfaceHolder.Callback,
"Fallback applied: $fallbackTransformationRequest"
)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -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)
}
}
})
}
}
Original file line number Diff line number Diff line change
@@ -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)
}

Original file line number Diff line number Diff line change
@@ -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")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.android.textureview_surfaceview.examples.verticalpager

interface HDRVerticalPagerFragmentInterface {
fun setSurfaceViewVisibility(visibility: Boolean) {
// Do nothing implementation
}
}
Original file line number Diff line number Diff line change
@@ -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
}
}
}
Original file line number Diff line number Diff line change
@@ -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) {

}
}
Loading

0 comments on commit b1093ce

Please sign in to comment.