基于智慧教室|无纸化会议的新选择:RTMP解决方案
基于智慧教室或是會議的技術方案,一般主要是涉及到屏幕采集和推送,整體技術方案這塊,一般建議走RTMP,說到這里,好人開發者提到,市面上也有RTSP的技術方案,甚至RTSP組播方案,這塊,大牛直播SDK Github 也做過相關對比,總的來說60人智慧教室或類似同屏場景下,最可靠的還是RTMP的解決方案(不贅述,具體可自行測試對比)。
有人說,RTMP延遲大,這種說法,相對片面,好多是由于推拉流模塊本身問題導致(如果服務器系NIGNX或SRS,基本可排除服務器轉發導致的大時延,不要再賴服務器了),從我們官方和實際場景來看,RTMP整體技術方案,延遲可做到1秒內,毫秒級。
整體設計方案如下
注意事項
1. 組網:無線組網,需要好的AP模塊才能撐得住大的并發流量,推送端到AP,最好是有線網鏈接;
2. 服務器部署:如果Windows平臺,可以考慮NGINX,如果是Linux,可以考慮SRS或NGINX,服務器可以和Windows平臺的教師機部署在一臺機器;
3. 教師端:如教師有移動的PAD,可以直接推到RTMP服務器,然后共享出去;
4. 學生端:直接拉取RTMP流播放即可;
5. 教師和學生互動:學生端如需作為示范案例,屏幕數據共享給其他同學,只需請求同屏,數據反推到RTMP服務器,其他學生查看即可。
6. 擴展監控:如果需要更進一步的技術方案,如教師端想監控學生端的屏幕情況,可以有兩種方案,如學生端直接推RTMP過來,或者,學生端啟動內置RTSP服務,教師端想看的時候,隨時看即可(亦可輪詢播放)。
以下分平臺介紹相關配置選項
Windows平臺RTMP推送端
對應DEMO:SmartPublisherDemo.exe
1. 如果采集屏幕,只要采集部分區域的話,可以點擊“選取屏幕區域”按鈕,選擇需要采集的區域,采集推送過程中,可以移動采集區域;
2. 如果是高分屏(如有些采集設備,是4K屏,原始分辨率過高),用戶又不想推這么高的分辨率的話,可以選中“縮放屏幕大小”,并指定縮放比例,可以先縮放,后編碼推送數據;
3. 設置采集幀率:如果是PPT/Word文檔類,一般8-12幀足矣,如果是電影之類,可以設置到20-30幀不等,關鍵幀間隔一般設置到幀率的2-4倍,屏幕推送的話,建議平均碼率模式;
4. 如果需要采集電腦端輸出的聲音,可以選中“采集揚聲器”,如果需要采集外部麥克風的音頻,選擇“采集麥克風”即可,并選擇對應的采集設備;
5. 設置下推送的RTMP URL,然后,點擊“推送”,就可以了;
6. 如果想預覽推送出去的數據,點擊“預覽”即可,想停止預覽的話,點擊“停止預覽”即可。
Android平臺RTMP屏幕推送端
對應工程:SmartServicePublisherV2
需要注意的事項:
1. Android 8.0及以上版本設備,需要加入省電優化白名單,6.0以上版本,需要動態獲取audio權限,具體代碼如下:
//加入省電優化白名單,以免8.0及以上版本設備后臺運行超過一分鐘被自動停掉//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)if (Build.VERSION.SDK_INT >=26){if(!isIgnoringBatteryOptimizations()){gotoSettingIgnoringBatteryOptimizations();}}//6.0及以上版本,動態獲取Audio權限if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){RequestAudioPermission();}//拉起請求加入省電白名單彈窗private void gotoSettingIgnoringBatteryOptimizations() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {try {Intent intent = new Intent();String packageName = getPackageName();intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);intent.setData(Uri.parse("package:" + packageName));startActivityForResult(intent, REQUEST_IGNORE_BATTERY_CODE);} catch (Exception e) {e.printStackTrace();}}}//動態獲取Audio權限private void RequestAudioPermission(){if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this.getApplicationContext(), android.Manifest.permission.RECORD_AUDIO)){}else {//提示用戶開戶權限音頻String[] perms = {"android.permission.RECORD_AUDIO"};ActivityCompat.requestPermissions(this, perms, RESULT_CODE_STARTAUDIO);}}2. 持續的補幀策略,防止屏幕不動,沒數據下去;
3.? 如果需要傳部分區域下去,可以用?SmartPublisherOnCaptureVideoClipedRGBAData() 接口;
4. 橫豎屏切換,上層無需過問,底層會自動切。
iOS平臺RTMP屏幕推送端
對應工程:?SmartServiceCameraPublisherV2
注意事項:ReplayKit2 的直播擴展目前是有50M的內存使用限制,超過此限制系統會直接殺死擴展進程,因此 ReplayKit2 上建議推流分辨率和幀率、碼率不要太高。
以下是核心processSampleBuffer() 處理,iOS 11.0以上 加入了橫豎屏自動切換適配:
- (void)processSampleBuffer:(CMSampleBufferRef)sampleBufferwithType:(RPSampleBufferType)sampleBufferType {CGFloat cur_memory = [self GetCurUsedMemoryInMB];if( cur_memory > 20.0f){//NSLog(@"processSampleBuffer cur: %.2fM", cur_memory);return;}switch (sampleBufferType) {case RPSampleBufferTypeVideo:{if (!CMSampleBufferIsValid(sampleBuffer))return;NSInteger rotation_degress = 0;//11.1以上支持自動旋轉#ifdef __IPHONE_11_1if (UIDevice.currentDevice.systemVersion.floatValue > 11.1) {CGImagePropertyOrientation orientation = ((__bridge NSNumber*)CMGetAttachment(sampleBuffer, (__bridge CFStringRef)RPVideoSampleOrientationKey , NULL)).unsignedIntValue;//NSLog(@"cur org: %d", orientation);switch (orientation){//豎屏case kCGImagePropertyOrientationUp:{rotation_degress = 0;}break;case kCGImagePropertyOrientationDown:{rotation_degress = 180;break;}case kCGImagePropertyOrientationLeft: {//靜音鍵那邊向上 所需轉90度rotation_degress = 90;}break;case kCGImagePropertyOrientationRight:{//關機鍵那邊向上 所需轉270rotation_degress = 270;}break;default:break;}}#endif//NSLog(@"RPSampleBufferTypeVideo");if(_smart_publisher_sdk){//[_smart_publisher_sdk SmartPublisherPostVideoSampleBuffer:sampleBuffer];[_smart_publisher_sdk SmartPublisherPostVideoSampleBufferV2:sampleBuffer rotateDegress:rotation_degress];}//NSLog(@"video ts:%.2f", CMTimeGetSeconds(CMSampleBufferGetPresentationTimeStamp(sampleBuffer)));}break;case RPSampleBufferTypeAudioApp://NSLog(@"RPSampleBufferTypeAudioApp");if (CMSampleBufferDataIsReady(sampleBuffer) != NO){if(_smart_publisher_sdk){NSInteger type = 2;[_smart_publisher_sdk SmartPublisherPostAudioSampleBuffer:sampleBuffer inputType:type];}}//NSLog(@"App ts:%.2f", CMTimeGetSeconds(CMSampleBufferGetPresentationTimeStamp(sampleBuffer)));break;case RPSampleBufferTypeAudioMic://NSLog(@"RPSampleBufferTypeAudioMic");if(_smart_publisher_sdk){NSInteger type = 1;[_smart_publisher_sdk SmartPublisherPostAudioSampleBuffer:sampleBuffer inputType:type];}//NSLog(@"Mic ts:%.2f", CMTimeGetSeconds(CMSampleBufferGetPresentationTimeStamp(sampleBuffer)));break;default:break;} }?
總結
以上是生活随笔為你收集整理的基于智慧教室|无纸化会议的新选择:RTMP解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【深度学习】用Pytorch给你的母校做
- 下一篇: layer.open 强化1