<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

    我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
    posts - 494, comments - 13, trackbacks - 0, articles - 1

    本文由微信客戶端團隊rhythm分享,原題“視頻號直播:如何進一步降低功耗占用?”,本文有修訂和改動。

    1、引言

    功耗優(yōu)化一直是 app 性能優(yōu)化中讓人頭疼的問題,尤其是在直播這種用戶觀看時長特別久的場景。怎樣能在不影響主體驗的前提下,進一步優(yōu)化微信iOS端視頻號直播的功耗占用,本文給出了一個不太一樣的答案。

     
     
    技術(shù)交流:

    (本文已同步發(fā)布于:http://www.52im.net/thread-4507-1-1.html

    2、問題背景

    問題的起因是我們測試統(tǒng)計發(fā)現(xiàn)帶有點贊的直播會比無點贊動畫的直播 GPU 占用要高將近一倍,同時 FPS 差異也很大。

    高刷屏下,PerfDog 測試顯示,有點贊情況下的大部分視頻號直播居然是以60fps在跑,這導致了極高的GPU占用。

    但我們根本沒有60fps 這么高的直播流,且絕大部分直播流都只有30fps 而已,少部分也就最高60fps,怎么到了設備上就達到了60fps?

    而且這還是我們開啟了強制低幀率UIViewAnimationOptionPreferredFramesPerSecond30后的效果,沒開之前直接奔120fps 去了。

    如下圖所示 PerfDog 數(shù)據(jù)顯示在 13 pro max上直播點贊期間 FPS 直奔120:

    正常情況下,視頻號直播里大部分主播開播流基本都是30fps 以內(nèi),也就是正常情況下我們只需要維持30fps 渲染,就能保持好流程的用戶體驗。

    那為什么這里降幀后依舊會出現(xiàn)60fps 呢?

    經(jīng)過一系列排查我們發(fā)現(xiàn)這是由于直播的點贊動畫導致的高幀率,如果去掉動畫后 FPS 就會回到正常情況下了,且 GPU 占用也有了明顯下降。

    這到底是怎么回事?我們是否可以降動畫的幀率降低到某個值來去優(yōu)化我們整體的 GPU 占用呢?

    3、知識儲備1:iOS中的動畫分類

    在iOS中,大部分動畫的本質(zhì)就是根據(jù)輸入的時間戳,返回對應屬性的動畫參數(shù),從而移動圖像,達到運動的效果。根據(jù)動畫 api 實現(xiàn)方式的特點我們可以把動畫 api 劃分為如下幾類。

    3.1UIView block animation

    基于 「+[UIView animateWithDuration:delay : options:animations:completion:]」 動畫api驅(qū)動的動畫,特點是所有動畫都在 animations block 里同步觸發(fā),可以方便的設置任何屬性動畫。

    [UIView animateWithDuration:duration

                                 delay:0

                               options:option

                            animations:^{

                                view.top -= offsetY;

                                view.left -= offsetX;

                            }

                            completion:completion];

    3.2CAAnimation

    基于 「CAAnimation api」 直接觸發(fā)提交的動畫,例如:

    CABasicAnimation *ani_position = [CABasicAnimation animationWithKeyPath:@"position"];

    ani_position.fromValue = @(val.position.from);

    ani_position.toValue = @(val.position.to);

    [view.layer addAnimation:group forKey:key];

    3.3Timer

    基于 「NSTimer/GCD」 觸發(fā)的動畫,例如定時去修改某個 imageView.image,使得它能定期變換的效果?;?「CADisplayLink」 觸發(fā)的動畫,和基于 NSTimer 觸發(fā)類似,只不過這個 timer 源是和渲染保持一致的,能夠做到更流暢更貼合。

    比如我們要實現(xiàn)自定義的 UIScrollView 動畫,就可以基于 CADisplayLink 來做。

    3.4UIViewPropertyAnimator

    「UIViewPropertyAnimator」是iOS10開始蘋果推動的新的動畫api,相比 UIView block animation 可以更靈活的控制動畫的過程。

    [UIViewPropertyAnimator runningPropertyAnimatorWithDuration:duration

                                         delay:0

                                       options:option

                                    animations:^{

                                        view.top -= offsetY;

                                        view.left -= offsetX;

                                    }

                                    completion:completion];

    4、知識儲備2:iOS中的動畫渲染

    iOS中的動畫或者 UIView 的修改到底是怎么被渲染到屏幕上去的?

    4.1Core Animation Pipeline

    iOS 的 UI 更新和動畫操作都離不開 Core Animation 和 UIKit,他們的底層都是 QuartzCore,所有的 UI 刷新和動畫提交都會打包成對應的 CA::Transaction 和 CAAnimation 對象并提交給 Render Server 去處理。

    App 本身并不負責渲染,渲染是由獨立的進程 Render Server 來負責的,Render Server 最終調(diào)用 -[AGXG14FamilyRenderContext drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:] 等 GPU 接口來完成 GPU 任務的提交,最終觸發(fā)屏幕更新操作。

    整體過程大概如下:

    • 1)App 處理事件,例如 touch 事件或者 displaylink timer 事件;
    • 2)App 完成視圖的 layout、圖像 decode 等操作,并觸發(fā) CA::Transaction 提交;
    • 3)Render Server 接收 App 提交的 Transction 和圖片數(shù)據(jù),Render Server 可直接跨進程訪問 App 進程的位圖內(nèi)存資源,并最終觸發(fā) GPU 調(diào)用;
    • 4)GPU 最終完成了圖像的渲染并顯示到屏幕 Display。

    4.2Render Server

    如下圖所示,最終的上屏任務提交操作是由 Render Server 也即 backboardd 進程來最終觸發(fā)的。

    在 iOS 中 Render Server 通常指的是 backboardd 進程,backboardd 進程是一個與 SpringBoard 守護進程一起運行的守護進程。

    它在 iOS 6 中引入,旨在減輕 Springboard 的一些職責,主要是事件處理的職責。它主要負責把 touch 事件分發(fā)到 app 進程以及處理 app 進程觸發(fā)的動畫和UI更新操作。

    如上圖所示,time profiler 里我們能清晰看到 backboardd 進程在處理來自 app 進程的圖像提交操作。

    微信直播之前就遇到過好幾次 Render Server 命中了 gpu io fence 導致系統(tǒng)全局卡死的問題。

    如下圖 ips 文件日志所示:

    4.3Render Loop

    Render Loop 是包括了從 app 到 Render Server 再最終到屏幕的一系列任務觸發(fā),刷新,更新與提交,直到上屏的一系列過程,是對渲染管道的進一步封裝,類似于一套 runloop 循環(huán)機制,能隨時的處理輸入和輸出。

    4.4動畫渲染

    當我們調(diào)用-[UIView animateWithDuration:animations:] api觸發(fā)動畫后,整體動畫渲染過程如下圖3步所示。

    4.5幀率

    幀率即 FPS(frames per second),每秒渲染了多少幀,正常情況下只要我們定期提交一次 opengl 上屏 [curContext presentRenderbuffer:GL_RENDERBUFFER] 就會觸發(fā)一幀的上屏操作,這就回導致 FPS 發(fā)生變化,也最終影響了 app 的性能占用。

    FPS 越高對于游戲等高清視頻效果就更細膩更好,但是并不是所有情況都需要高 FPS,部分情況下高 FPS 反而導致了無用的功耗但并沒有帶來更好的體驗。

    4.6屏幕刷新率

    對于 iOS15/iPhone 13以前的設備,屏幕是固定的刷新率,在這之后 iPhone 13和 iPad Pro 后引入了高刷屏,并且支持了動態(tài)刷新率。

    對于直播場景 FPS 有3個:

    • 1)視頻流 FPS;
    • 2)Render Server FPS;
    • 3)屏幕 FPS。

    對于非可變刷新率的屏幕,我們可以盡可能減少 GPU 的幀率(即 Render Server 提交的 FPS)來達到降低 GPU 功耗的目的,對于可變刷新率的屏幕,那只要減少了 GPU 幀率就自然而然也減少了屏幕的刷新率,使得屏幕和 GPU 功耗都下降了。

    在我們遇到的問題中,我們的視頻流 FPS 是25,那么我們預期的最終 GPU FPS 和屏幕 FPS 理應同理也是接近25才是,而這里卻達到了60fps,說明了有重復的內(nèi)容幀一直被 Render Server 重復的復制并提交給 GPU,導致了畫質(zhì)細節(jié)沒有增加,但頻繁的拷貝渲染造成了更高的 GPU 占用。這就是我們的問題所在。

    5、知識儲備3:iOS中的動畫降幀

    5.1概述

    結(jié)合上文,我們要解決直播幀率異常升高的問題,就需要解決點贊動畫的高幀率問題。

    很幸運,蘋果在 iOS15提供了一個 CAAnimation 的 api,即-[CAAnimation preferredFrameRateRange],它接受3個參數(shù)分別指定minimum 幀率,maximum 幀率,以及 preferred 幀率,基于這個api我們可以對于 CAAnimation 動畫設置幀率。

    蘋果的建議是把動畫分為了如下幾檔:

    5.2CAAnimation 降幀原理

    iOS15開始蘋果引入了 CAFrameRateRange 相關(guān) api 來供 app 去設置 CADisplayLink 和 CAAnimation 的 preferredFrameRateRange,以方便調(diào)節(jié)幀率,達到在高刷機上能進一步降低功耗的目的。

    那它又是如何工作的呢?

    首先需要明確 iOS15后 CAAnimation 和 CADisplayLink 的幀率控制底層都是一致的,也就是都是 CA:: Display: : DisplayLinkItem 來驅(qū)動觸發(fā)的。而動畫的本質(zhì)就是根據(jù)時間的輸入來得到對應的動畫 fraction 并觸發(fā)對應進度的動畫修改,再提交上屏完成修改。

    具體而言,我們以 UIScrollView的 setContentOffset:animated 動畫為例。

    5.3setContentOffset:animated 動畫機制

    當我們觸發(fā)[scrollView setContentOffset:CGPointMake(120,0) animated:YES]后,會觸發(fā)創(chuàng)建一個 UIScrollViewAnimation 的實例對象(UIAnimation的子類),接下來會調(diào)用 UIUpdateSequenceInsertItem 將這個動畫實例注冊到當前的 UIUpdateCycle 循環(huán)中。

    UIUpdateCycle 負責根據(jù)設備的 CADisplay 屏幕刷新率和設置動態(tài)效果里設置的是否限制幀速率來抉擇出到底是以120hz還是60hz來驅(qū)動 UIUpdateCycle 循環(huán)的觸發(fā),當以120hz觸發(fā)動畫循環(huán)時,接著會在每8ms間觸發(fā)一次_UIUpdateSequenceRun,來執(zhí)行 UIScrollViewAnimation 的動畫 progress 計算操作。

    如圖:

    每次觸發(fā)觸發(fā) _UIUpdateSequenceRun 時,會向 UIScrollViewAnimation 請求[UIAnimation fractionForTime:]來返回對應時間戳的 contentOffset 和 progress,然后觸發(fā)修改 contentOffset,最終接近目標 contentOffset 后就完成了完整的動畫。

    5.4CAFrameRateRange

    當我們設置 CAAnimation 的 preferredFrameRateRange 后,QuartzCore 會將 CAFrameRateRange 轉(zhuǎn)為CAFrameIntervalRange 結(jié)構(gòu),并最終嘗試觸發(fā) Render Server 在指定幀間隔內(nèi)渲染每一幀動畫。

    如下圖:

    5.5幀率變化探索

    所有的幀提交操作最終都是在 Render Server 觸發(fā)的,也就是只有從 Render Server 統(tǒng)計FPS才是最終的實際 FPS,那我們要怎么統(tǒng)計呢?

    QuartzCore 提供了一個系統(tǒng)級的面板工具,它可以很方便的顯示當前的 QuartzCore 渲染信息,包括fps,frame duration等一應俱全。

    我們可以在越獄后給 app 自簽名 com.apple.QuartzCore.debug 這個 entitlement 后,再調(diào)用如下代碼所示的私有 api 即可全局打開這個面板,可以方便的在手機端查看 Render Server 上的實際 FPS。

    extern"C"{

    intCARenderServerGetDebugOption(mach_port_t port, intkey);

    intCARenderServerGetDebugValue(mach_port_t port, intkey);

    voidCARenderServerSetDebugOption(mach_port_t port, intkey, intvalue);

    voidCARenderServerSetDebugValue(mach_port_t port, intkey, intvalue);

    }

    由于以上能力無法在非越獄設備上開啟,所以實際上我們無法檢測 app 在任意時刻的 FPS 變化情況。

    不過經(jīng)過分析,我們發(fā)現(xiàn)只要觸發(fā)了以下行為就可能代表要幀率要變化了。如下。

    1)在設置->動態(tài)效果里開啟或關(guān)閉“限制幀速率”:修改限制幀速率會觸發(fā)系統(tǒng)拋出 com.apple.CoreAnimation.CAWindowServer.DisplayChanged 的通知,QuartCore 會在啟動時注冊這個通知,并收到通知后通過 mach port 通信獲取當前注冊的幀速率值,以動態(tài)修改 displaylink 的回調(diào)頻次。

    2)直接通過 opengl/metal api 提交一幀畫面給 Render Server。

    3)觸發(fā) CA::Transaction 對象的提交:除了觸發(fā)動畫提交,觸發(fā) view property 提交變更外,甚至創(chuàng)建 view 也會導致 source0觸發(fā)一次,如下圖所示。

    通過調(diào)試分析,我們大概清楚了 iOS15引入的 CAAnimation 的 preferredFrameRateRange 工作機制,如下圖所示。

    我們只要修改 UIUpdateSequenceRun 的回調(diào)頻率,也就是 -[UIAnimator _advanceAnimationsOnScreenWithIdentifier:withTimestamp:] 的回調(diào)頻次我們就能控制部分系統(tǒng)動畫的幀率,強制調(diào)節(jié)他的執(zhí)行頻次,或者我們通過模擬系統(tǒng)設置->動態(tài)效果->限制幀速率的實現(xiàn)方式,主動調(diào)用 -[CADisplay overrideMinimumFrameDuration:] 傳入4便可將 UIAnimator 的刷新率調(diào)節(jié)為 240/4=60hz,或者傳入8即可將系統(tǒng)動畫刷新率調(diào)節(jié)為 240/8=30hz。

    基于以上研究,理論上我們可以嘗試調(diào)用私有 api 來全局控制 CADisplay 的刷新率,來進一步降低性能占用,但是由于 Render Server 是在其他進程,我們還是無法控制 Render Server 的刷新率,并且私有 api 會導致 app 被拒審,所以我們最終依舊只能改造部分系統(tǒng)動畫實現(xiàn)以繼續(xù)基于 CAAnimation api 去優(yōu)化幀率。

    6、我們的優(yōu)化方案

    6.1概述

    從 iOS15開始蘋果新增加了 preferredFrameRateRange api 可用于設置相應動畫或timer的刷新頻率,我們就可以基于該方案去改造相應動畫即可。

    @propertyCAFrameRateRange preferredFrameRateRange

        API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0));

    但新的問題又來了,系統(tǒng)僅給 CAAnimation 和 CADisplayLink 的 api 提供了動態(tài)修改幀率的操作。

    但是在我們直播場景中,一共有如下幾種場景的動畫提交:

    • 1)UIView block 動畫;
    • 2)UIScrollView scroll 動畫;
    • 3)NSTimer 動畫;
    • 4)CAAnimation。

    除了4我們可以直接修改為 iOS15支持的 preferredFrameRateRange api 外,其它幾個我們要怎么解決呢?

    針對以上1~3點我們分別做如下處理。

    6.2UIView block 動畫

    通過分析 +[UIView animateWithDuration:delay : options:animations:completion:] 調(diào)用,我們發(fā)現(xiàn) animations block 里的 property animation 會被同步的創(chuàng)建為 CAAnimation 對象。

    如圖所示:

    那我們是否可以 hook CAAnimation 然后尋找時機設置它的 preferredFrameRateRange 以達到降幀的目的?

    很遺憾,不行,因為這個 api 觸發(fā)的動畫不會去觸發(fā)對應的 setter 與 getter 去讀取新修改的值,而是被覆蓋為一個默認值,導致無法降幀。

    再進一步調(diào)試發(fā)現(xiàn)與UIViewPropertyAnimator 里是有主動 setPreferredFrameRateRange:的操作,那是否可以從這里入手?

    經(jīng)過驗證,果然可行,于是我們可以將所有的 UIView block animation 動畫都無縫替換為新方案后,即可實現(xiàn)自動降幀隨意靈活控制的目的了。

    部分代碼如下:

        if(@available(iOS 15.0, *)) {

            setFrameRateLevel(level);

            [UIViewPropertyAnimator runningPropertyAnimatorWithDuration:duration

                                                                  delay:delay

                                                                options:options

                                                             animations:animations

    completion:^(UIViewAnimatingPosition finalPosition) {

                                                                 if(completion) {

                                                                     completion(YES);

                                                                 }

                                                             }];

            clearFrameRateLevel();

        } else{

            if(level != MMAnimationFrameRateLevelNone) {

                if(level <= MMAnimationFrameRateLevelMedium)

                    options |= UIViewAnimationOptionPreferredFramesPerSecond30;

            }

            [selfanimateWithDuration:duration delay:delay options:options animations:animations completion:completion];

        }

    新的接口可以無縫替換原有的+[UIView animateWithDuration:delay : options:animations:completion:] 調(diào)用,可對所有系統(tǒng)實現(xiàn)降幀調(diào)節(jié)優(yōu)化,極大的方便了業(yè)務開發(fā)同學在不同場景中選擇合適的動畫幀率,以達到效果和耗電的平衡。

    6.3UIScrollView 動畫

    經(jīng)過上文的分析我們發(fā)現(xiàn) UIScrollView setContentOffset 的動畫是基于系統(tǒng)_UIUpdateTarget 機制來驅(qū)動的,由于對應的回調(diào)是私有 api 觸發(fā)的,所以我們無法直接調(diào)節(jié)它的幀率,于是我們干脆自己實現(xiàn)一個基于 CADisplayLink 驅(qū)動的 setContentOffset 滑動動畫即可解決問題。

    即:創(chuàng)建一個CADisplayLink對象,指定我們需要的 preferredFrameRateRange 幀率,然后在每一幀回調(diào)時,根據(jù)當前的時間戳計算出當前需要設置的 contentOffset 值,直到最終達到了指定的動畫 duration 時間后,我們再把 contentOffset 調(diào)整為目標值,即可。

    主體代碼大致如下:

    - (void)tt_contentOffset:(CGPoint)contentOffset duration:(CFTimeInterval)duration {

        self.duration = duration;

        self.deltaContentOffset = CGPointMinus(contentOffset, self.scrollView.contentOffset);

        if(!self.displayLink) {

            self.displayLink = [CADisplayLink displayLinkWithTarget:selfselector:@selector(updateContentOffset:)];

            if(@available(iOS 15.0, *)) {

                self.displayLink.preferredFrameRateRange = CAFrameRateRangeMake(15, 24, 0);

            } else{

                self.displayLink.preferredFramesPerSecond = 30;

            }

            [self.displayLink addToRunLoop:[NSRunLoopcurrentRunLoop] forMode:NSDefaultRunLoopMode];

        } else{

            self.displayLink.paused = NO;

        }

    }

    - (void)tt_onDisplayLink:(CADisplayLink *)displayLink {

        if(self.beginTime == 0.0) {

            self.beginTime = self.displayLink.timestamp;

            self.beginContentOffset = self.scrollView.contentOffset;

        } else{

            CFTimeInterval duration = displayLink.timestamp - self.beginTime;

            CGFloat percent = (CGFloat)(duration / self.duration);

            if(percent < 1.0) {

                CGFloat progress = (CGFloat)timingFunctionValue(self.timingFunction, percent);

                if(1 - progress < 0.001) {

                    [selftt_stopAnimation];

                } else{

                    [selftt_updateProgress:progress];

                }

            } else{

                [selftt_stopAnimation];

            }

        }

    }

    6.4NSTimer 動畫

    根據(jù)蘋果Explore UI animation hitches and the render loop 的說法,為了避免 vsync 信號和 timer  可能不同步的情形,我們直接用 CADisplayLink 來替換原先的 NSTimer,并在 CADisplayLink 回調(diào)里再觸發(fā)對應的 UI 提交操作和動畫即可。

    這是因為:如下圖所示,對于13 pro max 高刷屏設備而言,其 UI 動畫的系統(tǒng)回調(diào)頻次是240hz,渲染幀率是可變的可為0~120fps 之間,而常規(guī)的 NSTimer 是基于 RunLoop 觸發(fā)回調(diào)的,RunLoop 的回調(diào)間隔可能只有幾十 us,那么 Timer 的靈敏度遠高于 DisplayLink,所以完全是有可能在2幀渲染之間,回調(diào)了一次 Timer,而最終導致可能會多觸發(fā)了一幀的提交或一次渲染事件。所以我們采取 CADisplayLink 來替換 NSTimer,盡可能避免和 Display 不同步的渲染觸發(fā)操作。

    7、優(yōu)化后的效果

    按照蘋果的建議 ,app 內(nèi)容在沒有頻繁更新時,應該盡量降低 FPS 以平衡功耗占用,因為高刷必然帶來更頻繁的 GPU 任務提交,使得 GPU 占用提升。

    并且 app 的刷新率是由所有內(nèi)容的最高刷新率決定的,也就是高 FPS 的界面元素會導致整個屏幕全局 FPS 提升,只有適當平衡全局界面元素的 FPS 后,才能進一步降低不必要的性能消耗。

    基于上述指導思想和優(yōu)化方案,我們最終在視頻號直播上驗證測試如下:

    先基于 「UIViewAnimationOptionPreferredFramesPerSecond30」 將直播點贊場景下的fps從高刷屏的120fps 降低到60fps,再基于 「UIViewPropertyAnimator」 將任意UIView block animation的幀率降低到30~48fps(最終全局穩(wěn)定在40~50fps),幀率同比下降16%而 GPU 同比下降了26%~38%(在主場景和其他場景)。并且由于我們的視頻畫面依舊是25fps的低幀率,所以此處降幀只是降低了 QuartzCore 的重復幀,而沒有減少任何畫面細節(jié),最終本質(zhì)上是無損的畫面降幀。

    另外,「在實驗過程中調(diào)試」,進一步發(fā)現(xiàn)了一些很有用的環(huán)境變量,可以幫助我們更好的調(diào)試UI問題。

    如下:

    8、問題擴展

    我們通過一些奇怪的繞過方式間接的實現(xiàn)了對所有基于 UIView block animation api 調(diào)用的動畫以及 CAAnimation api 調(diào)用的動畫都實現(xiàn)了動態(tài)降幀,這極大的改善了低幀率直播間的業(yè)務動畫導致的 GPU 功耗占用問題。

    那對于高幀率直播間我們還能怎么解決呢?

    基于蘋果的文檔幀率檔位設置建議和我們的綜合實踐效果,我們對高幀率直播間采取了部分用戶無明顯感知的有損降級策略。即當檢測到設備過熱后,我們會將60fps 的直播流,以渲染端均勻丟幀的方式降幀到48fps。

    方案如下:

    最終也一樣取得了GPU 同比下降28%甚至更高的效果,有效減輕了過熱時的系統(tǒng)負載和功耗,并且從肉眼上基本無法分辨出差異。

    9、本文小結(jié)

    本文在不影響現(xiàn)有用戶體驗和業(yè)務邏輯的情況下,通過擴展系統(tǒng)接口的能力與實驗調(diào)試分析,最終實現(xiàn)了一套 UI 動畫的幀率調(diào)節(jié)方案。

    該方案得到的效果是:

    • 1)快速改造既有業(yè)務的所有動畫,動態(tài)的控制各自的幀率;
    • 2)最終達到不影響效果的前提下,盡可能的降低了功耗;
    • 3)同時極大的減輕了業(yè)務開發(fā)同學適配多系統(tǒng)和改造動畫的工作量。

    該方案最終在微信視頻號直播上得到廣泛應用,取得了較大的性能提升。

    至此,關(guān)于iOS視頻號直播的功耗優(yōu)化方案講解完畢。

    10、相關(guān)文章

    [1] 淘寶直播技術(shù)干貨:高清、低延時的實時視頻直播技術(shù)解密

    [2] 技術(shù)干貨:實時視頻直播首屏耗時400ms內(nèi)的優(yōu)化實踐

    [3] 七牛云技術(shù)分享:使用QUIC協(xié)議實現(xiàn)實時視頻直播0卡頓!

    [4] 首次披露:快手是如何做到百萬觀眾同場看直播仍能秒開且不卡頓的?

    [5] 淺談實時音視頻直播中直接影響用戶體驗的幾項關(guān)鍵技術(shù)指標

    [6] 移動端實時視頻直播技術(shù)實踐:如何做到實時秒開、流暢不卡

    [7] 實現(xiàn)延遲低于500毫秒的1080P實時音視頻直播的實踐分享

    [8] 直播系統(tǒng)聊天技術(shù)(五):微信小游戲直播在Android端的跨進程渲染推流實踐

    附錄:微信團隊分享的其它文章

    微信團隊分享:極致優(yōu)化,iOS版微信編譯速度3倍提升的實踐總結(jié)

    IM“掃一掃”功能很好做?看看微信“掃一掃識物”的完整技術(shù)實現(xiàn)

    微信團隊分享:微信支付代碼重構(gòu)帶來的移動端軟件架構(gòu)上的思考

    IM開發(fā)寶典:史上最全,微信各種功能參數(shù)和邏輯規(guī)則資料匯總

    微信團隊分享:微信直播聊天室單房間1500萬在線的消息架構(gòu)演進之路

    企業(yè)微信的IM架構(gòu)設計揭秘:消息模型、萬人群、已讀回執(zhí)、消息撤回等

    IM全文檢索技術(shù)專題(四):微信iOS端的最新全文檢索技術(shù)優(yōu)化實踐

    微信團隊分享:微信后臺在海量并發(fā)請求下是如何做到不崩潰的

    微信Windows端IM消息數(shù)據(jù)庫的優(yōu)化實踐:查詢慢、體積大、文件損壞等

    微信技術(shù)分享:揭秘微信后臺安全特征數(shù)據(jù)倉庫的架構(gòu)設計

    企業(yè)微信針對百萬級組織架構(gòu)的客戶端性能優(yōu)化實踐

    揭秘企業(yè)微信是如何支持超大規(guī)模IM組織架構(gòu)的——技術(shù)解讀四維關(guān)系鏈

    微信團隊分享:詳解iOS版微信視頻號直播中因幀率異常導致的功耗問題


    (本文已同步發(fā)布于:http://www.52im.net/thread-4507-1-1.html



    作者:Jack Jiang (點擊作者姓名進入Github)
    出處:http://www.52im.net/space-uid-1.html
    交流:歡迎加入即時通訊開發(fā)交流群 215891622
    討論:http://www.52im.net/
    Jack Jiang同時是【原創(chuàng)Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處(也可前往 我的52im.net 找到我)。


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 亚洲一区二区免费视频| 久久亚洲精品无码观看不卡| 亚洲AV无码专区国产乱码4SE| 一级毛片正片免费视频手机看| 日韩免费视频观看| 亚洲色偷偷综合亚洲AV伊人蜜桃 | 野花香在线视频免费观看大全| 亚洲性日韩精品国产一区二区| 无码 免费 国产在线观看91| 亚洲成A人片77777国产| 日韩精品免费一线在线观看 | 亚洲AV无码成人专区片在线观看| A级毛片高清免费视频在线播放| 亚洲成av人片天堂网| 久久免费看黄a级毛片| 亚洲制服丝袜第一页| 老司机永久免费网站在线观看| 免费人成动漫在线播放r18| 久久亚洲色一区二区三区| 无码成A毛片免费| 亚洲久悠悠色悠在线播放| 免费观看大片毛片| 国产精品美女久久久免费| 亚洲男人天堂av| 免费观看的a级毛片的网站| 免费一区二区无码视频在线播放| 中文字幕精品亚洲无线码一区应用| 今天免费中文字幕视频| 亚洲香蕉在线观看| 亚洲国产精品激情在线观看| 在线观看免费播放av片| 久久精品亚洲AV久久久无码| 免费精品国产自产拍观看| 久久精品免费观看| 亚洲另类无码专区首页| 亚洲自偷自偷在线制服| 国产一精品一AV一免费孕妇| av成人免费电影| 亚洲日韩AV一区二区三区中文| 久久精品国产亚洲精品| 成熟女人特级毛片www免费|