Skip to content

Commit

Permalink
commit
Browse files Browse the repository at this point in the history
  • Loading branch information
HelloHuDi committed May 19, 2018
1 parent 6a04866 commit c25816f
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 60 deletions.
51 changes: 30 additions & 21 deletions app/src/main/java/com/hd/screen/capture/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.hd.screencapture.ScreenCapture;
import com.hd.screencapture.ScreenCaptureCallback;
import com.hd.screencapture.ScreenCaptureState;
import com.hd.screencapture.callback.ScreenCaptureCallback;
import com.hd.screencapture.config.AudioConfig;
import com.hd.screencapture.config.ScreenCaptureConfig;
import com.hd.screencapture.config.VideoConfig;
import com.hd.screencapture.help.ScreenCaptureState;


/**
Expand All @@ -19,6 +22,8 @@ public class MainActivity extends AppCompatActivity implements ScreenCaptureCall

private ScreenCapture screenCapture;

private boolean isRunning;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All @@ -28,35 +33,39 @@ protected void onCreate(Bundle savedInstanceState) {

private void init() {
ScreenCaptureConfig captureConfig = new ScreenCaptureConfig.Builder()//
.setAudioConfig(AudioConfig.initDefaultConfig())//
.setCaptureCallback(this)//
.setAutoMoveTaskToBack(true)//
.create();//
.setVideoConfig(VideoConfig.initDefaultConfig(this))//
.setAudioConfig(AudioConfig.initDefaultConfig())//
.setCaptureCallback(this)//
.setAutoMoveTaskToBack(true)//
.create();//
screenCapture = ScreenCapture.with(this).setConfig(captureConfig);
}

public void startCapture(View view) {
screenCapture.startCapture();
if (!isRunning) {
screenCapture.startCapture();
} else {
Toast.makeText(MainActivity.this, "current is capturing state", Toast.LENGTH_SHORT).show();
}
}

public void stopCapture(View view) {
screenCapture.stopCapture();
if (isRunning) {
screenCapture.stopCapture();
} else {
Toast.makeText(MainActivity.this, "current is stopped state", Toast.LENGTH_SHORT).show();
}
}

@Override
public void captureState(ScreenCaptureState state) {
Log.d("tag", "capture state ==>" + state);
switch (state) {
case PREPARE:
break;
case START:
break;
case CAPTURING:
break;
case FAILED:
break;
case COMPLETED:
break;
}
isRunning = !(ScreenCaptureState.FAILED == state || ScreenCaptureState.COMPLETED == state);
Log.d("tag", "capture state ==>" + state + "==" + isRunning);
runOnUiThread(() -> Toast.makeText(MainActivity.this, "capture state ==>" + state, Toast.LENGTH_SHORT).show());
}

@Override
public void captureTime(long time) {
Log.d("tag", "capture time ==>" + time + "===" + DateUtils.formatElapsedTime(time));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.hd.screencapture.config.ScreenCaptureConfig;
import com.hd.screencapture.help.ScreenCaptureFragment;
import com.hd.screencapture.help.Utils;
import com.hd.screencapture.observer.CaptureObserver;
import com.hd.screencapture.observer.ScreenCaptureObserver;

import java.util.Timer;
import java.util.TimerTask;
Expand All @@ -19,7 +24,7 @@
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class ScreenCapture {

private final String TAG = "Screen-Capture";
private static final String TAG = "Screen-Capture";

public static ScreenCapture with(@NonNull AppCompatActivity activity) {
if (activity.isFinishing() || activity.isDestroyed()) {
Expand All @@ -28,6 +33,9 @@ public static ScreenCapture with(@NonNull AppCompatActivity activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
throw new RuntimeException("the sdk version less than 21 equipment does not provide this function !");
}
if(!Utils.isExternalStorageReady()){
Log.e(TAG,"current no storage space");
}
return new ScreenCapture(activity);
}

Expand All @@ -46,7 +54,7 @@ private ScreenCapture(@NonNull AppCompatActivity activity) {
setConfig(ScreenCaptureConfig.initDefaultConfig(activity));
}

private ScreenCaptureFragment getScreenCaptureFragment(Activity activity) {
private ScreenCaptureFragment getScreenCaptureFragment(@NonNull Activity activity) {
ScreenCaptureFragment screenCaptureFragment = findScreenCaptureFragment(activity);
boolean isNewInstance = screenCaptureFragment == null;
if (isNewInstance) {
Expand All @@ -58,11 +66,13 @@ private ScreenCaptureFragment getScreenCaptureFragment(Activity activity) {
return screenCaptureFragment;
}

private ScreenCaptureFragment findScreenCaptureFragment(Activity activity) {
private ScreenCaptureFragment findScreenCaptureFragment(@NonNull Activity activity) {
return (ScreenCaptureFragment) activity.getFragmentManager().findFragmentByTag(TAG);
}

public ScreenCapture setConfig(ScreenCaptureConfig config) {
public ScreenCapture setConfig(@NonNull ScreenCaptureConfig config) {
if (config.getVideoConfig() == null)
throw new RuntimeException("you must set the capture video config before start capture ");
screenCaptureFragment.setConfig(config);
observer.initConfig(config);
return this;
Expand Down
7 changes: 0 additions & 7 deletions screencapture/src/main/java/com/hd/screencapture/Utils.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package com.hd.screencapture;
package com.hd.screencapture.callback;

import com.hd.screencapture.help.ScreenCaptureState;

/**
* Created by hd on 2018/5/15 .
Expand All @@ -9,4 +11,9 @@ public interface ScreenCaptureCallback {
* report capture state{@link ScreenCaptureState}
*/
void captureState(ScreenCaptureState state);

