请尊重分享成果,转载请注明出处,本文来自Coder包子哥,原文链接:http://blog.csdn.net/zxccxzzxz/article/details/54254244

Android实现录屏直播(一)ScreenRecorder的简单分析

Android实现录屏直播(二)需求才是硬道理之产品功能调研

Android实现录屏直播(三)MediaProjection + VirtualDisplay + librtmp + MediaCodec实现视频编码并推流到rtmp服务器

前面的Android实现录屏直播(一)ScreenRecorder的简单分析一文中我们对 ScreenRecorder 这个开源 Demo 中的实现机制大概有了了解,但在继续写这个系列文章的时候发现每一个细节都太紧密了,稍微不注意就会深入每个知识点的细节导致文章又臭又长还表述不清晰,于是我决定把这7天实现该功能的整个流程重新梳理一遍,按照我开发和研究学习的步骤来写,大致过程如下:

  1. 产品功能调研
  2. Bilibili 的反编译及 UI 的编写
  3. ScreenRecorder 等 Demo 的代码分析
  4. 对 H264 结构、FLV 格式封装的研究学习
  5. sps pps avcc 关键帧等视频封装原理的学习与分析
  6. MediaProjection 实现录屏中 MediaCodec 的详细用法
  7. 编码后的帧进行推流

产品功能调研

我们作为技术开发人员,任务下发的时候首先要与产品经理进行需求的深入了解,只有了解对方想要的是什么后我们功能实现才能达到他们最大的期望值。当然一旦确定需求后把菜刀亮出来,然后就轻松愉快的写代码吧��。嗯,本次任务就是尽可能的还原Bilibili的录屏直播功能,汗颜,无需设计,无需讨论,我自己研究吧,反正项目一直都是我一人开发,也习惯了(PS: 尽管是Bilibili的忠实用户,当然不能在工作的时候看番剧啦),废话不多说,瞄准几个功能:

  • 直播悬浮窗
  • 直播提示通知栏
  • 录屏直播的实现机制

直播悬浮窗

说起悬浮窗不得不感谢郭神的博客 Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果,就是懒直接拿来修修改改就行(郭神别打我~),实现效果如图

悬浮窗包含一个自定义的View(继承自FrameLayout)、服务和自定义WindowManager,更多细节请见源码,代码就不贴出来了,太占地方。值得注意的是,这里的悬浮窗我添加了一个弹幕显示的ListView面板用于显示用户的发言。

直播提示通知栏

由于直接录制桌面涉及到用户的个人隐私问题,如果没有一个标识让用户看着那问题就麻烦了(亲测过通过这种录屏方式可以捕获桌面所有的内容,无论是键盘输入状态、摄像头拍照摄像及输入银行卡密码等等),所以Android系统虽然会提示需要进行屏幕录像,但还是有一定的风险!通知栏属于常驻类型,内容如下:

通知栏的实现

先看看下面这个服务类,主要功能就是开启通知并创建悬浮窗两个功能,注意创建悬浮窗时判断当前设备是否为我们的APP授权了悬浮窗权限这个功能我还没有来得及实现,小米、魅族华为等系统需要手动去APP设置中授权,之后有时间再补上。如需此服务与Activity之间有通信机制的话,还需要自定义Binder,在启动服务的Activity中通过bindService()与ServiceConnection来实现数据的传递,这里先挖一个坑,后续我完善功能后再回来填上。

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.os.Binder;
import android.os.Handler;
import android.support.v4.app.NotificationCompat;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;public class ScreenRecordListenerService extends Service {private static final String TAG = "ScreenRecordListenerService, ";private static final int PENDING_REQUEST_CODE = 0x01;private static final int NOTIFICATION_ID = 3;private NotificationManager mNotificationManager;private NotificationCompat.Builder builder;private Handler handler = new Handler();@Overridepublic void onCreate() {super.onCreate();initNotification();}@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// 当前界面是桌面,且没有悬浮窗显示,则创建悬浮窗。if (!MyWindowManager.isWindowShowing()) {handler.post(new Runnable() {@Overridepublic void run() {MyWindowManager.createSmallWindow(getApplicationContext());}});}return super.onStartCommand(intent, flags, startId);}private void initNotification() {builder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher).setContentTitle(getResources().getString(R.string.app_name)).setContentText("您正在录制视频内容哦").setOngoing(true).setDefaults(Notification.DEFAULT_VIBRATE);Intent backIntent = new Intent(this, RecordActivityV2.class);PendingIntent pendingIntent = PendingIntent.getActivity(this, PENDING_REQUEST_CODE, backIntent, PendingIntent.FLAG_UPDATE_CURRENT);builder.setContentIntent(pendingIntent);mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);mNotificationManager.notify(NOTIFICATION_ID, builder.build());}@Overridepublic void onDestroy() {super.onDestroy();if (mNotificationManager != null) {mNotificationManager.cancel(NOTIFICATION_ID);}MyWindowManager.removeSmallWindow(getApplicationContext());}
}

