视频拖动预览封装成独立控件

视频拖动预览封装成独立控件
pull/107/head
xufulong 5 years ago
parent 0e4fc7100a
commit 4ffee8a1c5
  1. 108
      app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.java
  2. 137
      app/src/main/java/com/frank/ffmpeg/view/VideoPreviewBar.java
  3. 18
      app/src/main/res/layout/activity_preview.xml
  4. 23
      app/src/main/res/layout/preview_video.xml

@ -9,10 +9,9 @@ import android.view.Surface;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
import android.view.View; import android.view.View;
import android.widget.SeekBar;
import com.frank.ffmpeg.R; import com.frank.ffmpeg.R;
import com.frank.ffmpeg.hardware.HardwareDecode; import com.frank.ffmpeg.view.VideoPreviewBar;
import java.io.IOException; import java.io.IOException;
@ -21,7 +20,7 @@ import java.io.IOException;
* Created by frank on 2019/11/16. * Created by frank on 2019/11/16.
*/ */
public class VideoPreviewActivity extends BaseActivity implements HardwareDecode.OnDataCallback { public class VideoPreviewActivity extends BaseActivity implements VideoPreviewBar.PreviewBarCallback {
private final static String TAG = VideoPreviewActivity.class.getSimpleName(); private final static String TAG = VideoPreviewActivity.class.getSimpleName();
@ -31,13 +30,8 @@ public class VideoPreviewActivity extends BaseActivity implements HardwareDecode
// videoPath = "https://www.apple.com/105/media/cn/mac/family/2018/46c4b917_abfd_45a3_9b51_4e3054191797" + // videoPath = "https://www.apple.com/105/media/cn/mac/family/2018/46c4b917_abfd_45a3_9b51_4e3054191797" +
// "/films/bruce/mac-bruce-tpl-cn-2018_1280x720h.mp4"; // "/films/bruce/mac-bruce-tpl-cn-2018_1280x720h.mp4";
private SeekBar previewBar;
private HardwareDecode hardwareDecode;
private long duration;
private MediaPlayer mediaPlayer; private MediaPlayer mediaPlayer;
private SurfaceView surfaceVideo; private VideoPreviewBar videoPreviewBar;
private SurfaceView surfacePreView;
@Override @Override
int getLayoutId() { int getLayoutId() {
@ -49,17 +43,13 @@ public class VideoPreviewActivity extends BaseActivity implements HardwareDecode
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
initView(); initView();
setListener();
} }
private void initView() { private void initView() {
previewBar = getView(R.id.preview_bar); SurfaceView surfaceVideo = getView(R.id.surface_view);
surfaceVideo = getView(R.id.surface_view);
setPlayCallback(videoPath, surfaceVideo); setPlayCallback(videoPath, surfaceVideo);
videoPreviewBar = getView(R.id.preview_video);
surfacePreView = getView(R.id.surface_preview); videoPreviewBar.init(videoPath, this);
setPreviewCallback(videoPath, surfacePreView);
} }
private void setPlayCallback(final String filePath, SurfaceView surfaceView) { private void setPlayCallback(final String filePath, SurfaceView surfaceView) {
@ -110,81 +100,22 @@ public class VideoPreviewActivity extends BaseActivity implements HardwareDecode
} }
} }
private void setPreviewCallback(final String filePath, SurfaceView surfaceView) {
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
doPreview(filePath, holder.getSurface());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
}
private void doPreview(String filePath, Surface surface) {
if (surface == null || TextUtils.isEmpty(filePath)) {
return;
}
releasePreviewer();
hardwareDecode = new HardwareDecode(surface, filePath, VideoPreviewActivity.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) {
hardwareDecode.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//TODO
if (mediaPlayer != null) {
Log.e(TAG, "onStop progress=" + seekBar.getProgress());
mediaPlayer.seekTo(seekBar.getProgress()/1000);
}
}
});
}
@Override @Override
public void onData(long duration) { void onViewClick(View view) {
Log.e(TAG,"duration=" + duration);
this.duration = duration;
previewBar.setMax((int) duration);
} }
@Override @Override
void onViewClick(View view) { void onSelectedFile(String filePath) {
} }
@Override @Override
void onSelectedFile(String filePath) { public void onStopTracking(long progress) {
// doPlay(filePath, surfaceVideo.getHolder().getSurface()); if (mediaPlayer != null) {
// doPreview(filePath, surfacePreView.getHolder().getSurface()); Log.e(TAG, "onStopTracking progress=" + progress);
setPlayCallback(filePath, surfaceVideo); mediaPlayer.seekTo((int) (progress / 1000));
setPreviewCallback(filePath, surfacePreView); }
} }
private void releasePlayer() { private void releasePlayer() {
@ -195,18 +126,13 @@ public class VideoPreviewActivity extends BaseActivity implements HardwareDecode
} }
} }
private void releasePreviewer() {
if (hardwareDecode != null) {
hardwareDecode.release();
hardwareDecode = null;
}
}
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
releasePreviewer();
releasePlayer(); releasePlayer();
if (videoPreviewBar != null) {
videoPreviewBar.release();
}
} }
} }

@ -0,0 +1,137 @@
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 com.frank.ffmpeg.R;
import com.frank.ffmpeg.hardware.HardwareDecode;
/**
* 视频拖动实时预览的控件
* 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 HardwareDecode hardwareDecode;
private long duration;
private PreviewBarCallback mPreviewBarCallback;
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);
setListener();
}
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) {
hardwareDecode.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (mPreviewBarCallback != null) {
mPreviewBarCallback.onStopTracking(seekBar.getProgress());
}
}
});
}
@Override
public void onData(long duration) {
Log.i(TAG, "duration=" + duration);
this.duration = duration;
previewBar.setMax((int) duration);
}
public void init(String videoPath, PreviewBarCallback previewBarCallback) {
this.mPreviewBarCallback = previewBarCallback;
setPreviewCallback(videoPath, texturePreView);
}
public void release() {
if (hardwareDecode != null) {
hardwareDecode.release();
hardwareDecode = null;
}
}
public interface PreviewBarCallback {
void onStopTracking(long progress);
}
}

@ -5,27 +5,17 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".activity.VideoPreviewActivity"> tools:context=".activity.VideoPreviewActivity">
<SurfaceView
android:id="@+id/surface_preview"
android:layout_width="64dp"
android:layout_height="48dp"
android:layout_centerInParent="true"
android:layout_marginBottom="50dp"
android:layout_marginEnd="50dp" />
<SurfaceView <SurfaceView
android:id="@+id/surface_view" android:id="@+id/surface_view"
android:layout_width="320dp" android:layout_width="320dp"
android:layout_height="240dp" android:layout_height="240dp"
android:layout_centerInParent="true"/> android:layout_centerInParent="true"/>
<SeekBar <com.frank.ffmpeg.view.VideoPreviewBar
android:id="@+id/preview_bar" android:id="@+id/preview_video"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="20dp" android:layout_alignParentBottom="true"
android:layout_marginEnd="20dp" android:layout_marginBottom="30dp"/>
android:layout_marginBottom="40dp"
android:layout_alignParentBottom="true"/>
</RelativeLayout> </RelativeLayout>

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<SeekBar
android:id="@+id/preview_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="40dp"
android:layout_alignParentBottom="true"/>
<TextureView
android:id="@+id/texture_preview"
android:layout_width="80dp"
android:layout_height="60dp"
android:layout_above="@+id/preview_bar"
android:layout_marginBottom="20dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp" />
</RelativeLayout>
Loading…
Cancel
Save