VideoPreviewActivity接入基类Activity

VideoPreviewActivity接入基类Activity
pull/107/head
xufulong 5 years ago
parent 3e8442ce4a
commit 86c63dda59
  1. 136
      app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.java
  2. 39
      app/src/main/java/com/frank/ffmpeg/hardware/HardwareDecode.java
  3. 9
      app/src/main/res/layout/activity_preview.xml
  4. 90
      gradlew.bat

@ -1,34 +1,34 @@
package com.frank.ffmpeg.activity; package com.frank.ffmpeg.activity;
import android.Manifest;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.os.Build;
import android.os.Environment; import android.os.Environment;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
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.widget.SeekBar; import android.widget.SeekBar;
import com.frank.ffmpeg.R; import com.frank.ffmpeg.R;
import com.frank.ffmpeg.hardware.HardwareDecode; import com.frank.ffmpeg.hardware.HardwareDecode;
import java.io.IOException; import java.io.IOException;
import androidx.appcompat.app.AppCompatActivity;
/** /**
* 视频拖动实时预览 * 视频拖动实时预览
* Created by frank on 2019/11/16. * Created by frank on 2019/11/16.
*/ */
public class VideoPreviewActivity extends AppCompatActivity implements HardwareDecode.OnDataCallback { public class VideoPreviewActivity extends BaseActivity implements HardwareDecode.OnDataCallback {
private final static String TAG = VideoPreviewActivity.class.getSimpleName(); private final static String TAG = VideoPreviewActivity.class.getSimpleName();
private final static String ROOT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath(); private final static String ROOT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
private static String PATH1 = ROOT_PATH + "/What.mp4"; private String videoPath = ROOT_PATH + "/What.mp4";
// private final static String PATH2 = ROOT_PATH + "/bird-1080P.mkv"; // private final static String videoPath = ROOT_PATH + "/bird-1080P.mkv";
// PATH1 = "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 SeekBar previewBar;
@ -36,53 +36,37 @@ public class VideoPreviewActivity extends AppCompatActivity implements HardwareD
private long duration; private long duration;
private MediaPlayer mediaPlayer; private MediaPlayer mediaPlayer;
private SurfaceView surfaceVideo;
private SurfaceView surfacePreView;
@Override
int getLayoutId() {
return R.layout.activity_preview;
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1234);
}
initView(); initView();
setListener(); setListener();
} }
private void initView() { private void initView() {
previewBar = findViewById(R.id.preview_bar); previewBar = getView(R.id.preview_bar);
SurfaceView surfaceVideo = findViewById(R.id.surface_view);
setCallback(surfaceVideo);
SurfaceView surfaceView = findViewById(R.id.surface_preview); surfaceVideo = getView(R.id.surface_view);
setCallbackAndPlay(PATH1, surfaceView); setPlayCallback(videoPath, surfaceVideo);
// SurfaceView surfaceViewOther = findViewById(R.id.surface_view_other); surfacePreView = getView(R.id.surface_preview);
// setCallbackAndPlay(PATH2, surfaceViewOther); setPreviewCallback(videoPath, surfacePreView);
} }
private void setCallback(SurfaceView surfaceView) { private void setPlayCallback(final String filePath, SurfaceView surfaceView) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
Log.e(TAG, "onPrepared...");
mediaPlayer.start();
}
});
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override @Override
public void surfaceCreated(SurfaceHolder holder) { public void surfaceCreated(SurfaceHolder holder) {
try { doPlay(filePath, holder.getSurface());
mediaPlayer.setDataSource(PATH1);
mediaPlayer.setSurface(holder.getSurface());
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
} }
@Override @Override
@ -95,16 +79,42 @@ public class VideoPreviewActivity extends AppCompatActivity implements HardwareD
} }
}); });
}
private void setPrepareListener() {
if (mediaPlayer == null) {
return;
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
Log.e(TAG, "onPrepared...");
mediaPlayer.start();
}
});
}
private void doPlay(String filePath, Surface surface) {
if (surface == null || TextUtils.isEmpty(filePath)) {
return;
}
releasePlayer();
try {
mediaPlayer = new MediaPlayer();
setPrepareListener();
mediaPlayer.setDataSource(filePath);
mediaPlayer.setSurface(surface);
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
} }
private void setCallbackAndPlay(final String filePath, SurfaceView surfaceView) { private void setPreviewCallback(final String filePath, SurfaceView surfaceView) {
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override @Override
public void surfaceCreated(SurfaceHolder holder) { public void surfaceCreated(SurfaceHolder holder) {
doPreview(filePath, holder.getSurface());
hardwareDecode = new HardwareDecode(holder.getSurface(), filePath, VideoPreviewActivity.this);
hardwareDecode.decode();
} }
@Override @Override
@ -119,6 +129,15 @@ public class VideoPreviewActivity extends AppCompatActivity implements HardwareD
}); });
} }
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() { private void setListener() {
previewBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { previewBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override @Override
@ -155,4 +174,39 @@ public class VideoPreviewActivity extends AppCompatActivity implements HardwareD
previewBar.setMax((int) duration); previewBar.setMax((int) duration);
} }
@Override
void onViewClick(View view) {
}
@Override
void onSelectedFile(String filePath) {
// doPlay(filePath, surfaceVideo.getHolder().getSurface());
// doPreview(filePath, surfacePreView.getHolder().getSurface());
setPlayCallback(filePath, surfaceVideo);
setPreviewCallback(filePath, surfacePreView);
}
private void releasePlayer() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
private void releasePreviewer() {
if (hardwareDecode != null) {
hardwareDecode.release();
hardwareDecode = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
releasePreviewer();
releasePlayer();
}
} }

@ -6,7 +6,6 @@ import android.media.MediaFormat;
import android.util.Log; import android.util.Log;
import android.view.Surface; import android.view.Surface;
import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
/** /**
@ -51,10 +50,20 @@ public class HardwareDecode {
} }
} }
public void release() {
if (videoDecodeThread != null && !videoDecodeThread.isInterrupted()) {
videoDecodeThread.interrupt();
videoDecodeThread.release();
videoDecodeThread = null;
}
}
private class VideoDecodeThread extends Thread { private class VideoDecodeThread extends Thread {
private MediaExtractor mediaExtractor; private MediaExtractor mediaExtractor;
private MediaCodec mediaCodec;
void seekTo(long seekPosition) { void seekTo(long seekPosition) {
try { try {
if (mediaExtractor != null) { if (mediaExtractor != null) {
@ -65,6 +74,20 @@ public class HardwareDecode {
} }
} }
void release() {
try {
if (mediaCodec != null) {
mediaCodec.stop();
mediaCodec.release();
}
if (mediaExtractor != null) {
mediaExtractor.release();
}
}catch (Exception e) {
Log.e(TAG, "release error=" + e.toString());
}
}
@Override @Override
public void run() { public void run() {
super.run(); super.run();
@ -99,7 +122,7 @@ public class HardwareDecode {
Log.e(TAG, "mediaFormat=" + mediaFormat.toString()); Log.e(TAG, "mediaFormat=" + mediaFormat.toString());
//配置MediaCodec,并且start //配置MediaCodec,并且start
MediaCodec mediaCodec = MediaCodec.createDecoderByType(mimeType); mediaCodec = MediaCodec.createDecoderByType(mimeType);
mediaCodec.configure(mediaFormat, mSurface, null, 0); mediaCodec.configure(mediaFormat, mSurface, null, 0);
mediaCodec.start(); mediaCodec.start();
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
@ -137,11 +160,6 @@ public class HardwareDecode {
Log.e(TAG, "output buffer changed..."); Log.e(TAG, "output buffer changed...");
break; break;
default: default:
// long time = (System.currentTimeMillis()-startTime);
// if (time > 50) {
// Log.e(TAG, "pts=" + bufferInfo.presentationTimeUs + "--time=" + time);
// }
// startTime = System.currentTimeMillis();
// while (bufferInfo.presentationTimeUs > (System.currentTimeMillis() - startTime)*1000) { // while (bufferInfo.presentationTimeUs > (System.currentTimeMillis() - startTime)*1000) {
// try { // try {
// Thread.sleep(SLEEP_TIME); // Thread.sleep(SLEEP_TIME);
@ -160,14 +178,9 @@ public class HardwareDecode {
Log.e(TAG, "is end of stream..."); Log.e(TAG, "is end of stream...");
} }
} }
} catch (Exception e) {
mediaCodec.stop();
mediaCodec.release();
mediaExtractor.release();
} catch (IOException e) {
Log.e(TAG, "setDataSource error=" + e.toString()); Log.e(TAG, "setDataSource error=" + e.toString());
} }
} }
} }

@ -19,15 +19,6 @@
android:layout_height="240dp" android:layout_height="240dp"
android:layout_centerInParent="true"/> android:layout_centerInParent="true"/>
<SurfaceView
android:id="@+id/surface_view_other"
android:layout_width="200dp"
android:layout_height="100dp"
android:layout_marginTop="100dp"
android:layout_centerHorizontal="true"
android:layout_below="@+id/surface_view"
android:visibility="gone"/>
<SeekBar <SeekBar
android:id="@+id/preview_bar" android:id="@+id/preview_bar"
android:layout_width="match_parent" android:layout_width="match_parent"

90
gradlew.bat vendored

@ -1,90 +0,0 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
Loading…
Cancel
Save