add some initial handling for 360 videos

This commit is contained in:
tibbi 2018-10-21 13:08:46 +02:00
parent 1ad517a813
commit 7bc48bee0b
3 changed files with 98 additions and 74 deletions

View file

@ -3,7 +3,6 @@ package com.simplemobiletools.gallery.fragments
import android.content.res.Configuration import android.content.res.Configuration
import android.graphics.Point import android.graphics.Point
import android.graphics.SurfaceTexture import android.graphics.SurfaceTexture
import android.media.AudioManager
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
@ -44,7 +43,6 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
private var mTextureView: TextureView? = null private var mTextureView: TextureView? = null
private var mCurrTimeView: TextView? = null private var mCurrTimeView: TextView? = null
private var mSeekBar: SeekBar? = null private var mSeekBar: SeekBar? = null
private var mTimeHolder: View? = null
private var mView: View? = null private var mView: View? = null
private var mExoPlayer: SimpleExoPlayer? = null private var mExoPlayer: SimpleExoPlayer? = null
private var mVideoSize = Point(0, 0) private var mVideoSize = Point(0, 0)
@ -57,6 +55,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
private var mIsFragmentVisible = false private var mIsFragmentVisible = false
private var mWasFragmentInit = false private var mWasFragmentInit = false
private var mIsExoPlayerInitialized = false private var mIsExoPlayerInitialized = false
private var mIsPanorama = false
private var mCurrTime = 0 private var mCurrTime = 0
private var mDuration = 0 private var mDuration = 0
@ -65,8 +64,9 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
private var mStoredBottomActions = true private var mStoredBottomActions = true
private var mStoredExtendedDetails = 0 private var mStoredExtendedDetails = 0
private lateinit var brightnessSideScroll: MediaSideScroll private lateinit var mTimeHolder: View
private lateinit var volumeSideScroll: MediaSideScroll private lateinit var mBrightnessSideScroll: MediaSideScroll
private lateinit var mVolumeSideScroll: MediaSideScroll
lateinit var medium: Medium lateinit var medium: Medium
@ -74,11 +74,21 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
mView = inflater.inflate(R.layout.pager_video_item, container, false).apply { mView = inflater.inflate(R.layout.pager_video_item, container, false).apply {
instant_prev_item.setOnClickListener { listener?.goToPrevItem() } instant_prev_item.setOnClickListener { listener?.goToPrevItem() }
instant_next_item.setOnClickListener { listener?.goToNextItem() } instant_next_item.setOnClickListener { listener?.goToNextItem() }
video_curr_time.setOnClickListener { skip(false) }
video_duration.setOnClickListener { skip(true) }
video_holder.setOnClickListener { toggleFullscreen() }
// adding an empty click listener just to avoid ripple animation at toggling fullscreen
video_seekbar.setOnClickListener { }
mTimeHolder = video_time_holder mTimeHolder = video_time_holder
mBrightnessSideScroll = video_brightness_controller
mVolumeSideScroll = video_volume_controller
} }
storeStateVariables() storeStateVariables()
medium = arguments!!.getSerializable(MEDIUM) as Medium medium = arguments!!.getSerializable(MEDIUM) as Medium
Glide.with(context!!).load(medium.path).into(mView!!.video_preview)
// setMenuVisibility is not called at VideoActivity (third party intent) // setMenuVisibility is not called at VideoActivity (third party intent)
if (!mIsFragmentVisible && activity is VideoActivity) { if (!mIsFragmentVisible && activity is VideoActivity) {
@ -86,7 +96,23 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
} }
mIsFullscreen = activity!!.window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_FULLSCREEN == View.SYSTEM_UI_FLAG_FULLSCREEN mIsFullscreen = activity!!.window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_FULLSCREEN == View.SYSTEM_UI_FLAG_FULLSCREEN
initTimeHolder()
medium.path.getVideoResolution()?.apply {
mVideoSize.x = x
mVideoSize.y = y
mIsPanorama = x == y * 2
if (mIsPanorama) {
mView!!.apply {
panorama_outline.beVisible()
video_play_outline.beGone()
mVolumeSideScroll.beGone()
mBrightnessSideScroll.beGone()
Glide.with(context!!).load(medium.path).into(video_preview)
}
}
}
if (!mIsPanorama) {
setupPlayer() setupPlayer()
if (savedInstanceState != null) { if (savedInstanceState != null) {
mCurrTime = savedInstanceState.getInt(PROGRESS) mCurrTime = savedInstanceState.getInt(PROGRESS)
@ -95,39 +121,32 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
checkFullscreen() checkFullscreen()
mWasFragmentInit = true mWasFragmentInit = true
mView!!.apply {
brightnessSideScroll = video_brightness_controller
brightnessSideScroll.initialize(activity!!, slide_info, true, container) { x, y ->
video_holder.performClick()
}
volumeSideScroll = video_volume_controller
volumeSideScroll.initialize(activity!!, slide_info, false, container) { x, y ->
video_holder.performClick()
}
video_curr_time.setOnClickListener { skip(false) }
video_duration.setOnClickListener { skip(true) }
Glide.with(context!!).load(medium.path).into(video_preview)
}
mExoPlayer = ExoPlayerFactory.newSimpleInstance(context, DefaultTrackSelector()) mExoPlayer = ExoPlayerFactory.newSimpleInstance(context, DefaultTrackSelector())
mExoPlayer!!.seekParameters = SeekParameters.CLOSEST_SYNC mExoPlayer!!.seekParameters = SeekParameters.CLOSEST_SYNC
initExoPlayerListeners() initExoPlayerListeners()
medium.path.getVideoResolution()?.apply { if (mVideoSize.x != 0 && mVideoSize.y != 0) {
mVideoSize.x = x
mVideoSize.y = y
setVideoSize() setVideoSize()
} }
setupVideoDuration() mView!!.apply {
mBrightnessSideScroll.initialize(activity!!, slide_info, true, container) { x, y ->
video_holder.performClick()
}
mView!!.video_surface.onGlobalLayout { mVolumeSideScroll.initialize(activity!!, slide_info, false, container) { x, y ->
video_holder.performClick()
}
video_surface.onGlobalLayout {
if (mIsFragmentVisible && context?.config?.autoplayVideos == true) { if (mIsFragmentVisible && context?.config?.autoplayVideos == true) {
playVideo() playVideo()
} }
} }
}
}
setupVideoDuration()
return mView return mView
} }
@ -139,8 +158,8 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
val allowVideoGestures = config.allowVideoGestures val allowVideoGestures = config.allowVideoGestures
val allowInstantChange = config.allowInstantChange val allowInstantChange = config.allowInstantChange
mView!!.apply { mView!!.apply {
video_volume_controller.beVisibleIf(allowVideoGestures) video_volume_controller.beVisibleIf(allowVideoGestures && !mIsPanorama)
video_brightness_controller.beVisibleIf(allowVideoGestures) video_brightness_controller.beVisibleIf(allowVideoGestures && !mIsPanorama)
instant_prev_item.beVisibleIf(allowInstantChange) instant_prev_item.beVisibleIf(allowInstantChange)
instant_next_item.beVisibleIf(allowInstantChange) instant_next_item.beVisibleIf(allowInstantChange)
@ -154,7 +173,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
initTimeHolder() initTimeHolder()
} }
mView!!.video_time_holder.setBackgroundResource(if (config.bottomActions) 0 else R.drawable.gradient_background) mTimeHolder.setBackgroundResource(if (config.bottomActions) 0 else R.drawable.gradient_background)
storeStateVariables() storeStateVariables()
} }
@ -208,9 +227,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
mTextureView = mView!!.video_surface mTextureView = mView!!.video_surface
mTextureView!!.setOnClickListener { toggleFullscreen() } mTextureView!!.setOnClickListener { toggleFullscreen() }
mTextureView!!.surfaceTextureListener = this mTextureView!!.surfaceTextureListener = this
mView!!.video_holder.setOnClickListener { toggleFullscreen() }
initTimeHolder()
checkExtendedDetails() checkExtendedDetails()
} }
@ -227,7 +244,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
val factory = DataSource.Factory { fileDataSource } val factory = DataSource.Factory { fileDataSource }
val audioSource = ExtractorMediaSource(fileDataSource.uri, factory, DefaultExtractorsFactory(), null, null) val audioSource = ExtractorMediaSource(fileDataSource.uri, factory, DefaultExtractorsFactory(), null, null)
mExoPlayer!!.audioStreamType = AudioManager.STREAM_MUSIC mExoPlayer!!.audioStreamType = C.STREAM_TYPE_MUSIC
mExoPlayer!!.prepare(audioSource) mExoPlayer!!.prepare(audioSource)
} }
@ -297,15 +314,12 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
bottom += resources.getDimension(R.dimen.bottom_actions_height).toInt() bottom += resources.getDimension(R.dimen.bottom_actions_height).toInt()
} }
mTimeHolder!!.setPadding(left, top, right, bottom) mTimeHolder.setPadding(left, top, right, bottom)
mCurrTimeView = mView!!.video_curr_time mCurrTimeView = mView!!.video_curr_time
mSeekBar = mView!!.video_seekbar mSeekBar = mView!!.video_seekbar
mSeekBar!!.setOnSeekBarChangeListener(this) mSeekBar!!.setOnSeekBarChangeListener(this)
mTimeHolder.beInvisibleIf(mIsFullscreen)
if (mIsFullscreen) {
mTimeHolder!!.beInvisible()
}
} }
private fun hasNavBar(): Boolean { private fun hasNavBar(): Boolean {
@ -367,7 +381,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
AnimationUtils.loadAnimation(activity, anim).apply { AnimationUtils.loadAnimation(activity, anim).apply {
duration = 150 duration = 150
fillAfter = true fillAfter = true
mTimeHolder?.startAnimation(this) mTimeHolder.startAnimation(this)
} }
} }
@ -431,7 +445,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
private fun videoEnded() = mExoPlayer?.currentPosition ?: 0 >= mExoPlayer?.duration ?: 0 private fun videoEnded() = mExoPlayer?.currentPosition ?: 0 >= mExoPlayer?.duration ?: 0
private fun setProgress(seconds: Int) { private fun setProgress(seconds: Int) {
mExoPlayer!!.seekTo(seconds * 1000L) mExoPlayer?.seekTo(seconds * 1000L)
mSeekBar!!.progress = seconds mSeekBar!!.progress = seconds
mCurrTimeView!!.text = seconds.getFormattedDuration() mCurrTimeView!!.text = seconds.getFormattedDuration()
} }
@ -555,7 +569,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
} }
private fun skip(forward: Boolean) { private fun skip(forward: Boolean) {
if (mExoPlayer == null) { if (mExoPlayer == null || mIsPanorama) {
return return
} }
@ -613,7 +627,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
private fun getExtendedDetailsY(height: Int): Float { private fun getExtendedDetailsY(height: Int): Float {
val smallMargin = resources.getDimension(R.dimen.small_margin) val smallMargin = resources.getDimension(R.dimen.small_margin)
val fullscreenOffset = smallMargin + if (mIsFullscreen) 0 else mTimeHolder!!.height val fullscreenOffset = smallMargin + if (mIsFullscreen) 0 else mTimeHolder.height
return context!!.realScreenSize.y.toFloat() - height - fullscreenOffset return context!!.realScreenSize.y.toFloat() - height - fullscreenOffset
} }
} }

