diff --git a/app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.java b/app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.java index 2ad1aec..87f3e79 100644 --- a/app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.java +++ b/app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.java @@ -9,10 +9,9 @@ import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; -import android.widget.SeekBar; import com.frank.ffmpeg.R; -import com.frank.ffmpeg.hardware.HardwareDecode; +import com.frank.ffmpeg.view.VideoPreviewBar; import java.io.IOException; @@ -21,7 +20,7 @@ import java.io.IOException; * 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(); @@ -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" + // "/films/bruce/mac-bruce-tpl-cn-2018_1280x720h.mp4"; - private SeekBar previewBar; - private HardwareDecode hardwareDecode; - private long duration; - private MediaPlayer mediaPlayer; - private SurfaceView surfaceVideo; - private SurfaceView surfacePreView; + private VideoPreviewBar videoPreviewBar; @Override int getLayoutId() { @@ -49,17 +43,13 @@ public class VideoPreviewActivity extends BaseActivity implements HardwareDecode super.onCreate(savedInstanceState); initView(); - setListener(); } private void initView() { - previewBar = getView(R.id.preview_bar); - - surfaceVideo = getView(R.id.surface_view); + SurfaceView surfaceVideo = getView(R.id.surface_view); setPlayCallback(videoPath, surfaceVideo); - - surfacePreView = getView(R.id.surface_preview); - setPreviewCallback(videoPath, surfacePreView); + videoPreviewBar = getView(R.id.preview_video); + videoPreviewBar.init(videoPath, this); } 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 - public void onData(long duration) { - Log.e(TAG,"duration=" + duration); - this.duration = duration; - previewBar.setMax((int) duration); + void onViewClick(View view) { + } @Override - void onViewClick(View view) { + void onSelectedFile(String filePath) { } @Override - void onSelectedFile(String filePath) { -// doPlay(filePath, surfaceVideo.getHolder().getSurface()); -// doPreview(filePath, surfacePreView.getHolder().getSurface()); - setPlayCallback(filePath, surfaceVideo); - setPreviewCallback(filePath, surfacePreView); + public void onStopTracking(long progress) { + if (mediaPlayer != null) { + Log.e(TAG, "onStopTracking progress=" + progress); + mediaPlayer.seekTo((int) (progress / 1000)); + } } 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 protected void onDestroy() { super.onDestroy(); - releasePreviewer(); releasePlayer(); + if (videoPreviewBar != null) { + videoPreviewBar.release(); + } } } diff --git a/app/src/main/java/com/frank/ffmpeg/view/VideoPreviewBar.java b/app/src/main/java/com/frank/ffmpeg/view/VideoPreviewBar.java new file mode 100644 index 0000000..7919be9 --- /dev/null +++ b/app/src/main/java/com/frank/ffmpeg/view/VideoPreviewBar.java @@ -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); + } + +} diff --git a/app/src/main/res/layout/activity_preview.xml b/app/src/main/res/layout/activity_preview.xml index b70d5c9..8a8150f 100644 --- a/app/src/main/res/layout/activity_preview.xml +++ b/app/src/main/res/layout/activity_preview.xml @@ -5,27 +5,17 @@ android:layout_height="match_parent" tools:context=".activity.VideoPreviewActivity"> - - - + android:layout_alignParentBottom="true" + android:layout_marginBottom="30dp"/> \ No newline at end of file diff --git a/app/src/main/res/layout/preview_video.xml b/app/src/main/res/layout/preview_video.xml new file mode 100644 index 0000000..d19e659 --- /dev/null +++ b/app/src/main/res/layout/preview_video.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file