日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

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

發布時間:2024/3/24 Android 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android实现录屏直播(二)需求才是硬道理之产品功能调研 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

請尊重分享成果,轉載請注明出處,本文來自Coder包子哥,原文鏈接:http://blog.csdn.net/zxccxzzxz/article/details/54254244

Android實現錄屏直播(一)ScreenRecorder的簡單分析

Android實現錄屏直播(二)需求才是硬道理之產品功能調研

Android實現錄屏直播(三)MediaProjection + VirtualDisplay + librtmp + MediaCodec實現視頻編碼并推流到rtmp服務器

前面的Android實現錄屏直播(一)ScreenRecorder的簡單分析一文中我們對 ScreenRecorder 這個開源 Demo 中的實現機制大概有了了解,但在繼續寫這個系列文章的時候發現每一個細節都太緊密了,稍微不注意就會深入每個知識點的細節導致文章又臭又長還表述不清晰,于是我決定把這7天實現該功能的整個流程重新梳理一遍,按照我開發和研究學習的步驟來寫,大致過程如下:

  • 產品功能調研
  • Bilibili 的反編譯及 UI 的編寫
  • ScreenRecorder 等 Demo 的代碼分析
  • 對 H264 結構、FLV 格式封裝的研究學習
  • sps pps avcc 關鍵幀等視頻封裝原理的學習與分析
  • MediaProjection 實現錄屏中 MediaCodec 的詳細用法
  • 編碼后的幀進行推流
  • 產品功能調研

    我們作為技術開發人員,任務下發的時候首先要與產品經理進行需求的深入了解,只有了解對方想要的是什么后我們功能實現才能達到他們最大的期望值。當然一旦確定需求后把菜刀亮出來,然后就輕松愉快的寫代碼吧��。嗯,本次任務就是盡可能的還原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倉庫中,有需要的朋友可以去 clone 或 fork,如對您有幫助還請給個Star,十分感謝~

    參考文檔

    • Android桌面懸浮窗效果實現,仿360手機衛士懸浮窗效果
    • Android Notification
    • Android面試一天一題(1Day)IntentService作用是什么
    • Android–通知之Notification

    總結

    以上是生活随笔為你收集整理的Android实现录屏直播(二)需求才是硬道理之产品功能调研的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。