change VideoPreviewBar to kotlin

pull/166/head
xufuji456 4 years ago
parent 48f8bd8018
commit d506d87487
  1. 217
      app/src/main/java/com/frank/ffmpeg/view/VideoPreviewBar.java
  2. 197
      app/src/main/java/com/frank/ffmpeg/view/VideoPreviewBar.kt

@ -1,217 +0,0 @@
package com.frank.ffmpeg.view;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import com.frank.ffmpeg.R;
import com.frank.ffmpeg.hardware.HardwareDecode;
import com.frank.ffmpeg.util.ScreenUtil;
import com.frank.ffmpeg.util.TimeUtil;
/**
* the custom view of preview SeekBar
* Created by frank on 2019/11/16.
*/
public class VideoPreviewBar extends RelativeLayout implements HardwareDecode.OnDataCallback {
private final static String TAG = VideoPreviewBar.class.getSimpleName();
private TextureView texturePreView;
private SeekBar previewBar;
private TextView txtVideoProgress;
private TextView txtVideoDuration;
private HardwareDecode hardwareDecode;
private PreviewBarCallback mPreviewBarCallback;
private int duration;
private int screenWidth;
private int moveEndPos = 0;
private int previewHalfWidth;
public VideoPreviewBar(Context context) {
super(context);
initView(context);
}
public VideoPreviewBar(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
initView(context);
}
private void initView(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.preview_video, this);
previewBar = view.findViewById(R.id.preview_bar);
texturePreView = view.findViewById(R.id.texture_preview);
txtVideoProgress = view.findViewById(R.id.txt_video_progress);
txtVideoDuration = view.findViewById(R.id.txt_video_duration);
setListener();
screenWidth = ScreenUtil.INSTANCE.getScreenWidth(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (moveEndPos == 0) {
int previewWidth = texturePreView.getWidth();
previewHalfWidth = previewWidth / 2;
int marginEnd = 0;
MarginLayoutParams layoutParams = (MarginLayoutParams) texturePreView.getLayoutParams();
if (layoutParams != null) {
marginEnd = layoutParams.getMarginEnd();
}
moveEndPos = screenWidth - previewWidth - marginEnd;
Log.i(TAG, "previewWidth=" + previewWidth);
}
}
private void setPreviewCallback(final String filePath, TextureView texturePreView) {
texturePreView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
doPreview(filePath, new Surface(surface));
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
}
private void doPreview(String filePath, Surface surface) {
if (surface == null || TextUtils.isEmpty(filePath)) {
return;
}
release();
hardwareDecode = new HardwareDecode(surface, filePath, this);
hardwareDecode.decode();
}
private void setListener() {
previewBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (!fromUser) {
return;
}
previewBar.setProgress(progress);
if (hardwareDecode != null && progress < duration) {
// us to ms
hardwareDecode.seekTo(progress * 1000);
}
int percent = progress * screenWidth / duration;
if (percent > previewHalfWidth && percent < moveEndPos && texturePreView != null) {
texturePreView.setTranslationX(percent - previewHalfWidth);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
if (texturePreView != null) {
texturePreView.setVisibility(VISIBLE);
}
if (hardwareDecode != null) {
hardwareDecode.setPreviewing(true);
}
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (texturePreView != null) {
texturePreView.setVisibility(GONE);
}
if (mPreviewBarCallback != null) {
mPreviewBarCallback.onStopTracking(seekBar.getProgress());
}
if (hardwareDecode != null) {
hardwareDecode.setPreviewing(false);
}
}
});
}
@Override
public void onData(long duration) {
//us to ms
final int durationMs = (int) (duration / 1000);
Log.i(TAG, "duration=" + duration);
this.duration = durationMs;
post(new Runnable() {
@Override
public void run() {
previewBar.setMax(durationMs);
txtVideoDuration.setText(TimeUtil.INSTANCE.getVideoTime(durationMs));
texturePreView.setVisibility(GONE);
}
});
}
private void checkArgument(String videoPath) {
if (texturePreView == null) {
throw new IllegalStateException("Must init TextureView first...");
}
if (videoPath == null || videoPath.isEmpty()) {
throw new IllegalStateException("videoPath is empty...");
}
}
public void init(String videoPath, PreviewBarCallback previewBarCallback) {
checkArgument(videoPath);
this.mPreviewBarCallback = previewBarCallback;
doPreview(videoPath, new Surface(texturePreView.getSurfaceTexture()));
}
public void initDefault(String videoPath, PreviewBarCallback previewBarCallback) {
checkArgument(videoPath);
this.mPreviewBarCallback = previewBarCallback;
setPreviewCallback(videoPath, texturePreView);
}
public void updateProgress(int progress) {
if (progress >= 0 && progress <= duration) {
txtVideoProgress.setText(TimeUtil.INSTANCE.getVideoTime(progress));
previewBar.setProgress(progress);
}
}
public void release() {
if (hardwareDecode != null) {
hardwareDecode.release();
hardwareDecode = null;
}
}
public interface PreviewBarCallback {
void onStopTracking(long progress);
}
}

@ -0,0 +1,197 @@
package com.frank.ffmpeg.view
import android.content.Context
import android.graphics.SurfaceTexture
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.view.*
import android.widget.RelativeLayout
import android.widget.SeekBar
import android.widget.TextView
import com.frank.ffmpeg.R
import com.frank.ffmpeg.hardware.HardwareDecode
import com.frank.ffmpeg.util.ScreenUtil
import com.frank.ffmpeg.util.TimeUtil
/**
* the custom view of preview SeekBar
* Created by frank on 2019/11/16.
*/
class VideoPreviewBar : RelativeLayout, HardwareDecode.OnDataCallback {
private var texturePreView: TextureView? = null
private var previewBar: SeekBar? = null
private var txtVideoProgress: TextView? = null
private var txtVideoDuration: TextView? = null
private var hardwareDecode: HardwareDecode? = null
private var mPreviewBarCallback: PreviewBarCallback? = null
private var duration: Int = 0
private var screenWidth: Int = 0
private var moveEndPos = 0
private var previewHalfWidth: Int = 0
constructor(context: Context) : super(context) {
initView(context)
}
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
initView(context)
}
private fun initView(context: Context) {
val view = LayoutInflater.from(context).inflate(R.layout.preview_video, this)
previewBar = view.findViewById(R.id.preview_bar)
texturePreView = view.findViewById(R.id.texture_preview)
txtVideoProgress = view.findViewById(R.id.txt_video_progress)
txtVideoDuration = view.findViewById(R.id.txt_video_duration)
setListener()
screenWidth = ScreenUtil.getScreenWidth(context)
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
super.onLayout(changed, l, t, r, b)
if (moveEndPos == 0) {
val previewWidth = texturePreView!!.width
previewHalfWidth = previewWidth / 2
val marginEnd: Int
val layoutParams = texturePreView!!.layoutParams as MarginLayoutParams
marginEnd = layoutParams.marginEnd
moveEndPos = screenWidth - previewWidth - marginEnd
Log.i(TAG, "previewWidth=$previewWidth")
}
}
private fun setPreviewCallback(filePath: String, texturePreView: TextureView) {
texturePreView.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) {
doPreview(filePath, Surface(surface))
}
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {
}
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
return false
}
override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
}
}
}
private fun doPreview(filePath: String, surface: Surface?) {
if (surface == null || TextUtils.isEmpty(filePath)) {
return
}
release()
hardwareDecode = HardwareDecode(surface, filePath, this)
hardwareDecode!!.decode()
}
private fun setListener() {
previewBar!!.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (!fromUser) {
return
}
previewBar!!.progress = progress
if (hardwareDecode != null && progress < duration) {
// us to ms
hardwareDecode!!.seekTo((progress * 1000).toLong())
}
val percent = progress * screenWidth / duration
if (percent in (previewHalfWidth + 1) until moveEndPos && texturePreView != null) {
texturePreView!!.translationX = (percent - previewHalfWidth).toFloat()
}
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
if (texturePreView != null) {
texturePreView!!.visibility = View.VISIBLE
}
if (hardwareDecode != null) {
hardwareDecode!!.setPreviewing(true)
}
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
if (texturePreView != null) {
texturePreView!!.visibility = View.GONE
}
if (mPreviewBarCallback != null) {
mPreviewBarCallback!!.onStopTracking(seekBar.progress.toLong())
}
if (hardwareDecode != null) {
hardwareDecode!!.setPreviewing(false)
}
}
})
}
override fun onData(duration: Long) {
//us to ms
val durationMs = (duration / 1000).toInt()
Log.i(TAG, "duration=$duration")
this.duration = durationMs
post {
previewBar!!.max = durationMs
txtVideoDuration!!.text = TimeUtil.getVideoTime(durationMs.toLong())
texturePreView!!.visibility = View.GONE
}
}
private fun checkArgument(videoPath: String?) {
checkNotNull(texturePreView) { "Must init TextureView first..." }
check(!(videoPath == null || videoPath.isEmpty())) { "videoPath is empty..." }
}
fun init(videoPath: String, previewBarCallback: PreviewBarCallback) {
checkArgument(videoPath)
this.mPreviewBarCallback = previewBarCallback
doPreview(videoPath, Surface(texturePreView!!.surfaceTexture))
}
fun initDefault(videoPath: String, previewBarCallback: PreviewBarCallback) {
checkArgument(videoPath)
this.mPreviewBarCallback = previewBarCallback
setPreviewCallback(videoPath, texturePreView!!)
}
fun updateProgress(progress: Int) {
if (progress in 0..duration) {
txtVideoProgress!!.text = TimeUtil.getVideoTime(progress.toLong())
previewBar!!.progress = progress
}
}
fun release() {
if (hardwareDecode != null) {
hardwareDecode!!.release()
hardwareDecode = null
}
}
interface PreviewBarCallback {
fun onStopTracking(progress: Long)
}
companion object {
private val TAG = VideoPreviewBar::class.java.simpleName
}
}
Loading…
Cancel
Save