基本信息
源码名称:android 录屏及截图
源码大小:8.24M
文件格式:.zip
开发语言:Java
更新时间:2021-03-09
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
Android 5.0 屏幕录制
从 Android 4.4 开始支持手机端本地录屏,但首先需要获取 root 权限才行,Android 5.0 引入 MediaProject, 可以不用 root 就可以录屏,但需要弹权限获取窗口,需要用户允许才行,这里主要介绍 Android 5.0 利用 MediaProject 在非 root 情况下实现屏幕录制。
基本原理
在 Android 5.0,Google 终于开放了视频录制的接口,其实严格来说,是屏幕采集的接口,也就是 MediaProjection 和 MediaProjectionManager。
public class MainActivity extends AppCompatActivity { private static final int RECORDER_CODE = 0; private static final String TAG = "TAG"; int width; int height; int dpi; MediaProjectionManager projectionManager; MediaProjection mediaProjection; MediaCodec mediaCodec; MediaMuxer mediaMuxer; Surface surface; VirtualDisplay virtualDisplay; private MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); private int videoTrackIndex = -1; String filePath; private AtomicBoolean mQuit = new AtomicBoolean(false); private boolean muxerStarted = false; @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DisplayMetrics metric = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metric); width = 720; height = 1280; dpi = 1; File file = null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { file = new File(this.getDataDir().getPath(), "record-" width "x" height "-" System.currentTimeMillis() ".avc"); } filePath = file.getAbsolutePath(); Log.e(TAG, "onCreate: " filePath ); mMP4Path =filePath; projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { mediaProjection = projectionManager.getMediaProjection(resultCode,data); new Thread() { @Override public void run() { try { try { prepareEncoder(); mediaMuxer = new MediaMuxer(filePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); } catch (IOException e) { throw new RuntimeException(e); } virtualDisplay = mediaProjection.createVirtualDisplay(TAG "-display", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC, surface, null, null); recordVirtualDisplay(); } finally { release(); } } }.start(); Toast.makeText(this, "Recorder is running...", Toast.LENGTH_SHORT).show(); // moveTaskToBack(true); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private void recordVirtualDisplay() { while (!mQuit.get()) { int index = mediaCodec.dequeueOutputBuffer(bufferInfo, 10000); if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { resetOutputFormat(); } else if (index >= 0) { encodeToVideoTrack(index); mediaCodec.releaseOutputBuffer(index, false); } } } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private void encodeToVideoTrack(int index) { ByteBuffer encodedData = mediaCodec.getOutputBuffer(index); if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { bufferInfo.size = 0; } if (bufferInfo.size == 0) { encodedData = null; } if (encodedData != null) { encodedData.position(bufferInfo.offset); encodedData.limit(bufferInfo.offset bufferInfo.size); mediaMuxer.writeSampleData(videoTrackIndex, encodedData, bufferInfo); } } @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) private void resetOutputFormat() { MediaFormat newFormat = mediaCodec.getOutputFormat(); videoTrackIndex = mediaMuxer.addTrack(newFormat); mediaMuxer.start(); muxerStarted = true; } @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) private void prepareEncoder() throws IOException { MediaFormat format = MediaFormat.createVideoFormat("video/avc", width, height); format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); format.setInteger(MediaFormat.KEY_BIT_RATE, 6000000); format.setInteger(MediaFormat.KEY_FRAME_RATE, 30); format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10); mediaCodec = MediaCodec.createEncoderByType("video/avc"); mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); surface = mediaCodec.createInputSurface(); mediaCodec.start(); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void StartRecorder(View view) { startActivityForResult(projectionManager.createScreenCaptureIntent(),RECORDER_CODE); } public void StopRecorder(View view) { mQuit.set(true); Toast.makeText(this, "Recorder stop", Toast.LENGTH_SHORT).show(); } @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) private void release() { if (mediaCodec != null) { mediaCodec.stop(); mediaCodec.release(); mediaCodec = null; } if (virtualDisplay != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { virtualDisplay.release(); } } if (mediaProjection != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mediaProjection.stop(); } } if (mediaMuxer != null) { mediaMuxer.release(); mediaMuxer = null; } } private static String mMP4Path; VideoView mVideoView; MediaController mMediaController;