您的位置:首页 > 移动开发 > Android开发

Android屏幕录制源码Demo下载

2015-11-07 17:36 477 查看
Android实现屏幕录制的方式介绍两种,第一种是通过adb shell命令,还一种使用SDK的提供的方法实现.
adb shell 命令

语法: screenrecord [options] <filename>

Sample:

adb shell screenrecord /sdcard/demo.mp4
开始录制(录制手机屏幕; 视频格式为mp4,存放到手机sd卡里,默认录制时间为180s)

参数: --size
adb shell screenrecord --size 1280*720 /sdcard/demo.mp4
指定视频分辨率大小 (指定分辨率为1280*720;不指定则默认使用手机的分辨率,为获得最佳效果,请使用设备上的高级视频编码(AVC)支持的大小)

参数: --bit-rate
adb shell screenrecord --bit-rate 6000000 /sdcard/demo.mp4
指定视频的比特率 (指定视频的比特率为6Mbps; 如果不指定则默认为4Mbps, 你可以增加比特率以提高视频质量或为了让文件更小而降低比特率)

参数: --time-limit
adb shell screenrecord  --time-limit 10 /sdcard/demo.mp4
限制录制时间 (限制视频录制时间为10s; 如果不限制,默认180s)

参数: --verbose
adb shell screenrecord --time-limit 10 --verbose /sdcard/demo.mp4
在命令行显示录屏Log如下:
xxxx:/ # screenrecord --time-limit 10 --verbose /sdcard/demo.mp4
Main display is 1080x2160 @60.00fps (orientation=0)
Configuring recorder for 1080x2160 video/avc at 4.00Mbps
Content area is 1080x2160 at offset x=0 y=0
Time limit reached
Encoder stopping; recorded 34 frames in 10 seconds
Stopping encoder and muxer
Executing: /system/bin/am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/demo.mp4
Broadcasting: Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/demo.mp4 }
Broadcast completed: result=0

参数: --bugreport
添加额外的信息,例如时间戳覆盖,这有助于捕获用于演示错误的视频

参数: --help
查看帮助

导出视频:
adb pull /sdcard/demo.mp4


如果在APP中使用,我们可以通过Process p = Runtime.getRuntime().exec(cmd)来调用shell命令.但是只有system app才能调用,可以在manifest节点中添加android:sharedUserId="android.uid.system"拥有系统级的权限
通过MediaProjection实现





1.动态申请录音和外部存储权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 10);
}


2.获取屏幕录制的权限
MediaProjectionManager manager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
Intent intent = new Intent(manager.createScreenCaptureIntent());
startActivityForResult(intent, REQUEST_CODE);


3.启动屏幕录制服务
Intent service = new Intent(this, ScreenRecordService.class);
service.putExtra("resultCode", resultCode);
service.putExtra("data", data);
service.putExtra("mWidthPixels", mWidthPixels);
service.putExtra("mHeightPixels", mHeightPixels);
service.putExtra("mDensityDpi", mDensityDpi);
startService(service);


