前言
Android提供了来实现录屏,通过可以获取当前屏幕的视频流,而视频流需要通过编解码来压缩进行传输,通过可实现视频的编码和解码。视频流的推送和接收可通过Socket或WebSocket来实现,服务端推送编码的视频流,客户端接收视频流并进行解码,然后渲染在SurfaceView上即可显示服务端的画面。
媒体投影的核心是虚拟屏幕,您可以通过对 实例调用 来创建虚拟屏幕(VirtualDisplay):
Android的媒体投影MediaProjection介绍:媒体投影
投屏服务端的实现
服务端主入口负责请求录屏和启动录屏服务,服务端主入口的实现如下:
Android8.0后录屏需要开启前台服务通知,录屏服务开启后同时启动WebSocketServer服务端,前台服务代码如下:
package com.example.screenprojection;import android.app.Notification;import android.app.NotificationChannel;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.Intent;import android.graphics.BitmapFactory;import android.media.projection.MediaProjection;import android.media.projection.MediaProjectionManager;import android.os.Build;import android.os.IBinder;public class ScreenService extends Service { private MediaProjectionManager mMediaProjectionManager; private SocketManager mSocketManager; @Override public void onCreate() { super.onCreate(); mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE); createNotificationChannel(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { int resultCode = intent.getIntExtra("code", -1); Intent resultData = intent.getParcelableExtra("data"); startProject(resultCode, resultData); return super.onStartCommand(intent, flags, startId); } // 录屏开始后进行编码推流 private void startProject(int resultCode, Intent data) { MediaProjection mediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data); if (mediaProjection == null) { return; } // 初始化服务器端 mSocketManager = new SocketManager(); mSocketManager.start(mediaProjection); } private void createNotificationChannel() { Notification.Builder builder = new Notification.Builder(this.getApplicationContext()); Intent nfIntent = new Intent(this, MainActivity.class); builder.setContentIntent(PendingIntent.getActivity(this, 0, nfIntent, 0)).setLargeIcon( BitmapFactory.decodeResource( this.getResources(), R.mipmap.ic_launcher)) // 设置下拉列表中的图标(大图标).setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标.setContentText("is running......") // 设置上下文内容.setWhen(System.currentTimeMillis()); // 设置该通知发生的时间 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { builder.setChannelId("notification_id"); // 前台服务notification适配 NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationChannel channel = new NotificationChannel( "notification_id", "notification_name", NotificationManager.IMPORTANCE_LOW); notificationManager.createNotificationChannel(channel); } Notification notification = builder.build(); notification.defaults = Notification.DEFAULT_SOUND; // 设置为默认通知音 startForeground(110, notification); } @Override public IBinder onBind声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!