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 1418a3c..2ad1aec 100644 --- a/app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.java +++ b/app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.java @@ -1,34 +1,34 @@ package com.frank.ffmpeg.activity; -import android.Manifest; import android.media.MediaPlayer; -import android.os.Build; import android.os.Environment; import android.os.Bundle; +import android.text.TextUtils; import android.util.Log; +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 java.io.IOException; -import androidx.appcompat.app.AppCompatActivity; /** * 视频拖动实时预览 * 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 ROOT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath(); - private static String PATH1 = ROOT_PATH + "/What.mp4"; -// private final static String PATH2 = ROOT_PATH + "/bird-1080P.mkv"; -// PATH1 = "https://www.apple.com/105/media/cn/mac/family/2018/46c4b917_abfd_45a3_9b51_4e3054191797" + + private String videoPath = ROOT_PATH + "/What.mp4"; +// private final static String videoPath = ROOT_PATH + "/bird-1080P.mkv"; +// 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; @@ -36,53 +36,37 @@ public class VideoPreviewActivity extends AppCompatActivity implements HardwareD private long duration; private MediaPlayer mediaPlayer; + private SurfaceView surfaceVideo; + private SurfaceView surfacePreView; + + @Override + int getLayoutId() { + return R.layout.activity_preview; + } @Override protected void onCreate(Bundle 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(); setListener(); } private void initView() { - previewBar = findViewById(R.id.preview_bar); - - SurfaceView surfaceVideo = findViewById(R.id.surface_view); - setCallback(surfaceVideo); + previewBar = getView(R.id.preview_bar); - SurfaceView surfaceView = findViewById(R.id.surface_preview); - setCallbackAndPlay(PATH1, surfaceView); + surfaceVideo = getView(R.id.surface_view); + setPlayCallback(videoPath, surfaceVideo); -// SurfaceView surfaceViewOther = findViewById(R.id.surface_view_other); -// setCallbackAndPlay(PATH2, surfaceViewOther); + surfacePreView = getView(R.id.surface_preview); + setPreviewCallback(videoPath, surfacePreView); } - private void setCallback(SurfaceView surfaceView) { - mediaPlayer = new MediaPlayer(); - mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { - @Override - public void onPrepared(MediaPlayer mp) { - Log.e(TAG, "onPrepared..."); - mediaPlayer.start(); - } - }); - + private void setPlayCallback(final String filePath, SurfaceView surfaceView) { surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { - try { - mediaPlayer.setDataSource(PATH1); - mediaPlayer.setSurface(holder.getSurface()); - mediaPlayer.prepareAsync(); - } catch (IOException e) { - e.printStackTrace(); - } + doPlay(filePath, holder.getSurface()); } @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() { @Override public void surfaceCreated(SurfaceHolder holder) { - - hardwareDecode = new HardwareDecode(holder.getSurface(), filePath, VideoPreviewActivity.this); - hardwareDecode.decode(); + doPreview(filePath, holder.getSurface()); } @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() { previewBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override @@ -155,4 +174,39 @@ public class VideoPreviewActivity extends AppCompatActivity implements HardwareD 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(); + } + } diff --git a/app/src/main/java/com/frank/ffmpeg/hardware/HardwareDecode.java b/app/src/main/java/com/frank/ffmpeg/hardware/HardwareDecode.java index aff80f4..4d366b0 100644 --- a/app/src/main/java/com/frank/ffmpeg/hardware/HardwareDecode.java +++ b/app/src/main/java/com/frank/ffmpeg/hardware/HardwareDecode.java @@ -6,7 +6,6 @@ import android.media.MediaFormat; import android.util.Log; import android.view.Surface; -import java.io.IOException; 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 MediaExtractor mediaExtractor; + private MediaCodec mediaCodec; + void seekTo(long seekPosition) { try { 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 public void run() { super.run(); @@ -99,7 +122,7 @@ public class HardwareDecode { Log.e(TAG, "mediaFormat=" + mediaFormat.toString()); //配置MediaCodec,并且start - MediaCodec mediaCodec = MediaCodec.createDecoderByType(mimeType); + mediaCodec = MediaCodec.createDecoderByType(mimeType); mediaCodec.configure(mediaFormat, mSurface, null, 0); mediaCodec.start(); long startTime = System.currentTimeMillis(); @@ -137,11 +160,6 @@ public class HardwareDecode { Log.e(TAG, "output buffer changed..."); break; 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) { // try { // Thread.sleep(SLEEP_TIME); @@ -160,14 +178,9 @@ public class HardwareDecode { Log.e(TAG, "is end of stream..."); } } - - mediaCodec.stop(); - mediaCodec.release(); - mediaExtractor.release(); - } catch (IOException e) { + } catch (Exception e) { Log.e(TAG, "setDataSource error=" + e.toString()); } - } } diff --git a/app/src/main/res/layout/activity_preview.xml b/app/src/main/res/layout/activity_preview.xml index 581d241..b70d5c9 100644 --- a/app/src/main/res/layout/activity_preview.xml +++ b/app/src/main/res/layout/activity_preview.xml @@ -19,15 +19,6 @@ android:layout_height="240dp" android:layout_centerInParent="true"/> - - 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