diff --git a/app/src/main/java/com/simplemobiletools/gallery/fragments/VideoFragment.java b/app/src/main/java/com/simplemobiletools/gallery/fragments/VideoFragment.java deleted file mode 100644 index 0525460d9..000000000 --- a/app/src/main/java/com/simplemobiletools/gallery/fragments/VideoFragment.java +++ /dev/null @@ -1,415 +0,0 @@ -package com.simplemobiletools.gallery.fragments; - -import android.content.res.Configuration; -import android.content.res.Resources; -import android.media.AudioManager; -import android.media.MediaPlayer; -import android.media.MediaPlayer.OnPreparedListener; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.Display; -import android.view.LayoutInflater; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.ImageView; -import android.widget.SeekBar; -import android.widget.TextView; - -import com.simplemobiletools.gallery.Config; -import com.simplemobiletools.gallery.Constants; -import com.simplemobiletools.gallery.R; -import com.simplemobiletools.gallery.Utils; -import com.simplemobiletools.gallery.models.Medium; - -import java.io.IOException; -import java.util.Locale; - -public class VideoFragment extends ViewPagerFragment - implements View.OnClickListener, SurfaceHolder.Callback, MediaPlayer.OnCompletionListener, MediaPlayer.OnVideoSizeChangedListener, - SeekBar.OnSeekBarChangeListener, OnPreparedListener { - private static final String TAG = VideoFragment.class.getSimpleName(); - private static final String PROGRESS = "progress"; - - private MediaPlayer mMediaPlayer; - private SurfaceView mSurfaceView; - private SurfaceHolder mSurfaceHolder; - private ImageView mPlayOutline; - private TextView mCurrTimeView; - private TextView mDurationView; - private Handler mTimerHandler; - private SeekBar mSeekBar; - private Medium mMedium; - private View mTimeHolder; - private View mView; - - private boolean mIsPlaying; - private boolean mIsDragged; - private boolean mIsFullscreen; - private boolean mIsFragmentVisible; - private int mCurrTime; - private int mDuration; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - mView = inflater.inflate(R.layout.pager_video_item, container, false); - - mMedium = (Medium) getArguments().getSerializable(Constants.MEDIUM); - if (savedInstanceState != null) { - mCurrTime = savedInstanceState.getInt(PROGRESS); - } - - mIsFullscreen = (getActivity().getWindow().getDecorView().getSystemUiVisibility() & View.SYSTEM_UI_FLAG_FULLSCREEN) == - View.SYSTEM_UI_FLAG_FULLSCREEN; - setupPlayer(); - mView.setOnClickListener(this); - - return mView; - } - - private void setupPlayer() { - if (getActivity() == null) - return; - - mPlayOutline = (ImageView) mView.findViewById(R.id.video_play_outline); - mPlayOutline.setOnClickListener(this); - - mSurfaceView = (SurfaceView) mView.findViewById(R.id.video_surface); - mSurfaceView.setOnClickListener(this); - mSurfaceHolder = mSurfaceView.getHolder(); - mSurfaceHolder.addCallback(this); - - initTimeHolder(); - } - - @Override - public void setMenuVisibility(boolean menuVisible) { - super.setMenuVisibility(menuVisible); - mIsFragmentVisible = menuVisible; - if (menuVisible) { - if (getContext() != null && Config.Companion.newInstance(getContext()).getAutoplayVideos()) { - playVideo(); - } - } - } - - public void itemDragged() { - pauseVideo(); - } - - @Override - public void systemUiVisibilityChanged(boolean toFullscreen) { - if (mIsFullscreen != toFullscreen) { - mIsFullscreen = toFullscreen; - checkFullscreen(); - } - } - - @Override - public void updateItem() { - setVideoSize(); - initTimeHolder(); - } - - private void initTimeHolder() { - mTimeHolder = mView.findViewById(R.id.video_time_holder); - final Resources res = getResources(); - final int height = Utils.Companion.getNavBarHeight(res); - final int left = mTimeHolder.getPaddingLeft(); - final int top = mTimeHolder.getPaddingTop(); - int right = (int) getResources().getDimension(R.dimen.timer_padding); - int bottom = 0; - - if (Utils.Companion.hasNavBar(getActivity())) { - if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { - bottom += height; - } else { - right += height; - } - mTimeHolder.setPadding(left, top, right, bottom); - } - - mCurrTimeView = (TextView) mView.findViewById(R.id.video_curr_time); - mDurationView = (TextView) mView.findViewById(R.id.video_duration); - mSeekBar = (SeekBar) mView.findViewById(R.id.video_seekbar); - mSeekBar.setOnSeekBarChangeListener(this); - - if (mIsFullscreen) - mTimeHolder.setVisibility(View.INVISIBLE); - } - - private void setupTimeHolder() { - mSeekBar.setMax(mDuration); - mDurationView.setText(getTimeString(mDuration)); - mTimerHandler = new Handler(); - setupTimer(); - } - - private void setupTimer() { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - if (mMediaPlayer != null && !mIsDragged && mIsPlaying) { - mCurrTime = mMediaPlayer.getCurrentPosition() / 1000; - mSeekBar.setProgress(mCurrTime); - mCurrTimeView.setText(getTimeString(mCurrTime)); - } - - mTimerHandler.postDelayed(this, 1000); - } - }); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putInt(PROGRESS, mCurrTime); - } - - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.video_play_outline: - togglePlayPause(); - break; - default: - mIsFullscreen = !mIsFullscreen; - checkFullscreen(); - - if (getListener() == null) - setListener((FragmentClickListener) getActivity()); - getListener().fragmentClicked(); - break; - } - } - - private void checkFullscreen() { - int anim = R.anim.fade_in; - if (mIsFullscreen) { - anim = R.anim.fade_out; - mSeekBar.setOnSeekBarChangeListener(null); - } else { - mSeekBar.setOnSeekBarChangeListener(this); - } - - final Animation animation = AnimationUtils.loadAnimation(getContext(), anim); - mTimeHolder.startAnimation(animation); - } - - private void togglePlayPause() { - if (getActivity() == null || !isAdded()) - return; - - mIsPlaying = !mIsPlaying; - if (mIsPlaying) { - playVideo(); - } else { - pauseVideo(); - } - } - - private void playVideo() { - mIsPlaying = true; - if (mMediaPlayer != null) { - mMediaPlayer.start(); - } - - mPlayOutline.setImageDrawable(null); - getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } - - private void pauseVideo() { - mIsPlaying = false; - if (mMediaPlayer != null) { - mMediaPlayer.pause(); - } - - mPlayOutline.setImageDrawable(getResources().getDrawable(R.mipmap.play_outline_big)); - getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } - - private void initMediaPlayer() { - if (mMediaPlayer != null) - return; - - try { - mMediaPlayer = new MediaPlayer(); - mMediaPlayer.setDataSource(getContext(), Uri.parse(mMedium.getPath())); - mMediaPlayer.setDisplay(mSurfaceHolder); - mMediaPlayer.setOnCompletionListener(this); - mMediaPlayer.setOnVideoSizeChangedListener(this); - mMediaPlayer.setOnPreparedListener(this); - mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); - mMediaPlayer.prepareAsync(); - } catch (IOException e) { - Log.e(TAG, "init media player " + e.getMessage()); - } - } - - private void setProgress(int seconds) { - mMediaPlayer.seekTo(seconds * 1000); - mSeekBar.setProgress(seconds); - mCurrTimeView.setText(getTimeString(seconds)); - } - - private void addPreviewImage() { - mMediaPlayer.start(); - mMediaPlayer.pause(); - } - - @Override - public void onPause() { - super.onPause(); - pauseVideo(); - mIsFragmentVisible = false; - } - - @Override - public void onDestroy() { - super.onDestroy(); - if (getActivity() != null && !getActivity().isChangingConfigurations()) { - cleanup(); - } - } - - private void cleanup() { - pauseVideo(); - - if (mCurrTimeView != null) - mCurrTimeView.setText(getTimeString(0)); - - if (mMediaPlayer != null) { - mMediaPlayer.release(); - mMediaPlayer = null; - } - - if (mSeekBar != null) - mSeekBar.setProgress(0); - - if (mTimerHandler != null) - mTimerHandler.removeCallbacksAndMessages(null); - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - initMediaPlayer(); - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - if (mMediaPlayer != null) { - mMediaPlayer.release(); - mMediaPlayer = null; - } - } - - @Override - public void onCompletion(MediaPlayer mp) { - mSeekBar.setProgress(mSeekBar.getMax()); - mCurrTimeView.setText(getTimeString(mDuration)); - pauseVideo(); - } - - @Override - public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { - setVideoSize(); - } - - private void setVideoSize() { - if (getActivity() == null) - return; - - final float videoProportion = (float) mMediaPlayer.getVideoWidth() / (float) mMediaPlayer.getVideoHeight(); - final Display display = getActivity().getWindowManager().getDefaultDisplay(); - int screenWidth; - int screenHeight; - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { - final DisplayMetrics realMetrics = new DisplayMetrics(); - display.getRealMetrics(realMetrics); - screenWidth = realMetrics.widthPixels; - screenHeight = realMetrics.heightPixels; - } else { - screenWidth = display.getWidth(); - screenHeight = display.getHeight(); - } - - final float screenProportion = (float) screenWidth / (float) screenHeight; - - final android.view.ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams(); - if (videoProportion > screenProportion) { - lp.width = screenWidth; - lp.height = (int) ((float) screenWidth / videoProportion); - } else { - lp.width = (int) (videoProportion * (float) screenHeight); - lp.height = screenHeight; - } - mSurfaceView.setLayoutParams(lp); - } - - private String getTimeString(int duration) { - final StringBuilder sb = new StringBuilder(8); - final int hours = duration / (60 * 60); - final int minutes = (duration % (60 * 60)) / 60; - final int seconds = ((duration % (60 * 60)) % 60); - - if (duration > 3600) { - sb.append(String.format(Locale.getDefault(), "%02d", hours)).append(":"); - } - - sb.append(String.format(Locale.getDefault(), "%02d", minutes)); - sb.append(":").append(String.format(Locale.getDefault(), "%02d", seconds)); - - return sb.toString(); - } - - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (mMediaPlayer != null && fromUser) { - setProgress(progress); - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - if (mMediaPlayer == null) - initMediaPlayer(); - - mMediaPlayer.pause(); - mIsDragged = true; - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - if (!mIsPlaying) { - togglePlayPause(); - } else { - mMediaPlayer.start(); - } - - mIsDragged = false; - } - - @Override - public void onPrepared(MediaPlayer mp) { - mDuration = mp.getDuration() / 1000; - addPreviewImage(); - setupTimeHolder(); - setProgress(mCurrTime); - - if (mIsFragmentVisible && Config.Companion.newInstance(getContext()).getAutoplayVideos()) - playVideo(); - } -} diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt new file mode 100644 index 000000000..6c1f9070c --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt @@ -0,0 +1,364 @@ +package com.simplemobiletools.gallery.fragments + +import android.content.res.Configuration +import android.media.AudioManager +import android.media.MediaPlayer +import android.media.MediaPlayer.OnPreparedListener +import android.net.Uri +import android.os.Bundle +import android.os.Handler +import android.util.DisplayMetrics +import android.util.Log +import android.view.* +import android.view.animation.AnimationUtils +import android.widget.SeekBar +import android.widget.TextView +import com.simplemobiletools.gallery.Config +import com.simplemobiletools.gallery.Constants +import com.simplemobiletools.gallery.R +import com.simplemobiletools.gallery.Utils +import com.simplemobiletools.gallery.models.Medium +import kotlinx.android.synthetic.main.pager_video_item.view.* +import java.io.IOException +import java.util.* + +class VideoFragment : ViewPagerFragment(), View.OnClickListener, SurfaceHolder.Callback, MediaPlayer.OnCompletionListener, + MediaPlayer.OnVideoSizeChangedListener, SeekBar.OnSeekBarChangeListener, OnPreparedListener { + + private var mMediaPlayer: MediaPlayer? = null + private var mSurfaceView: SurfaceView? = null + private var mSurfaceHolder: SurfaceHolder? = null + private var mCurrTimeView: TextView? = null + private var mTimerHandler: Handler? = null + private var mSeekBar: SeekBar? = null + private var mTimeHolder: View? = null + + private var mIsPlaying = false + private var mIsDragged = false + private var mIsFullscreen = false + private var mIsFragmentVisible = false + private var mCurrTime = 0 + private var mDuration = 0 + + lateinit var mView: View + lateinit var mMedium: Medium + + companion object { + private val TAG = VideoFragment::class.java.simpleName + private val PROGRESS = "progress" + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + mView = inflater.inflate(R.layout.pager_video_item, container, false) + + mMedium = arguments.getSerializable(Constants.MEDIUM) as Medium + if (savedInstanceState != null) { + mCurrTime = savedInstanceState.getInt(PROGRESS) + } + + mIsFullscreen = activity.window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_FULLSCREEN == View.SYSTEM_UI_FLAG_FULLSCREEN + setupPlayer() + mView.setOnClickListener(this) + + return mView + } + + private fun setupPlayer() { + if (activity == null) + return + + mView.video_play_outline.setOnClickListener(this) + + mSurfaceView = mView.video_surface + mSurfaceView!!.setOnClickListener(this) + mSurfaceHolder = mSurfaceView!!.holder + mSurfaceHolder!!.addCallback(this) + + initTimeHolder() + } + + override fun setMenuVisibility(menuVisible: Boolean) { + super.setMenuVisibility(menuVisible) + mIsFragmentVisible = menuVisible + if (menuVisible) { + if (context != null && Config.newInstance(context).autoplayVideos) { + playVideo() + } + } + } + + override fun itemDragged() { + pauseVideo() + } + + override fun systemUiVisibilityChanged(toFullscreen: Boolean) { + if (mIsFullscreen != toFullscreen) { + mIsFullscreen = toFullscreen + checkFullscreen() + } + } + + override fun updateItem() { + setVideoSize() + initTimeHolder() + } + + private fun initTimeHolder() { + mTimeHolder = mView.video_time_holder + val res = resources + val height = Utils.getNavBarHeight(res) + val left = mTimeHolder!!.paddingLeft + val top = mTimeHolder!!.paddingTop + var right = res.getDimension(R.dimen.timer_padding).toInt() + var bottom = 0 + + if (Utils.hasNavBar(activity)) { + if (res.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { + bottom += height + } else { + right += height + } + mTimeHolder!!.setPadding(left, top, right, bottom) + } + + mCurrTimeView = mView.video_curr_time + mSeekBar = mView.video_seekbar + mSeekBar!!.setOnSeekBarChangeListener(this) + + if (mIsFullscreen) + mTimeHolder!!.visibility = View.INVISIBLE + } + + private fun setupTimeHolder() { + mSeekBar!!.max = mDuration + mView.video_duration.text = getTimeString(mDuration) + mTimerHandler = Handler() + setupTimer() + } + + private fun setupTimer() { + activity.runOnUiThread(object : Runnable { + override fun run() { + if (mMediaPlayer != null && !mIsDragged && mIsPlaying) { + mCurrTime = mMediaPlayer!!.currentPosition / 1000 + mSeekBar!!.progress = mCurrTime + mCurrTimeView!!.text = getTimeString(mCurrTime) + } + + mTimerHandler!!.postDelayed(this, 1000) + } + }) + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putInt(PROGRESS, mCurrTime) + } + + override fun onClick(v: View) { + when (v.id) { + R.id.video_play_outline -> togglePlayPause() + else -> { + mIsFullscreen = !mIsFullscreen + checkFullscreen() + listener.fragmentClicked() + } + } + } + + private fun checkFullscreen() { + var anim = R.anim.fade_in + if (mIsFullscreen) { + anim = R.anim.fade_out + mSeekBar!!.setOnSeekBarChangeListener(null) + } else { + mSeekBar!!.setOnSeekBarChangeListener(this) + } + + val animation = AnimationUtils.loadAnimation(context, anim) + mTimeHolder!!.startAnimation(animation) + } + + private fun togglePlayPause() { + if (activity == null || !isAdded) + return + + mIsPlaying = !mIsPlaying + if (mIsPlaying) { + playVideo() + } else { + pauseVideo() + } + } + + private fun playVideo() { + mIsPlaying = true + mMediaPlayer?.start() + mView.video_play_outline.setImageDrawable(null) + activity.window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + } + + private fun pauseVideo() { + mIsPlaying = false + mMediaPlayer?.pause() + mView.video_play_outline.setImageDrawable(resources.getDrawable(R.mipmap.play_outline_big)) + activity.window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + } + + private fun initMediaPlayer() { + if (mMediaPlayer != null) + return + + try { + mMediaPlayer = MediaPlayer().apply { + setDataSource(context, Uri.parse(mMedium.path)) + setDisplay(mSurfaceHolder) + setOnCompletionListener(this@VideoFragment) + setOnVideoSizeChangedListener(this@VideoFragment) + setOnPreparedListener(this@VideoFragment) + setAudioStreamType(AudioManager.STREAM_MUSIC) + prepareAsync() + } + } catch (e: IOException) { + Log.e(TAG, "init media player failed " + e) + } + } + + private fun setProgress(seconds: Int) { + mMediaPlayer!!.seekTo(seconds * 1000) + mSeekBar!!.progress = seconds + mCurrTimeView!!.text = getTimeString(seconds) + } + + private fun addPreviewImage() { + mMediaPlayer!!.start() + mMediaPlayer!!.pause() + } + + override fun onPause() { + super.onPause() + pauseVideo() + mIsFragmentVisible = false + } + + override fun onDestroy() { + super.onDestroy() + if (activity != null && !activity.isChangingConfigurations) { + cleanup() + } + } + + private fun cleanup() { + pauseVideo() + mCurrTimeView?.text = getTimeString(0) + mMediaPlayer?.release() + mMediaPlayer = null + mSeekBar?.progress = 0 + mTimerHandler?.removeCallbacksAndMessages(null) + } + + override fun surfaceCreated(holder: SurfaceHolder) { + initMediaPlayer() + } + + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + + } + + override fun surfaceDestroyed(holder: SurfaceHolder) { + mMediaPlayer?.release() + mMediaPlayer = null + } + + override fun onCompletion(mp: MediaPlayer) { + mSeekBar!!.progress = mSeekBar!!.max + mCurrTimeView!!.text = getTimeString(mDuration) + pauseVideo() + } + + override fun onVideoSizeChanged(mp: MediaPlayer, width: Int, height: Int) { + setVideoSize() + } + + private fun setVideoSize() { + if (activity == null) + return + + val videoProportion = mMediaPlayer!!.videoWidth.toFloat() / mMediaPlayer!!.videoHeight.toFloat() + val display = activity.windowManager.defaultDisplay + val screenWidth: Int + val screenHeight: Int + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { + val realMetrics = DisplayMetrics() + display.getRealMetrics(realMetrics) + screenWidth = realMetrics.widthPixels + screenHeight = realMetrics.heightPixels + } else { + screenWidth = display.width + screenHeight = display.height + } + + val screenProportion = screenWidth.toFloat() / screenHeight.toFloat() + + val lp = mSurfaceView!!.layoutParams + if (videoProportion > screenProportion) { + lp.width = screenWidth + lp.height = (screenWidth.toFloat() / videoProportion).toInt() + } else { + lp.width = (videoProportion * screenHeight.toFloat()).toInt() + lp.height = screenHeight + } + mSurfaceView!!.layoutParams = lp + } + + private fun getTimeString(duration: Int): String { + val sb = StringBuilder(8) + val hours = duration / (60 * 60) + val minutes = duration % (60 * 60) / 60 + val seconds = duration % (60 * 60) % 60 + + if (duration > 3600) { + sb.append(String.format(Locale.getDefault(), "%02d", hours)).append(":") + } + + sb.append(String.format(Locale.getDefault(), "%02d", minutes)) + sb.append(":").append(String.format(Locale.getDefault(), "%02d", seconds)) + + return sb.toString() + } + + override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { + if (mMediaPlayer != null && fromUser) { + setProgress(progress) + } + } + + override fun onStartTrackingTouch(seekBar: SeekBar) { + if (mMediaPlayer == null) + initMediaPlayer() + + mMediaPlayer!!.pause() + mIsDragged = true + } + + override fun onStopTrackingTouch(seekBar: SeekBar) { + if (!mIsPlaying) { + togglePlayPause() + } else { + mMediaPlayer!!.start() + } + + mIsDragged = false + } + + override fun onPrepared(mp: MediaPlayer) { + mDuration = mp.duration / 1000 + addPreviewImage() + setupTimeHolder() + setProgress(mCurrTime) + + if (mIsFragmentVisible && Config.newInstance(context).autoplayVideos) + playVideo() + } +}