基于声网 SDK 实现 macOS 端的一对一视频通话 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cookiezmq
V2EX    分享发现

基于声网 SDK 实现 macOS 端的一对一视频通话

  •  
  •   cookiezmq 2022-09-26 14:11:20 +08:00 1330 次点击
    这是一个创建于 1190 天前的主题,其中的信息可能已经有所发展或是发生改变。

    音视频互动包括直播是当前比较热门的玩法,我们经常见到有 PK 连麦、直播答题、一起 KTV 、电商直播、互动大班课、视频相亲等。本文将演示如何通过声网 SDK 在 macOS 端实现一个视频通话应用

    前提条件

    注:如果你的网络环境部署了防火墙,请根据声网文档中心的「应用企业防火墙限制」打开相关端口。

    准备开发环境

    本节介绍如何创建项目,并将声网 SDK 集成至你的项目中。

    创建 macOS 项目

    参考以下步骤创建一个 macOS 项目。若已有 macOS 项目,可以跳脱这一步,直接查看本文「集成 SDK 」小节。

    1. 打开 Xcode 并点击 Create a new Xcode project 。

    2. 选择项目类型为 Cocoa App ,并点击 Next 。

    3. 输入项目信息,如项目名称、开发团队信息、组织名称和语言,并点击 Next 。

    如果你没有添加过开发团队信息,会看到 Add account… 按钮。点击该按钮并按照屏幕提示登入 Apple ID ,完成后即可选择你的账户作为开发团队。

    1. 选择项目存储路径,并点击 Create 。

    2. 进入 TARGETS > Project Name > General > Signing 菜单,选择 Automatically manage signing ,并在弹出菜单中点击 Enable Automatic 。 在这里插入图片描述

    集成 SDK

    选择如下任意一种方式将声网 SDK 集成到你的项目中。

    方法一:使用 CocoaPods 自动集成

    1. 开始前确保你已安装 Cocoapods 。参考 Getting Started with CocoaPods 安装说明。

    2. 在 Terminal 里进入项目根目录,并运行 pod init 命令。项目文件夹下会生成一个 Podfile 文本文件。

    3. 打开 Podfile 文件,修改文件为如下内容。注意将 Your App 替换为你的 Target 名称。

    # platform :macOS, '10.11' use_frameworks! target 'Your App' do pod 'AgoraRtcEngine_macOS' end 
    1. 在 Terminal 内运行 pod update 命令更新本地库版本。

    2. 运行 pod install 命令安装声网 SDK 。成功安装后,Terminal 中会显示 Pod installation complete! ,此时项目文件夹下会生成一个 xcworkspace 文件。

    3. 打开新生成的 xcworkspace 文件。

    方法二:手动复制 SDK 文件

    1. 前往 SDK 下载页面,获取最新版的声网 SDK ,然后解压。

    2. 将 libs 文件夹内的 AgoraRtcEngineKit.framework 文件复制到项目文件夹下。

    3. 打开 Xcode ,进入 TARGETS > Project Name > Build Phases > Link Binary with Libraries 菜单,点击 + 添加如下库。在添加 AgoraRtcEngineKit.framework 文件时,还需在点击 + 后点击 Add Other…,找到本地文件并打开。 在这里插入图片描述

    4. AgoraRtcEngineKit.framework

    5. Accelerate.framework

    6. CoreWLAN.framework

    7. libc++.dylib

    8. libresolv.9.tbd

    9. SystemConfiguration.framework

    10. VideoToolbox.framework

    添加媒体设备权限

    1. 根据场景需要,打开 Xcode ,在 info.plist 文件中,点击 + 图标开始添加如下内容,获取相应的设备权限: 在这里插入图片描述 在这里插入图片描述

    2. 若你的项目已启用 App Sandbox 或 Hardened Runtime 设置,则需勾选如下内容,获取相应的设备权限: 在这里插入图片描述在这里插入图片描述

    实现音视频通话

    本节介绍如何实现音视频通话。视频通话的 API 调用时序见下图: 在这里插入图片描述

    1. 创建用户界面

    根据场景需要,为你的项目创建音视频通话的用户界面。若已有用户界面,可以直接查看导入类。

    如果你想实现一个视频通话,我们推荐你添加如下 UI 元素:

    • 本地视频窗口

    • 远端视频窗口

    • 结束通话按钮

    当你使用示例项目中的 UI 设计时,你将会看到如下界面: 在这里插入图片描述

    2. 导入类

    在项目中导入 AgoraRtcEngineKit 类:

    // Objective-C #import <AgoraRtcEngineKit/AgoraRtcEngineKit.h> // Swift import AgoraRtcEngineKit 

    声网 Native SDK 默认使用 libc++ (LLVM),如需使用 libstdc++ (GNU),请联系 [email protected] 。SDK 提供的库是 Fat Image ,包含 32/64 位模拟器、32/64 位真机版本。

    3. 初始化 AgoraRtcEngineKit

    在调用其他声网 API 前,需要创建并初始化 AgoraRtcEngineKit 对象。

    你需要在该步骤中填入项目的 App ID 。请参考如下步骤在控制台创建声网项目并获取 App ID 。

    1. 登录控制台

    2. 点击创建,按照屏幕提示设置"项目名""使用场景",鉴权机制,在测试阶段可以选择“调试模式:APP ID”然后点击提交。

    3. 在项目管理页面,你可以获取该项目的 App ID

    调用 sharedEngineWithAppId 方法,传入获取到的 App ID ,即可初始化 AgoraRtcEngineKit

    你还可以根据场景需要,在初始化时注册想要监听的回调事件,如本地用户加入频道及解码远端用户视频首帧等。

    // Objective-C - (void)initializeAgoraEngine { // 输入 App ID 并初始化 AgoraRtcEngineKit 类 self.agoraKit = [AgoraRtcEngineKit sharedEngineWithAppId:appID delegate:self]; } 
    // Swift func initializeAgoraEngine() { // 输入 App ID 并初始化 AgoraRtcEngineKit 类。 agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: AppID, delegate: self) } 

    4. 设置本地视图

    如果你想实现一个语音通话,可以直接查看加入频道。

    成功初始化 AgoraRtcEngineKit 对象后,需要在加入频道前设置本地视图,以便在通话中看到本地图像。参考以下步骤设置本地视图:

    • 调用 enableVideo 方法启用视频模块。

    • 调用 setupLocalVideo 方法设置本地视图。

    // Objective-C // 启用视频模块 [self.agoraKit enableVideo]; - (void)setupLocalVideo { AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init]; videoCanvas.uid = 0; videoCanvas.view = self.localVideo; videoCanvas.renderMode = AgoraVideoRenderModeHidden; // 设置本地视图 [self.agoraKit setupLocalVideo:videoCanvas]; } // Swift // 启用视频模块 agoraKit.enableVideo() func setupLocalVideo() { let videoCanvas = AgoraRtcVideoCanvas() videoCanvas.uid = 0 videoCanvas.view = localVideo videoCanvas.renderMode = .hidden // 设置本地视图 agoraKit.setupLocalVideo(videoCanvas) } 

    5. 加入频道

    完成初始化和设置本地视图后(视频通话场景),你就可以调用 joinChannelByToken 方法加入频道。你需要在该方法中传入如下参数:

    • channelId : 传入能标识频道的频道 ID 。输入频道 ID 相同的用户会进入同一个频道。

    • token :传入能标识用户角色和权限的 Token 。可设为如下一个值:

    若项目已启用 App 证书,请使用 Token 。

    • nil

    • 临时 Token 。临时 Token 服务有效期为 24 小时。你可以在控制台里生成一个临时 Token ,详见获取临时 Token 。

    • 在你的服务器端生成的 Token 。在安全要求高的场景下,我们推荐你使用此种方式生成的 Token ,详见生成 Token 。

    • uid : 本地用户的 ID 。数据类型为整型,且频道内每个用户的 uid 必须是唯一的。若将 uid 设为 0 ,则 SDK 会自动分配一个 uid ,并在 joinSuccessBlock 回调中报告。

    • joinSuccessBlock :成功加入频道回调。 joinSuccessBlock 优先级高于 didJoinChannel ,2 个同时存在时, didJoinChannel 会被忽略。需要有 didJoinChannel 回调时,请将 joinSuccessBlock 设置为 nil

    更多的参数设置注意事项请参考 joinChannelByToken 接口中的参数描述。

    // Objective-C - (void)joinChannel { // 加入频道 [self.agoraKit joinChannelByToken:token channelId:@"demoChannel1" info:nil uid:0 joinSuccess:^(NSString *channel, NSUInteger uid, NSInteger elapsed) { }]; } 
    // Swift func joinChannel() { // 加入频道 agoraKit.joinChannel(byToken: Token, channelId: "demoChannel1", info:nil, uid:0) { [unowned self] (channel, uid, elapsed) -> Void in} self.isLocalVideoRender = true self.logVC?.log(type: .info, content: "did join channel") } isStartCalling = true } 

    6. 设置远端视图

    视频通话中,通常你也需要看到其他用户。在加入频道后,可通过调用 setupRemoteVideo 方法设置远端用户的视图。

    远端用户成功加入频道后,SDK 会触发 firstRemoteVideoDecodedOfUid 回调,该回调中会包含这个远端用户的 uid 信息。在该回调中调用 setupRemoteVideo 方法,传入获取到的 uid ,设置远端用户的视图。

    // Objective-C // 监听 firstRemoteVideoDecodedOfUid 回调。 // SDK 接收到第一帧远端视频并成功解码时,会触发该回调。 // 可以在该回调中调用 setupRemoteVideo 方法设置远端视图。 - (void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoDecodedOfUid:(NSUInteger)uid size: (CGSize)size elapsed:(NSInteger)elapsed { if (self.remoteVideo.hidden) { self.remoteVideo.hidden = NO; } AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init]; videoCanvas.uid = uid; videoCanvas.view = self.remoteVideo; videoCanvas.renderMode = AgoraVideoRenderModeHidden; // 设置远端视图 [self.agoraKit setupRemoteVideo:videoCanvas]; } 
    // Swift // 监听 firstRemoteVideoDecodedOfUid 回调。 // SDK 接收到第一帧远端视频并成功解码时,会触发该回调。 // 可以在该回调中调用 setupRemoteVideo 方法设置远端视图。 func rtcEngine(_ engine: AgoraRtcEngineKit, firstRemoteVideoDecodedOfUid uid:UInt, size:CGSize, elapsed:Int) { isRemoteVideoRender = true let videoCanvas = AgoraRtcVideoCanvas() videoCanvas.uid = uid videoCanvas.view = remoteVideo videoCanvas.renderMode = .hidden // 设置远端视图 agoraKit.setupRemoteVideo(videoCanvas) } 

    7. 离开频道

    根据场景需要,如结束通话、关闭 App 或 App 切换至后台时,调用 leaveChannel 离开当前通话频道。

    // Objective-C - (void)leaveChannel { // 离开频道。 [self.agoraKit leaveChannel:^(AgoraChannelStats *stat) } // Swift func leaveChannel() { // 离开频道 AgoraKit.leaveChannel(nil) AgoraKit.setupLocalVideo(nil) remoteVideo.removeFromSuperview() localVideo.removeFromSuperview() delegate?.VideoChatNeedClose(self) AgoraKit = nil view.window!.close() } 

    示例代码

    你可以在 Agora-macOS-Tutorial-Objective-C-1to1/Agora-macOS-Tutorial-Swift-1to1 示例项目的 VideoChatViewController.m/VideoChatViewController.swift 文件中查看完整的源码和代码逻辑。

    运行 /测试项目

    你可以在 macOS 设备中运行此项目。当成功开始视频通话时,你可以同时看到本地和远端的视图。


    如果遇到问题,可以在RTE 开发者社区 发帖提问。

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1020 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 18:29 PVG 02:29 LAX 10:29 JFK 13:29
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86