屏幕录制服务
public class ScreenRecordService extends Service {

private static final String TAG = "ScreenRecordService";
private WindowManager mWindowManager;
private WindowManager.LayoutParams wmParams;
private LinearLayout mFloatLayout;
private MediaProjection mMediaProjection;
private MediaRecorder mMediaRecorder;
private VirtualDisplay mVirtualDisplay;
private boolean isScreenRecord;
private int mScreenDensity, mWidthPixels, mHeightPixels;

@Override
public IBinder onBind(Intent intent) {
//        return new MyBinder();
return null;
}

@Override
public void onCreate() {
super.onCreate();
initView();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

int resultCode = intent.getIntExtra("resultCode", -1);
Intent data = intent.getParcelableExtra("data");
mWidthPixels = intent.getIntExtra("mWidthPixels", 720);
mHeightPixels = intent.getIntExtra("mHeightPixels", 1080);
mScreenDensity = intent.getIntExtra("mDensityDpi", 1);
Log.d(TAG, "initData  -->  mScreenDensity: " + mScreenDensity + "  mWidthPixels: " + mWidthPixels + "  mHeightPixels: " + mHeightPixels);
mMediaProjection = ((MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE))
.getMediaProjection(resultCode, data);

return super.onStartCommand(intent, flags, startId);
}

private void startRecorder() {
Log.d(TAG, "startRecord");

isScreenRecord = true;

createMediaRecorder();

createVirtualDisplay(); // 在mediaRecorder.prepare() 之后调用,否则报错 failed to get surface

mMediaRecorder.start();
}

private void createVirtualDisplay() {
mVirtualDisplay = mMediaProjection.createVirtualDisplay(TAG, mWidthPixels, mHeightPixels, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder.getSurface(), null, null);
}

private void createMediaRecorder() {
// 生成文件名
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String curTime = formatter.format(new Date(System.currentTimeMillis()));

mMediaRecorder = new MediaRecorder();

//设置视频源: DEFAULT,Surface,Camera
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);

//设置视频输出格式: amr_nb,amr_wb,default,mpeg_4,raw_amr,three_gpp
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

//设置视频编码格式: default, H263, H264, MPEG_4_SP
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

//        //设置音频源
//        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
//
//        //设置音频编码格式: default,AAC,AMR_NB,AMR_WB
//        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

//设置视频尺寸大小
mMediaRecorder.setVideoSize(mWidthPixels, mHeightPixels);

//设置视频编码的码率
mMediaRecorder.setVideoEncodingBitRate(5 * mWidthPixels * mHeightPixels);   // mWidthPixels * mHeightPixels

//设置视频编码的帧率
mMediaRecorder.setVideoFrameRate(60);   // 30

//设置视频输出路径
mMediaRecorder.setOutputFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/Ansen_" + curTime + ".mp4");

try {
mMediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
}
Log.d(TAG, "VideoSize: " + mWidthPixels + " X " + mHeightPixels + "  VideoEncodingBitRate: "
+ (5 * mWidthPixels * mHeightPixels) + "  +VideoFrameRate: " + "60");
}

private void initView() {
mWindowManager = (WindowManager) getApplication().getSystemService(getApplication().WINDOW_SERVICE);
wmParams = new WindowManager.LayoutParams();
wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;// 设置window type为TYPE_SYSTEM_ALERT
wmParams.format = PixelFormat.RGBA_8888;// 设置图片格式,效果为背景透明
wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作)
wmParams.gravity = Gravity.LEFT | Gravity.TOP;// 默认位置:右下角
wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
wmParams.x = (ScreenUtils.getScreenWidth(getApplicationContext()) - wmParams.width) / 2;// 设置x、y初始值,相对于gravity
wmParams.y = 10;
// 浮动窗口布局
mFloatLayout = (LinearLayout) LayoutInflater.from(getApplication()).inflate(R.layout.screen_recorder, null);
mWindowManager.addView(mFloatLayout, wmParams);
final LinearLayout screenrecord = (LinearLayout) mFloatLayout.findViewById(R.id.screenrecord);
final TextView title = (TextView) mFloatLayout.findViewById(R.id.screenrecord_title);
final TextView close = (TextView) mFloatLayout.findViewById(R.id.screenrecord_close);
final ImageView image = (ImageView) mFloatLayout.findViewById(R.id.play_stop);
mFloatLayout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));

// 设置监听浮动窗口的触摸移动
View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {
// getRawX是触摸位置相对于屏幕的坐标,getX是相对于按钮的坐标
wmParams.x = (int) event.getRawX() - mFloatLayout.getMeasuredWidth() / 2;
Log.i(TAG, "RawX" + event.getRawX() + "  X" + event.getX());
wmParams.y = (int) event.getRawY() - mFloatLayout.getMeasuredHeight() / 2 - 25;// 减25为状态栏的高度
Log.i(TAG, "RawY" + event.getRawY() + "  Y" + event.getY());
mWindowManager.updateViewLayout(mFloatLayout, wmParams);// 刷新
return false;
}
};
mFloatLayout.setOnTouchListener(mOnTouchListener);
screenrecord.setOnTouchListener(mOnTouchListener);
screenrecord.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (isScreenRecord) {
image.setImageResource(R.mipmap.screen_record_play);
title.setText("开始");
stopRecord();
} else {
image.setImageResource(R.mipmap.screen_record_stop);
title.setText("停止");
startRecorder();
}
}
});
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "stopSelf");
ScreenRecordService.this.stopSelf();

}
});
}

private void stopRecord() {
Log.d(TAG, "stopRecord");
isScreenRecord = false;

mMediaRecorder.stop();
mMediaRecorder.reset();

}

@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
if (isScreenRecord) {
stopRecord();
}

mVirtualDisplay.release();
mMediaProjection.stop();

mWindowManager.removeView(mFloatLayout);
}
}


代码地址

Android屏幕截图实现方式 & 系统截屏源码分析和三指截屏
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: