日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

如何在IOS上使用ReplayKit與RTC

瀏覽:22日期:2022-09-16 18:00:55

在日益繁多的直播場景中,如果你也是某位游戲主播的粉絲的話,有一種直播方式是你一定不陌生的,那就是我們今天要聊的屏幕分享。

直播場景下的屏幕分享,不僅要將當前顯示器所展示的畫面分享給遠端,也要將聲音傳輸出去,包括應用的聲音,以及主播的聲音。鑒于這兩點需求,我們可以簡單分析出,進行一次屏幕分享的直播所需要的媒體流如下:

一條顯示器畫面的視頻流 一條應用聲音的音頻流 一條主播聲音的音頻流

ReplayKit 是蘋果提供的用于 iOS 系統進行屏幕錄制的框架。

首先我們來看看蘋果提供的用于屏幕錄制的 ReplayKit 的數據回調接口:

override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {DispatchQueue.main.async { switch sampleBufferType { case .video:AgoraUploader.sendVideoBuffer(sampleBuffer) case .audioApp:AgoraUploader.sendAudioAppBuffer(sampleBuffer) case .audioMic:AgoraUploader.sendAudioMicBuffer(sampleBuffer) @unknown default:break }} }

從枚舉 sampleBufferType 上,我們不難看出,剛好能符合我們上述對媒體流的需求。

視頻格式

guard let videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer) else { return}let type = CVPixelBufferGetPixelFormatType(videoFrame)

type = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange

通過 CVPixelBufferGetPixelFormatType,我們可以獲取到每幀的視頻格式為 yuv420

幀率

通過打印接口的回調次數,可以知道每秒能夠獲取的視頻幀為30次,也就是幀率為 30。

格式與幀率都能符合 Agora RTC 所能接收的范圍,所以通過 Agora RTC 的 pushExternalVideoFrame 就可以將視頻分享到遠端了。

agoraKit.pushExternalVideoFrame(frame)插入一個小知識

顯示器所顯示的幀來自于一個幀緩存區,一般常見的為雙緩存或三緩存。當屏幕顯示完一幀后,發出一個垂直同步信號(V-Sync),告訴幀緩存區切換到下一幀的緩存上,然后顯示器開始讀取新的一幀數據做顯示。

這個幀緩存區是系統級別的,一般的開發者是無法讀取跟寫入的。但是如果是蘋果自身提供的錄制框架 ReplayKit 能夠直接讀取到已經渲染好且將用于顯示器的幀,且這一過程不會影響渲染流程而造成掉幀,那就能減少一次用于提供給 ReplayKit 回調數據的渲染過程。

音頻

ReplayKit 能提供的音頻有兩種,分為麥克風錄制進來的音頻流,與當前響應的應用播放的音頻流。(下文將前者稱為 AudioMic,后者為 AudioApp)

可以通過下面的兩行代碼,來獲取音頻格式

CMAudioFormatDescriptionRef format = CMSampleBufferGetFormatDescription(sampleBuffer);const AudioStreamBasicDescription *description = CMAudioFormatDescriptionGetStreamBasicDescription(format);AudioApp

AudioApp 會在不同的機型下有不一樣的聲道數。例如在 iPad 或 iPhone7 以下機型中,不具備雙聲道播放的設備,這時候 AudioApp 的數據就是單聲道,反之則是雙聲道。

采樣率在部分試過的機型里,都是 44100,但不排除在未測試過的機型會是其他的采樣率。

AudioMic

AudioMic 在測試過的機型里,采樣率為 32000,聲道數為單聲道。

音頻前處理

如果我們將 AudioApp 與 AudioMic 作為兩條音頻流去發送,那么流量肯定是大于一條音頻流的。我們為了節省一條音頻流的流量,就需要將這兩條音頻流做混音(融合)。

但是通過上述,我們不難看出,兩條音頻流的格式是不一樣的,而且不能保證隨著機型的不同,是不是會出現其他的格式。在測試的過程中還發現 OS 版本的不同,每次回調給到的音頻數據長度也會出現變化。那么我們在對兩條音頻流做混音前,就需要進行格式統一,來應對 ReplayKit 給出的各種格式。所以我們采取了以下幾個重要的步驟:

if (channels == 1) { int16_t* intData = (int16_t*)dataPointer; int16_t newBuffer[totalSamples * 2];for (int i = 0; i < totalSamples; i++) {newBuffer[2 * i] = intData[i];newBuffer[2 * i + 1] = intData[i]; } totalSamples *= 2; memcpy(dataPointer, newBuffer, sizeof(int16_t) * totalSamples); totalBytes *= 2; channels = 2;}

無論是 AudioMic 還是 AudioApp,只要進來的流為單聲道,我們都將它轉化為雙聲道;

if (sampleRate != resampleRate) { int inDataSamplesPer10ms = sampleRate / 100; int outDataSamplesPer10ms = (int)resampleRate / 100; int16_t* intData = (int16_t*)dataPointer; switch (type) {case AudioTypeApp: totalSamples = resampleApp(intData, dataPointerSize, totalSamples, inDataSamplesPer10ms, outDataSamplesPer10ms, channels, sampleRate, (int)resampleRate); break;case AudioTypeMic: totalSamples = resampleMic(intData, dataPointerSize, totalSamples, inDataSamplesPer10ms, outDataSamplesPer10ms, channels, sampleRate, (int)resampleRate); break; } totalBytes = totalSamples * sizeof(int16_t);}

無論是 AudioMic 還是 AudioApp,只要進來的流采樣率不為 48000,我們將它們重采樣為 48000;

memcpy(appAudio + appAudioIndex, dataPointer, totalBytes);appAudioIndex += totalSamples;

memcpy(micAudio + micAudioIndex, dataPointer, totalBytes);micAudioIndex += totalSamples;

通過第一步與第二步,我們保證了兩條音頻流都為同樣的音頻格式。但是由于 ReplayKit 是一次回調給到一種數據的,所以在混音前我們還得用兩個緩存區來存儲這兩條流數據;

int64_t mixIndex = appAudioIndex > micAudioIndex ? micAudioIndex : appAudioIndex;int16_t pushBuffer[appAudioIndex];memcpy(pushBuffer, appAudio, appAudioIndex * sizeof(int16_t));for (int i = 0; i < mixIndex; i ++) { pushBuffer[i] = (appAudio[i] + micAudio[i]) / 2;}

ReplayKit 有選項是否開啟麥克風錄制,所以在關閉麥克風錄制的時候,我們就只有一條 AudioApp 音頻流。所以我們以這條流為主,去讀取 AudioMic 緩存區的數據長度,然后對比兩個緩存區的數據長度,以最小的數據長度為我們的混音長度。將混音長度的兩個緩存區里的數據做融合,得到混音后的數據,寫入一個新的混音緩存區(或者直接寫入 AudioApp 緩存區);

[AgoraAudioProcessing pushAudioFrame:(*unsigned* *char* *)pushBuffer withFrameSize:appAudioIndex * *sizeof*(int16_t)];

最后我們再將這段混音后的數據拷貝進 Agora RTC 的 C++ 錄制回調接口里,這時候就可以把麥克風錄制的聲音與應用播放的聲音傳輸到遠端了。

通過對音視頻流的處理,結合 Agora RTC SDK,我們就完成了一個屏幕分享直播場景的實現了。

以上就是如何在IOS上使用ReplayKit與RTC的詳細內容,更多關于IOS上使用ReplayKit與RTC的資料請關注好吧啦網其它相關文章!

標簽: IOS
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久一级电影| 欧美日韩国产精品一区二区亚洲| 黄色日韩精品| 成人精品中文字幕| 美腿丝袜亚洲一区| 国产乱码精品一区二区亚洲| 青草av.久久免费一区| 一区二区电影在线观看| 久久午夜影视| 久久亚洲一区| 亚洲综合图色| 四虎精品永久免费| 综合一区在线| 色综合视频一区二区三区日韩| 日av在线不卡| 婷婷精品在线观看| 日本v片在线高清不卡在线观看| 模特精品在线| 亚洲一区av| 欧美亚洲网站| 日韩精品国产欧美| 久久激五月天综合精品| 国产麻豆精品| 国产a久久精品一区二区三区| 日韩深夜视频| 蜜臀久久99精品久久一区二区| 黄色不卡一区| 日韩影院免费视频| 日本三级亚洲精品| 精品视频一区二区三区在线观看| 国产精品国产一区| 亚洲性色视频| 亚洲精品高潮| 国产精品久久久久久久免费软件| 成人一区而且| 精精国产xxxx视频在线播放| 黄色日韩在线| 欧美午夜网站| 久久久久久一区二区| 久久久久国产| 一区二区三区四区精品视频| 国产精品啊啊啊| 久久精品国语| 日韩激情网站| 免费一二一二在线视频| 亚洲欧美视频| 国产精品一卡| 精品丝袜在线| 亚洲精选久久| 成人国产精品一区二区免费麻豆| 免费一二一二在线视频| 在线免费观看亚洲| 久久精品亚洲| 亚洲激情av| 国产毛片精品久久| 国产一区视频在线观看免费| 日日摸夜夜添夜夜添国产精品| 麻豆精品少妇| 在线视频免费在线观看一区二区| 欧美一级一区| 亚洲一区资源| 综合一区av| jizzjizz中国精品麻豆| 免费精品视频| 高清在线一区| 欧美日韩日本国产亚洲在线 | 99视频精品全国免费| 视频精品一区| 女生影院久久| 日韩精品国产欧美| 国产一区清纯| 狠狠久久伊人中文字幕| 亚洲欧美高清| 国产夫妻在线| 日韩在线视频一区二区三区| 久久久久美女| 欧美激情综合| 免费久久99精品国产自在现线| 精品视频黄色| 亚洲精品激情| 国产精品99一区二区| 国产福利资源一区| 国产午夜久久| 蜜臀国产一区| 欧美片网站免费| 亚洲大全视频| 四虎国产精品免费观看| 91麻豆精品| 视频一区视频二区在线观看| 夜鲁夜鲁夜鲁视频在线播放| 国产精品亚洲一区二区在线观看| 美女尤物久久精品| 久久国产中文字幕| 老司机精品在线| 91精品国产经典在线观看| 亚洲综合丁香| 国产精品av久久久久久麻豆网| 国产suv精品一区二区四区视频 | 午夜久久久久| 91欧美在线| 国产精品久久久久久av公交车| 视频在线观看一区| 国户精品久久久久久久久久久不卡| 国产精品magnet| 四虎精品永久免费| 国产农村妇女精品一区二区| 欧美日中文字幕| 成人午夜亚洲| 精品中文在线| 国产精品毛片aⅴ一区二区三区| 亚洲一二av| 日韩专区一卡二卡| 亚洲一卡久久| 亚洲欧美日韩视频二区| 黄色亚洲精品| 美女毛片一区二区三区四区 | 好看的av在线不卡观看| 日韩国产一区二区三区| 久久97视频| 国产精品115| 国产精品99久久免费| 国产欧美午夜| 国产精品美女午夜爽爽| 国产日韩一区二区三免费高清| 五月国产精品| 日韩专区视频网站| 日韩在线观看一区二区三区| 蜜臀av一区二区三区| 视频一区中文字幕国产| 久久国产精品亚洲77777| 婷婷精品进入| 婷婷激情综合| 1000部精品久久久久久久久| 亚洲91视频| 色爱av综合网| 99精品在线观看| 亚洲欧美伊人| 欧美一区=区| 亚州国产精品| 国产精品玖玖玖在线资源| 免费在线播放第一区高清av| 久久天堂影院| 日韩毛片视频| 亚洲高清av| 视频一区二区欧美| 日本aⅴ亚洲精品中文乱码| 日韩精品1区2区3区| 欧美亚洲色图校园春色| 麻豆成人在线观看| 日本美女一区| 1000部精品久久久久久久久| 国产视频一区三区| 日韩在线视频一区二区三区| 国产欧美三级| 中文字幕人成乱码在线观看| 激情久久五月| 久久国产高清| 国产精品久久久久久久久久久久久久久 | 国产精品hd| 国产suv精品一区| 亚洲一级黄色| 亚洲人成亚洲精品| 国产精久久一区二区| 日本在线啊啊| 久久国产88| 老司机免费视频一区二区三区| 久久夜夜操妹子| 在线一区免费观看| 亚洲午夜久久| 另类欧美日韩国产在线| 久久久精品网| 免费看黄色91| 国产精久久久| 欧美不卡高清| 色综合视频一区二区三区日韩| 久久久久久久久成人| 久久黄色影院| 日韩欧美中文字幕在线视频| 麻豆国产精品视频| 91久久视频| 日本不卡视频在线观看| 精品视频一区二区三区四区五区| 999久久久国产精品| 蜜桃av一区二区| 久久一区精品| 亚洲综合日韩| 韩日一区二区| 一区二区三区四区精品视频| 国产精品久久久久久久免费观看| 羞羞答答国产精品www一本| 美女久久久久久| 国产精品试看| 精品久久97| 亚洲小说春色综合另类电影| 精品国产第一福利网站| 亚洲精品成人一区| 日本在线精品| 91av一区| 亚洲一级黄色| 麻豆成人在线观看|