上面的代码我们可以看出服务启动后进行了Notification的初始化,我这里按照Bilibili的样式去实现的。在Activity中当启动直播时,Bilibili是通过moveTaskToBack(true)直接回到桌面的,所以我猜想开启通知栏和悬浮窗服务应该是在Activity生命周期的onStop()启动和onResume()关闭,当然这些都是业务逻辑可自己定义。

@Override
protected void onResume() {super.onResume();if (isRecording) stopScreenRecordService();
}@Override
protected void onStop() {super.onStop();if (isRecording) startScreenRecordService();
}private void startScreenRecordService() {if (mRecorder != null && mRecorder.getStatus()) {Intent runningServiceIT = new Intent(this, ScreenRecordListenerService.class);// bindService(runningServiceIT, connection, BIND_AUTO_CREATE); startService(runningServiceIT);}
}private void stopScreenRecordService() {Intent runningServiceIT = new Intent(this, ScreenRecordListenerService.class);stopService(runningServiceIT);if (mRecorder != null && mRecorder.getStatus()) {Toast.makeText(this, "现在正在进行录屏直播哦", Toast.LENGTH_SHORT).show();}
}

最后别忘了在AndroidManifest.xml中进行Service的注册和对悬浮窗的授权。

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application
    <serviceandroid:name=".service.ScreenRecordListenerService"android:enabled="true"android:exported="false" />
</application>

关于悬浮窗与通知栏差不多就介绍到这里了,更多细节请查看源码,本Demo源码都是基于上篇博客提到的ScreenRecorder实现的。

我们来看看最终效果吧:

录屏直播的实现机制

使用MediaProjection与VirtualDisplay等Android 5.0以上的API实现的,在此就不多说了,请看上篇博客吧。

尾语

果然还是有个提纲要好下笔的多,至少知道写些什么。因为最近文章写的都有点赶,有疑问的朋友还请留言指正!接下来准备写一下MediaProjection 实现录屏中 MediaCodec 的详细用法,至于反编译Bilibili的过程就不写了,反编译为的是参考别人的思路,并不是为了做代码小偷,这点职业操守还是有的,如果说业务上有盗窃之意请出门左转找我们的产品经理,我是无辜的码农[笑]。之后会在别的文章中提及一下我个人使用反编译时的一些心得和小技巧吧。别的主题都还需要花些时间再看看,毕竟都是工作时候囫囵吞枣接触的,理论知识可不能瞎糊弄。

Demo源码

Demo源码都在我的GitHub仓库中,有需要的朋友可以去 clonefork,如对您有帮助还请给个Star,十分感谢~

参考文档

  • Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果
  • Android Notification
  • Android面试一天一题(1Day)IntentService作用是什么
  • Android–通知之Notification

Android实现录屏直播(二)需求才是硬道理之产品功能调研相关推荐

  1. android 录屏自动运行,Android实现录屏直播+远程控制(二)

    前言 前面Android实现录屏直播+远程控制(一)的文章说到Android5.0的录屏直播实现方式,今天来说说实现录屏直播的另外一种方案 1 启动一个后台服务实现录屏 1.服务的创建这边就不在赘述了 ...

  2. android实现录像功能吗,Android实现录屏直播(一)ScreenRecorder的简单分析

    应项目需求瞄准了Bilibili的录屏直播功能,基本就仿着做一个吧.研究后发现Bilibili是使用的MediaProjection 与 VirtualDisplay结合实现的,需要 Android ...

  3. 如何在Android实现录屏直播

    许多开发者在做智慧教室同屏亦或会议同屏时,基于Andriod平台采集屏幕并编码推送,往往遇到各种各样的问题,以下就我们开发过程中的一些技术考量做个分享,权当抛砖引玉: 协议选择.数据来源和处理 1. ...

  4. Android PC投屏简单尝试(录屏直播)2—硬解章(MediaCodec+RMTP)

    代码地址 :https://github.com/deepsadness/MediaProjectionDemo 想法来源 上一边文章的最后说使用录制的Api进行录屏直播.本来这边文章是预计在5月份完 ...

  5. Android之间互相的录屏直播 --点对点传输(tcp长连接发送h264)(一)

    前言 转载请注明出处 ,来自: 暂时两篇: (1) Android之间互相的录屏直播 –点对点传输(tcp长连接发送h264)(一) http://blog.csdn.net/baidu_335462 ...

  6. iOS录屏直播(二)Broadcast Upload Extension和Broadcast Setup UI Extension

    Morris_2019.06.13 上一篇总结了ReplayKit相关的知识点,实现了应用内的录屏功能,同时涉及到了很少一部分Broadcast Upload Extension和Broadcast ...

  7. c语言安卓录屏,手写 Android 录屏直播

    简介 观看手游直播时,我们观众端看到的是选手的屏幕上的内容,这是如何实现的呢?这篇博客将手写一个录屏直播 Demo,实现类似手游直播的效果 获取屏幕数据很简单,Android 系统有提供对应的服务,难 ...

  8. iOS录屏直播(一)初识ReplayKit

    Morris_2019.05.08 本篇主要功能: 认识ReplayKit框架 RPScreenRecorder实现在应用内录屏功能 RPPreviewViewController查看录屏内容 RPB ...

  9. 如何做电脑游戏桌面录屏直播实现手机直接观看

    原创教程 ( 转载请注明出处 ) 2017-6-26,今天来做一下是电脑游戏桌面录屏直播的教程,就是把桌面的游戏直播出去,加上话筒做讲解.最终实现在电脑.手机.微信中都可以观看到游戏的直播和讲解画面. ...

最新文章

  1. winform让子窗体始终居于父窗体的中间
  2. T-SQL查询进阶--深入理解子查询
  3. 简单介绍tomcat中maxThreads,acceptCount,connectionTimeout
  4. 抖音用户规模达5.18亿,数据解读抖音支付背后逻辑?
  5. Google Apps – Framework, Phonesky, GmsCore w/ AOSP Build.
  6. R语言GGPlot2
  7. MyCat介绍与配置(精)
  8. mt4 python神经网络_迈达克软件公司承认Python运算对量化交易的重要性----将Python与Metatrader 5集成一体...
  9. minmaxloc matlab,opencv minmaxloc 最大最小匹配值是什么意思
  10. 二、将mysql用作一个简单的计算器
  11. 新版Edge浏览器如何设置崩溃自动恢复网页
  12. 如何制定一份测试工程师年度计划
  13. php单页菜单,CSS3单页切换导航菜单界面设计的实现详解
  14. 关于0x80070091 目录不是空的
  15. 微信挂机托管服务器nodejs,怎么执行node app.js 脚本
  16. Dual Super-Resolution Learning for Semantic Segmentation解读
  17. Spark history server 启动报错:History server ui acls disabled; users with admin permissions
  18. C语言计算机二级/C语言期末考试 刷题(四)
  19. 现存最古老青海撒拉族手抄本《古兰经》首次公开展览
  20. 微软全球最大人工智能和物联网实验室落户上海张江

热门文章

  1. 关于无线遥控315模块的发射与接收
  2. iOS微信公众平台彻底关闭打赏功能
  3. C++项目实战:基于多态的职工管理系统(源码)
  4. 微信 10 年,张小龙的 7 个逻辑和一个选择
  5. yolov7-pyqt代码教程
  6. 关于在WinForm下对Excel进行操作的总结
  7. [读书笔记]《没人会告诉你的PPT真相》
  8. 心灵鸡汤 - tenth (10th)
  9. 分布式锁-Redisson
  10. Golang实现端口检测