爲了讓你們體驗基於 Agora SDK 實現的互動直播場景,咱們三年前開發了應用 Agora Live。近期,咱們對 Agora Live 進行了一次「史詩級」更新。咱們不只從新設計了 UI,而且還增長了多人連麥直播、PK 直播、虛擬主播功能。更重要的是,咱們決定把這份代碼也開源給全部開發者。但願你們能更快速地實現這些社交娛樂中最熱門的實時互動場景,並創新出更多別具一格的玩法!git
Github URL:github.com/AgoraIO-use…github
新版本 Agora Live 已經上線應用商店,僅面向 Android 和 iOS 用戶。iOS 用戶能夠在 App Store 搜索「Agora Live」直接下載或更新。Android 用戶能夠訪問聲網官網下載中心下載。bash
新版 Agora Live 目前已經支持四種時下最熱門的實時互動場景,包括:markdown
單主播直播場景:這是 Agora Live 最初就支持的功能,支持美顏、文字消息、添加背景音樂等功能。app
多人連麥直播場景:在直播的基礎上,還可邀請另外 6 名觀衆進行連麥。async
PK 直播場景:就像你們在陌陌、抖音等應用中看到的 PK 直播同樣,主播能夠向另外一個主播發起 PK 邀請。兩個直播間的觀衆會同時看到兩個主播在線互動。oop
虛擬主播場景:與單主播直播場景相似,只不過App 會爲主播生成一個實時的虛擬形象,虛擬形象的表情會與主播同步。在直播過程當中,還能夠邀請觀衆上麥。atom
App 中全部音視頻實時互動與文字消息、控制指令(如邀請上麥),都是基於聲網 Agora Native SDK 、聲網 Agora 實時消息 RTM SDK 實現的。美顏、虛擬形象則是基於聲網Agora 的生態合做夥伴相芯科技 FaceUnity SDK 實現的。spa
爲了便於你們快速熟悉源碼,咱們簡單講解如下核心功能的代碼。如下以 Swift 代碼爲例。設計
這個示例中,直播間、房主與觀衆連麥,都是基於 Agora RTC SDK 實現的。咱們經過如下代碼可讓用戶加入RTC頻道,實現音視頻的互通。
func join(channel: String, token: String? = nil, streamId: Int, success: Completion = nil) { agoraKit.join(channel: channel, token: token, streamId: streamId) { [unowned self] in self.channelStatus = .ing if let success = success { success() } } } 複製代碼
在直播間中的文字消息、控制指令(好比邀請觀衆上麥)等,都是基於 Agora 實時消息 RTM SDK 實現的。在這裏咱們集成 RTM SDK 後,經過如下代碼讓用戶加入 RTM 頻道。
func joinChannel(_ id: String, delegate: AgoraRtmChannelDelegate, success: Completion, fail: ErrorCompletion) { do { let channel = try createChannel(id: id, delegate: delegate) channel.join { (errorCode) in switch errorCode { case .channelErrorOk: self.log(info: "rtm join channel success", extra: "channel id: \(id)") if let success = success { success() } default: let error = AGEError.rtm("join channel fail", code: errorCode.rawValue, extra: "channel: \(id)") self.log(error: error) if let fail = fail { fail(error) } } } } catch { log(error: error, extra: "create channel fail") if let fail = fail { fail(error) } } } 複製代碼
美顏與虛擬形象是經過接入 FaceUnity 的服務來實現的。能夠結合 FUClient 這個類的實現與 FaceUnity 的文檔來集成美顏模塊。
typedef void (^FUCompletion)(void); typedef void (^FUErrorCompletion)(NSError *error); typedef NS_ENUM(NSUInteger, FUFilterItemType) { FUFilterItemTypeSmooth = 1, FUFilterItemTypeBrighten = 2, FUFilterItemTypeThinning = 3, FUFilterItemTypeEye = 4 }; @interface FUFilterItem : NSObject @property (nonatomic, assign) FUFilterItemType type; @property (nonatomic, assign) float defaultValue; @property (nonatomic, assign) float minValue; @property (nonatomic, assign) float maxValue; @property (nonatomic, assign) float value; @property (nonatomic, copy) NSString *funcName; @end @interface FUClient : NSObject - (void)loadFilterWithSuccess:(FUCompletion)success fail:(FUErrorCompletion)fail; - (void)setFilterValue:(float)value withType:(FUFilterItemType)type; - (FUFilterItem *)getFilterItemWithType:(FUFilterItemType)type; - (void)loadBackgroudWithSuccess:(FUCompletion)success fail:(FUErrorCompletion)fail; - (void)loadAnimoji:(NSString *)name success:(FUCompletion)success fail:(FUErrorCompletion)fail; - (void)renderItemsToPixelBuffer:(CVPixelBufferRef)pixelBuffer; - (void)destoryAllItems; @end 複製代碼
視頻流從 AVCaptureSession 流出,流入 FaceUnity 進行前處理,而後進入 Agora RTC SDK 發送到遠端。
func camera(_ camera: AGESingleCamera, position: AGECamera.Position, didOutput sampleBuffer: CMSampleBuffer) { cameraStreamQueue.async { [unowned self] in guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return } CVPixelBufferLockBaseAddress(pixelBuffer, .init(rawValue: 0)) let timeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer) if self.enhancement.beauty == .on || self.enhancement.appearance != .none { self.enhancement.renderItems(to: pixelBuffer) } self.consumer?.consumePixelBuffer(pixelBuffer, withTimestamp: timeStamp, rotation: .rotationNone) CVPixelBufferUnlockBaseAddress(pixelBuffer, .init(rawValue: 0)) } } 複製代碼
咱們已經在官方 Github「AgoraIO Usecase」中開源了 Agora Live 的代碼。你們能夠直接 fork,在聲網官網註冊後,在聲網後臺獲取 AppID,替換掉源碼中的 AppID 便可使用。方便你們快速實現多人連麥直播、單主播直播、PK 直播、虛擬主播 4 種實時互動場景。
Github URL:github.com/AgoraIO-use…
若是你在這份源碼基礎上,本身實現了更多功能,也歡迎提交 PR。咱們也會向社區中更多開發者推薦你的項目。
🌟本次開源是基於現有 App,只提供了 Java 和 Swift 源碼。若是你們須要 Objective-C 或 Kotlin 版本,還請自行封裝。
😉固然如已經有小夥伴基於源碼作了不一樣語言的版本,並願意開源給更多人,能夠提交給咱們,咱們很樂意幫忙推廣各位的 repo。