View file

@ -30,8 +30,8 @@ class MediaSideScroll(context: Context, attrs: AttributeSet) : RelativeLayout(co
private var mSlideInfoText = "" private var mSlideInfoText = ""
private var mSlideInfoFadeHandler = Handler() private var mSlideInfoFadeHandler = Handler()
private var mParentView: ViewGroup? = null private var mParentView: ViewGroup? = null
private var activity: Activity? = null
private lateinit var activity: Activity
private lateinit var slideInfoView: TextView private lateinit var slideInfoView: TextView
private lateinit var callback: (Float, Float) -> Unit private lateinit var callback: (Float, Float) -> Unit
@ -55,7 +55,7 @@ class MediaSideScroll(context: Context, attrs: AttributeSet) : RelativeLayout(co
} }
override fun onTouchEvent(event: MotionEvent): Boolean { override fun onTouchEvent(event: MotionEvent): Boolean {
if (mPassTouches) { if (mPassTouches && activity == null) {
return false return false
} }
@ -112,11 +112,11 @@ class MediaSideScroll(context: Context, attrs: AttributeSet) : RelativeLayout(co
return true return true
} }
private fun getCurrentVolume() = activity.audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) private fun getCurrentVolume() = activity!!.audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
private fun getCurrentBrightness(): Int { private fun getCurrentBrightness(): Int {
return try { return try {
Settings.System.getInt(activity.contentResolver, Settings.System.SCREEN_BRIGHTNESS) Settings.System.getInt(activity!!.contentResolver, Settings.System.SCREEN_BRIGHTNESS)
} catch (e: Settings.SettingNotFoundException) { } catch (e: Settings.SettingNotFoundException) {
70 70
} }
@ -132,11 +132,11 @@ class MediaSideScroll(context: Context, attrs: AttributeSet) : RelativeLayout(co
private fun volumePercentChanged(percent: Int) { private fun volumePercentChanged(percent: Int) {
val stream = AudioManager.STREAM_MUSIC val stream = AudioManager.STREAM_MUSIC
val maxVolume = activity.audioManager.getStreamMaxVolume(stream) val maxVolume = activity!!.audioManager.getStreamMaxVolume(stream)
val percentPerPoint = 100 / maxVolume val percentPerPoint = 100 / maxVolume
val addPoints = percent / percentPerPoint val addPoints = percent / percentPerPoint
val newVolume = Math.min(maxVolume, Math.max(0, mTouchDownValue + addPoints)) val newVolume = Math.min(maxVolume, Math.max(0, mTouchDownValue + addPoints))
activity.audioManager.setStreamVolume(stream, newVolume, 0) activity!!.audioManager.setStreamVolume(stream, newVolume, 0)
val absolutePercent = ((newVolume / maxVolume.toFloat()) * 100).toInt() val absolutePercent = ((newVolume / maxVolume.toFloat()) * 100).toInt()
showValue(absolutePercent) showValue(absolutePercent)
@ -156,9 +156,9 @@ class MediaSideScroll(context: Context, attrs: AttributeSet) : RelativeLayout(co
val absolutePercent = ((newBrightness / maxBrightness) * 100).toInt() val absolutePercent = ((newBrightness / maxBrightness) * 100).toInt()
showValue(absolutePercent) showValue(absolutePercent)
val attributes = activity.window.attributes val attributes = activity!!.window.attributes
attributes.screenBrightness = absolutePercent / 100f attributes.screenBrightness = absolutePercent / 100f
activity.window.attributes = attributes activity!!.window.attributes = attributes
mSlideInfoFadeHandler.removeCallbacksAndMessages(null) mSlideInfoFadeHandler.removeCallbacksAndMessages(null)
mSlideInfoFadeHandler.postDelayed({ mSlideInfoFadeHandler.postDelayed({

View file

@ -60,13 +60,23 @@
android:alpha="0" android:alpha="0"
android:background="@drawable/black_rounded_background" android:background="@drawable/black_rounded_background"
android:gravity="center" android:gravity="center"
android:paddingBottom="@dimen/medium_margin"
android:paddingLeft="@dimen/activity_margin" android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:paddingTop="@dimen/medium_margin" android:paddingTop="@dimen/medium_margin"
android:paddingRight="@dimen/activity_margin"
android:paddingBottom="@dimen/medium_margin"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="@dimen/extra_big_text_size"/> android:textSize="@dimen/extra_big_text_size"/>
<ImageView
android:id="@+id/panorama_outline"
android:layout_width="@dimen/play_outline_size_big"
android:layout_height="@dimen/play_outline_size_big"
android:layout_centerInParent="true"
android:background="@drawable/circle_black_background_with_inset"
android:padding="28dp"
android:src="@drawable/ic_panorama"
android:visibility="gone"/>
<TextView <TextView
android:id="@+id/video_details" android:id="@+id/video_details"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -92,10 +102,10 @@
style="@style/MyBorderlessBackgroundStyle" style="@style/MyBorderlessBackgroundStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_alignBottom="@+id/video_seekbar"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignTop="@+id/video_seekbar" android:layout_alignTop="@+id/video_seekbar"
android:layout_alignBottom="@+id/video_seekbar"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingLeft="@dimen/activity_margin" android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin" android:paddingRight="@dimen/activity_margin"
@ -106,22 +116,22 @@
android:id="@+id/video_seekbar" android:id="@+id/video_seekbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toEndOf="@+id/video_curr_time"
android:layout_toLeftOf="@+id/video_duration"
android:layout_toRightOf="@+id/video_curr_time"
android:layout_toStartOf="@+id/video_duration" android:layout_toStartOf="@+id/video_duration"
android:paddingBottom="@dimen/activity_margin" android:layout_toLeftOf="@+id/video_duration"
android:paddingTop="@dimen/activity_margin"/> android:layout_toEndOf="@+id/video_curr_time"
android:layout_toRightOf="@+id/video_curr_time"
android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"/>
<TextView <TextView
android:id="@+id/video_duration" android:id="@+id/video_duration"
style="@style/MyBorderlessBackgroundStyle" style="@style/MyBorderlessBackgroundStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignTop="@+id/video_seekbar"
android:layout_alignBottom="@+id/video_seekbar" android:layout_alignBottom="@+id/video_seekbar"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignTop="@+id/video_seekbar"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingLeft="@dimen/activity_margin" android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin" android:paddingRight="@dimen/activity_margin"