/**
* report capture time,unit seconds
*/
void captureTime(long time);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.hd.screencapture;
package com.hd.screencapture.capture;

import android.annotation.TargetApi;
import android.hardware.display.DisplayManager;
Expand All @@ -9,11 +9,14 @@
import android.media.MediaMuxer;
import android.media.projection.MediaProjection;
import android.os.Build;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.Surface;

import com.hd.screencapture.config.ScreenCaptureConfig;
import com.hd.screencapture.help.ScreenCaptureState;
import com.hd.screencapture.observer.CaptureObserver;

import java.io.IOException;
import java.nio.ByteBuffer;
Expand Down Expand Up @@ -49,7 +52,7 @@ public class ScreenCaptureRecorder extends Thread {

private Surface mSurface;

ScreenCaptureRecorder(@NonNull MediaProjection mediaProjection, @NonNull ScreenCaptureConfig config) {
public ScreenCaptureRecorder(@NonNull MediaProjection mediaProjection, @NonNull ScreenCaptureConfig config) {
this.mediaProjection = mediaProjection;
this.config = config;
}
Expand All @@ -70,27 +73,22 @@ public void stopCapture() {
@Override
public void run() {
super.run();
boolean error = false;
try {
observer.reportState(ScreenCaptureState.CAPTURING);
prepareEncoder();
mMuxer = new MediaMuxer(config.getFile().getAbsolutePath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
mVirtualDisplay = mediaProjection.createVirtualDisplay(TAG + "-display",//
config.getVideoConfig().getWidth(), config.getVideoConfig().getHeight(), config.getVideoConfig().getDpi(), //
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR/*VIRTUAL_DISPLAY_FLAG_PUBLIC*/,//
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,//
mSurface, null, null);
Log.d(TAG, "created virtual display: " + mVirtualDisplay);
recordVirtualDisplay();
} catch (Exception e) {
error = true;
e.printStackTrace();
observer.reportState(ScreenCaptureState.FAILED);
observer.stopCapture();
} finally {
release();
if (!error) {
observer.reportState(ScreenCaptureState.COMPLETED);
}
}
}

Expand Down Expand Up @@ -131,6 +129,7 @@ private void recordVirtualDisplay() {
mEncoder.releaseOutputBuffer(index, false);
}
}
observer.reportState(ScreenCaptureState.COMPLETED);
}

private void encodeToVideoTrack(int index) {
Expand All @@ -146,16 +145,45 @@ private void encodeToVideoTrack(int index) {
Log.d(TAG, "info.size == 0, drop it.");
encodedData = null;
} else {
Log.d(TAG, "got buffer, info: size=" + mBufferInfo.size + ", presentationTimeUs=" + mBufferInfo.presentationTimeUs + ", offset=" + mBufferInfo.offset);
Log.d(TAG, "got buffer, info: size=" + mBufferInfo.size +//
", presentationTimeUs=" + mBufferInfo.presentationTimeUs + ", offset=" + mBufferInfo.offset);
}
if (encodedData != null) {
setCaptureTime();
encodedData.position(mBufferInfo.offset);
encodedData.limit(mBufferInfo.offset + mBufferInfo.size);
mMuxer.writeSampleData(mVideoTrackIndex, encodedData, mBufferInfo);
Log.i(TAG, "sent " + mBufferInfo.size + " bytes to muxer...");
}
}

private void setCaptureTime() {
if (mBufferInfo.presentationTimeUs != 0) {
resetVideoPts(mBufferInfo);
}
if (startTime <= 0) {
startTime = mBufferInfo.presentationTimeUs;
}
long time = (mBufferInfo.presentationTimeUs - startTime) / 1000 / 1000;
//no need to report when time less than one second
if (SystemClock.elapsedRealtime() - mLastFiredTime < 1000) {
return;
}
observer.reportTime(time);
mLastFiredTime = SystemClock.elapsedRealtime();
}

private long mVideoPtsOffset, startTime, mLastFiredTime;

private void resetVideoPts(MediaCodec.BufferInfo buffer) {
if (mVideoPtsOffset == 0) {
mVideoPtsOffset = buffer.presentationTimeUs;
buffer.presentationTimeUs = 0;
} else {
buffer.presentationTimeUs -= mVideoPtsOffset;
}
}

private void resetOutputFormat() {
// should happen before receiving buffers, and should only happen once
if (mMuxerStarted) {
Expand Down Expand Up @@ -189,6 +217,6 @@ private void release() {
mMuxer.release();
mMuxer = null;
}
Log.d("tag","recorder release complete");
Log.d("tag", "recorder release complete");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
import android.app.Activity;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.util.DisplayMetrics;

import com.hd.screencapture.ScreenCaptureCallback;
import com.hd.screencapture.callback.ScreenCaptureCallback;

import java.io.File;

Expand Down Expand Up @@ -55,13 +54,7 @@ public static ScreenCaptureConfig initDefaultConfig() {
}

public static ScreenCaptureConfig initDefaultConfig(@NonNull Activity activity) {
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
VideoConfig videoConfig=new VideoConfig();
videoConfig.setDpi(metrics.densityDpi);
videoConfig.setWidth(metrics.widthPixels);
videoConfig.setHeight(metrics.heightPixels);
return initDefaultConfig(videoConfig);
return initDefaultConfig(VideoConfig.initDefaultConfig(activity));
}

public VideoConfig getVideoConfig() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.hd.screencapture.config;

import android.app.Activity;
import android.support.annotation.NonNull;
import android.util.DisplayMetrics;

/**
* Created by hd on 2018/5/18 .
*/
Expand Down Expand Up @@ -34,6 +38,16 @@ public static VideoConfig initDefaultConfig() {
return new VideoConfig();
}

public static VideoConfig initDefaultConfig(@NonNull Activity activity) {
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
VideoConfig videoConfig = new VideoConfig();
videoConfig.setDpi(metrics.densityDpi);
videoConfig.setWidth(metrics.widthPixels);
videoConfig.setHeight(metrics.heightPixels);
return videoConfig;
}

public int getWidth() {
return width;
}
Expand Down
Loading

0 comments on commit c25816f

Please sign in to comment.