├── .gitignore ├── AV_Monitor.md ├── README.md ├── SPEARConfig.md ├── SPEARConfig_pics ├── image001.png ├── image002.png ├── image003.png ├── image004.png ├── image005.png ├── image006.png ├── image007.png ├── image008.png ├── image009.png ├── image010.png ├── image011.png ├── image012.png ├── image013.png ├── image014.png ├── image015.png ├── image016.png ├── image017.png ├── image018.png ├── image019.png ├── image020.png ├── image021.png ├── image022.png ├── image023.png ├── image024.png └── image025.png ├── avmonitor_pics ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg ├── 6.jpg ├── 7.jpg └── 8.jpg ├── demoList.md ├── doc2 ├── AVSDK 1.8.4转置功能升级指南.md ├── Android_ILiveSDK_BeforeHand.md ├── Android_ILiveSDK_Live.md ├── Android_ILiveSDK_Senior.md ├── Architecture.md ├── History.md ├── IE_ILiveSDK_BeforeHand.md ├── IE_ILiveSDK_Interactive.md ├── IE_ILiveSDK_Live.md ├── Introduction.md ├── Mac_ILiveSDK_BeforeHand.md ├── Mac_ILiveSDK_Interactive.md ├── Mac_ILiveSDK_Live.md ├── avmonitor.md ├── breakEvent.md ├── custom.md ├── custominput.md ├── docList.md ├── enterRoomParam.md ├── fastConfig.md ├── focus.md ├── iOS_ILiveSDK_BeforeHand.md ├── iOS_ILiveSDK_Interactive.md ├── iOS_ILiveSDK_Live.md ├── log.md ├── loguploader.md ├── multiStream.md ├── musicinput.md ├── ocdc.md ├── onlineMember.md ├── pushStream.md ├── record.md ├── restCall.md ├── restCallPushStream.md ├── restCallRecord.md ├── rotate.md ├── serverInit.md ├── spearConfig.md ├── speed test.md ├── webPlayer.md ├── 互动直播下载页面.md ├── 截图和鉴黄.md ├── 新老随心播信令兼容文档.md ├── 直播码升级指南.md ├── 直播码模式下录制开发指南.md ├── 直播码模式下旁路直播开发指南.md ├── 角度方案.md └── 随心播后台.markdown ├── ios自定义画面采集流程文档.md ├── 大咖模式.md ├── 屏幕旋转方案.md └── 随心播 ├── .DS_Store ├── Android随心播集成 ├── DEMO开发文档.md ├── ILVCallManager.md ├── ILVLiveManager.md ├── ILVLiveRecordAPush.md ├── ILVLiveSenior.md ├── Names.md ├── beforeHand.md └── image │ ├── OpenVideo.png │ ├── UiLayers.png │ ├── customcmd.png │ ├── demos.png │ ├── helloAndroid.png │ ├── idntype.png │ ├── iliveappid.png │ ├── ilivelocation.png │ ├── jarnso.png │ ├── jdk.png │ ├── livedemo.png │ ├── nolongsupport.png │ ├── pic1.png │ ├── pic10.png │ ├── pic11.png │ ├── pic12.png │ ├── pic13.png │ ├── pic14.png │ ├── pic15.png │ ├── pic16.png │ ├── pic17.png │ ├── pic18.png │ ├── pic19.png │ ├── pic2.png │ ├── pic20.png │ ├── pic21.png │ ├── pic3.png │ ├── pic4.png │ ├── pic5.png │ ├── pic6.png │ ├── pic7.png │ ├── pic8.png │ ├── pic9.png │ ├── process.png │ ├── qalservice.png │ ├── respositories.png │ ├── rights.png │ ├── sdkversion.png │ ├── server.png │ └── suixinbo.png └── iOS随心播集成 ├── 0.随心播功能列表.md ├── 1.随心播运行指南.md ├── 2.架构集成.md ├── 3.开发指南.md ├── 4.直播中的功能点讲解.md ├── OpenGL Crash问题定位方法.md ├── beforeHand.md └── media ├── image1.png ├── image10.png ├── image100.png ├── image101.png ├── image102.png ├── image103.png ├── image104.jpeg ├── image105.jpeg ├── image106.png ├── image107.png ├── image108.png ├── image109.png ├── image11.jpeg ├── image110.png ├── image111.png ├── image112.png ├── image113.png ├── image114.png ├── image12.jpeg ├── image13.jpeg ├── image14.jpeg ├── image15.jpeg ├── image16.jpeg ├── image17.jpeg ├── image18.jpeg ├── image19.jpeg ├── image2.png ├── image20.jpeg ├── image21.jpeg ├── image22.jpeg ├── image23.jpeg ├── image24.png ├── image25.png ├── image26.png ├── image27.png ├── image28.png ├── image29.png ├── image3.png ├── image30.jpeg ├── image31.png ├── image32.jpeg ├── image33.png ├── image34.png ├── image35.png ├── image36.png ├── image37.png ├── image38.png ├── image39.png ├── image4.png ├── image40.png ├── image41.png ├── image42.jpeg ├── image43.png ├── image44.png ├── image45.jpeg ├── image46.png ├── image47.png ├── image48.png ├── image49.png ├── image5.png ├── image50.png ├── image51.png ├── image52.png ├── image53.png ├── image54.png ├── image55.png ├── image56.png ├── image57.png ├── image58.png ├── image59.png ├── image6.jpeg ├── image60.png ├── image61.png ├── image62.png ├── image63.png ├── image64.png ├── image65.png ├── image66.png ├── image67.png ├── image68.png ├── image69.png ├── image7.jpeg ├── image70.png ├── image71.png ├── image72.png ├── image73.png ├── image74.png ├── image75.png ├── image76.png ├── image77.png ├── image78.png ├── image79.png ├── image8.jpeg ├── image80.png ├── image81.png ├── image82.png ├── image83.png ├── image84.png ├── image85.png ├── image86.png ├── image87.png ├── image88.png ├── image89.png ├── image9.jpeg ├── image90.png ├── image91.png ├── image92.png ├── image93.jpeg ├── image94.png ├── image95.jpeg ├── image96.png ├── image97.png ├── image98.jpeg └── image99.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /AV_Monitor.md: -------------------------------------------------------------------------------- 1 | # AV_Monitor功能和使用介绍 2 | 3 | ## 内容提要 4 | 5 | AV\_Monitor是帮助用户定位排除网络问题的实时监控工具。地址是[http://avq.avc.qcloud.com/monitor.html](http://avq.avc.qcloud.com/monitor.html)。 6 | 7 | ## 基本功能 8 | 9 | ![基本界面](avmonitor_pics/1.jpg) 10 | 11 | 界面最上方是查询条件录入文本框,SdkAppid、账号(Identifier)、查询时间段,都是必填项目。界面左边竖排的两个文本框,主要用于显示某些上报具体的取值,方便开发同事定位问题。例如,在下图中点击进入房间的红色点就可以在左侧文本框里看到一些基本信息,如CPU、操作系统、网络类型、机型、SDK版本等 12 | ![基本界面](avmonitor_pics/2.jpg) 13 | 14 | 同样是这张图,在曲线上方显示地列出了所查询用户的一些常用的基本信息,其中需要关注以下几项: 15 | 16 | * Tinyid,即基本信息左侧最下面的uin:xxxxxx,这个有时候开发查问题需要用 17 | * 是否代理机,在DC上的用户,这里显示“否”;在OC上的用户,这里显示“是” 18 | * 传输协议,通常主播类型都是UDT 19 | * 客户端IP,可以看到用户侧的省份运营商 20 | * 接口机IP,可以查看分配的接入机IP和客户端是否匹配,但目前只能显示内网IP,需要腾讯开发在内部网站tnm2.oa.com查询 21 | 22 | 最后,上图中最右边的图表目录是各种曲线图表的快捷入口,点击即达想要的位置 23 | 24 | ## 下行质量监控图表 25 | 26 | 顾名思义,主要用于展示观众端的各种动作和状态,下面注意列举各图表展示的内容和使用场景 27 | 28 | ### 下行总丢包率 29 | 30 | ![基本界面](avmonitor_pics/3.jpg) 31 | 32 | * 丢包率曲线 33 | 最下面的紫色曲线是丢包率曲线,每2s一个点,反应的是用户当前的网络状况。高丢包率会导致音视频卡顿,而出现高丢包通常说明用户可能网络质量较差。例如,上图中丢包率曲线显示,在用户开播的时候有短时的丢包情况,而其他时间丢包率为0,说明其整体网络状况良好 34 | 35 | * 红色点 36 | 红色点代表用户一次进房间的动作。红点是可以用鼠标点的,点了之后图表上方的基本信息和左侧的文本框里会刷新出该用户这次进房间时所携带的基本信息 37 | 38 | * 蓝色点 39 | 蓝色点代表用户一次退出房间的动作。由于用户可能不退出房间直接杀进程,所以蓝色点可能会比真实情况晚90s(后台的超时时间)。鼠标放在蓝色点上会弹出提示信息,可以看到是正常退出还是超时退出 40 | 41 | * 黄色点 42 | 黄色点是说明用户在使用过程中IP发生了改变,极有可能发生了网络切换但又没退出房间 43 | 44 | ### 下行总码率 45 | 46 | ![基本界面](avmonitor_pics/4.jpg) 47 | 48 | 下行总码率=下行视频码率+下行音频码率(包含各自的FEC)。点击下行总码率的任意一个点,都可以得到主播的TinyID,而通过这个TinyID就可以查看主播的状态信息,不用再去找业务开发要主播ID了,事实证明这个功能非常的有用 49 | 50 | ### 下行音频码率 51 | 52 | 顾名思义,需要注意的是,由于音频最高会有100%的FEC,网络不好的时候和平时码率可能会相差1一倍 53 | 54 | #### 其他下行图标 55 | 56 | * 下行大画面总帧率,顾名思义 57 | * 下行大画面总帧率,顾名思义,帧率越低,画面越不流畅 58 | * 下行辅路总帧率/总码率,屏幕分享的帧率码率 59 | 60 | ## 上行质量监控图表 61 | 62 | ### 上行总丢包率 63 | 64 | ![基本界面](avmonitor_pics/5.jpg) 65 | 66 | 与下行丢包率视图相比,这里只多了一个粉色点,代表获取/清除视频位。这是主播独有的动作,即开播前需要向后台申请视频位成功,后台才会将该主播的视频流转给观众。若该主播30s内没有任何视频数据上行,那么后台将会清理视频位;如果主播后来仍要上行视频流,则需要重新申请视频位。 67 | 68 | ### 时延(ms) 69 | 70 | ![基本界面](avmonitor_pics/6.jpg) 71 | 72 | 时延,是指客户端到接口机Hello包的RTT。通常网络变差时延时就会变大,造成视频卡顿。需要注意的是,有时候CPU高也会引起延时变大,这是由于CPU高占用使得Hello包的处理进程无法正常处理回包导致的 73 | 74 | ## 其他监控图表 75 | 76 | ![基本界面](avmonitor_pics/7.jpg) 77 | 78 | 应用的CPU使用率是指SDK的CPU占用情况,设备的CPU使用率是指App整体占用情况。需要注意的是,最近iPhone遇到某些场景下CPU降频导致CPU整体占用过高的问题,需要具体情况具体分析 79 | 80 | 81 | # 互动直播音视频后台Q&A 82 | 83 | ## 关于“房间”的认知 84 | 85 | 对于互动直播音视频后台而言,房间主要用于实现用户群体的隔离,用户在不同的房间可以看到不同主播的视频流,这个和现实中秀场的概念是想通的。房间是用`房间ID`标识的,类型为32位整形数字,由**_业务方生成和管理_**,不同的房间应该使用不同的`房间ID`。 86 | 87 | 注意,音视频的`房间ID`与IM群组ID是没有任何关联的,但通常业务在使用过程中其实是将*音视频房间*和*IM群组*做了一一对应的,即可以用IM群组ID作为音视频`房间ID`或在二者之间建立映射,这个都是业务方自己根据实际需要来决策 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 随心播相关知识目录 2 | 3 | AV_Monitor是帮助用户定位排除网络问题的实时监控工具。 4 | * [https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/AV_Monitor.md](AV_Monitor.md) 5 | SPEAR引擎流控用来配置直播时候的码率等相关属性。 6 | * [https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/SPEARConfig.md](SPEARConfig.md) 7 | ios随心播集成文档 8 | * [https://github.com/zhaoyang21cn/suixinbo\_doc/blob/master/%E9%9A%8F%E5%BF%83%E6%92%AD/iOS%E9%9A%8F%E5%BF%83%E6%92%AD%E9%9B%86%E6%88%90/1.%E9%9A%8F%E5%BF%83%E6%92%AD%E8%BF%90%E8%A1%8C%E6%8C%87%E5%8D%97.md](%E9%9A%8F%E5%BF%83%E6%92%AD/iOS%E9%9A%8F%E5%BF%83%E6%92%AD%E9%9B%86%E6%88%90/1.%E9%9A%8F%E5%BF%83%E6%92%AD%E8%BF%90%E8%A1%8C%E6%8C%87%E5%8D%97.md) 9 | Android基础文档 10 | * [https://github.com/zhaoyang21cn/suixinbo\_doc/blob/master/%E9%9A%8F%E5%BF%83%E6%92%AD/Android%E9%9A%8F%E5%BF%83%E6%92%AD%E9%9B%86%E6%88%90/DEMO%E5%BC%80%E5%8F%91%E6%96%87%E6%A1%A3.md](%E9%9A%8F%E5%BF%83%E6%92%AD/Android%E9%9A%8F%E5%BF%83%E6%92%AD%E9%9B%86%E6%88%90/DEMO%E5%BC%80%E5%8F%91%E6%96%87%E6%A1%A3.md) 11 | -------------------------------------------------------------------------------- /SPEARConfig.md: -------------------------------------------------------------------------------- 1 | # SPEAR引擎流控配置简介 2 | ###**在进行实际开发前,首先要在腾讯云互动直播配置流控参数,才能获得更好的视频效果。** 3 | 4 | # 一、入口 5 | 登录腾讯云后,从 “云产品” -> “互动直播” 进入配置页面。 6 | ![](SPEARConfig_pics/image001.png) 7 | 8 | 进入“互动直播”配置页面后,可以看到自己创建的不同appid对应的配置。鼠标放在“更多”上,选择“SPEAR引擎配置”。 9 | 10 | ![](SPEARConfig_pics/image002.png) 11 | 12 | 进入后就可以看到具体的参数配置。后面会详细说明配置的含义和如何设置参数。 13 | 14 | ![](SPEARConfig_pics/image004.png) 15 | 16 | # 二、配置说明 17 | ## 1. 场景 18 | 互动直播的配置首先分为不同的场景,每个场景保存自己的配置参数。一个appid可以设置一种对应的场景,当切换场景时,所有的音视频参数都会切换。 19 | 目前互动直播主要支持两种场景的业务:互动直播和实时通信。 20 | 21 | ![](SPEARConfig_pics/image006.png) 22 | ![](SPEARConfig_pics/image007.png) 23 | 24 | 互动直播主要针对一个或少量几个主播在直播,其他大多数的观众观看的场景。只有一个或几个用户有上行数据,其他大多数用户(几百、几千或更多)只有下行数据,没有上行数据。 25 | 实时通信主要针对多人聊天或多人会议的场景。参与的用户都有上下行数据的需要,同时需要较高的实时性,延时要小。 26 | 针对不同的场景,提供更适合业务需要的参数配置。 27 | 28 | ## 2. 平台 29 | 每个场景中包含不同平台的配置,支持根据不同的平台设置平台相关的不同参数。目前支持Windows、Web、iOS、Android四个平台,其中Windows和Web的参数配置是统一的。这样设置好后,Windows客户端会自动使用Windows页面的配置,iOS客户端会自动使用iOS页面的配置,以此类推。 30 | 31 | ![](SPEARConfig_pics/image008.png) 32 | 33 | ## 3. 角色 34 | 具体的某一平台的配置中,可以添加多个角色。角色实现了在单一平台上也可以配置不同的参数,即同一客户端可以通过切换角色来实现改变音视频配置的策略。 35 | user是默认角色,当客户端没有选择角色时,会使用默认角色的配置。 36 | 37 | ![](SPEARConfig_pics/image010.png) 38 | 39 | 可以在页面的最底部添加角色,角色名称设置角色名。角色可以编辑,自己添加的角色可以删除。角色可以根据业务需要添加多个。 40 | 41 | ![](SPEARConfig_pics/image012.png) 42 | ![](SPEARConfig_pics/image014.png) 43 | 44 | 45 | ## 4. 场景、平台、角色的不同 46 | 场景、平台、角色都可以用来设置不同的配置方案,他们之间有什么区别? 47 | 场景是应用层面的不同,即一个app是主要用于直播还是实时通话。直播对清晰度流畅度要求高、延时要求低,实时通话对延时要求高;所以互动直播和实时通信的很多配置项都是不同的。一般一个app选择一个场景后,后续不会再改变。平台很容易理解,主要处理平台相关的不同配置,比如PC的性能一般比手机高,手机上的app会有权限的要求的等等。 48 | 49 | 角色上的区分,主要是为了业务层面的支持。不同角色可设置的配置项和取值范围都是一样的,配置的不同完全由业务决定。比如,作为主播时使用可以上行数据的配置,作为观众时使用只有下行数据的配置;性能高的机器上使用分辨率更高的配置等等。 50 | 51 | 52 | ## 5. 参数配置 53 | 参数配置分为视频参数、音频参数、网络参数三部分。在互动直播场景下,视频参数和大部分音频参数(下图红框中的参数)主要应用于上行数据,即只对主播起作用,对观众不起作用;网络参数应用于上下行数据,对主播、观众都起作用。实时通信场景,所有用户都有上下行数据,所以三部分参数对所有用户都起作用。 54 | 55 | ![](SPEARConfig_pics/image016.png) 56 | 57 | 下面具体看下每部分参数的设置。 58 | ### 5.1 视频参数 59 | 60 | ![](SPEARConfig_pics/image018.png) 61 | 62 | 63 | * 配置模式:提供预设的“标清”、“高清”、“超清”打包模式,选择后不需要再配置其他参数。建议选择“高清”。选择“自定义”模式,可以自己配置其他参数 64 | * 编码格式:“自适应”由SDK根据设备性能和网络情况自行调整分辨率;“固定图像格式”选择一个固定的分辨率,提供4:3和16:9两种类型的分辨率。 65 | * 编码码率:“自适应”由SDK根据设备性能和网络情况自行调整码率;“自定义”指定SDK可以调整的范围,如果需要固定码率可以把最大最小值设置成一样的 66 | * 编码帧率:“自适应”由SDK根据设备性能和网络情况自行调整帧率;“自定义”指定一个期望的帧率。帧率和码率、清晰度相关,如果MinQP、MaxQP设置的不当,可能达不到期望的帧率。 67 | * 冗余抗丢包:通过FEC等方式增加冗余度来抵消网络丢包,冗余度一般为丢包率的两倍。一般情况下建议关闭。 68 | 69 | 帧率、码率、分辨率有一定的相关性,QP设置的不合理也有可能会降低帧率。简单的用法可以直接选择预设的“标清”、“高清”、“超清”打包模式;自定义情况下,帧率、码率、分辨率的对应建议如下: 70 | 71 | 分辨率 | 码率 | 帧率 72 | ---- |---- |---- 73 | 640 x 368 | 800Kbps | 25fps 74 | 960 x 540 | 1200Kbps | 15fps 75 | 76 | ### 5.2 音频参数 77 | 78 | ![](SPEARConfig_pics/image020.png) 79 | 80 | * 配置模式:“默认”模式不需要再设置其他参数,“自定义”模式可设置更多参数。 81 | * 音频场景:“开播”模式可以采集、编码、发送音频,适用于主播;“观看”模式不会打开音频设备也不会发送音频数据,适用于观众。 82 | * 编码码率:设置音频码率,范围0~64 83 | * 冗余抗丢包:通过FEC等方式增加冗余度来抵消网络丢包。互动直播场景建议关闭,实时通信场景建议打开。 84 | * aec:回声消除。互动直播不连麦的场景建议关闭,互动直播可能连麦场景和实时通信场景建议打开。 85 | * agc:自动增益。互动直播不连麦的场景建议关闭,互动直播可能连麦场景和实时通信场景建议打开。 86 | * ans:噪声抑制。互动直播不连麦的场景建议关闭,互动直播可能连麦场景和实时通信场景建议打开。 87 | 88 | ### 5.3 参数差异 89 | 90 | ![](SPEARConfig_pics/image024.png) 91 | 92 | 不同平台、不同场景下的参数配置略有不同,根据页面显示的可配置选项配置即可。 93 | 94 | 如实时通信场景,音频参数和网络参数是不能配置的。 95 | 96 | 可配置参数可能会随着版本升级发生变化,以配置网页上显示的配置项为准。 97 | 98 | # 三、客户端逻辑 99 | ## 1. 配置生效时机 100 | 在腾讯云上配置好后,客户端不会立即生效。客户端要在调用xxx api(AVSDK StartContext, ILive iLiveLogin)时,去后台拉取最新配置。拉取成功后会在本地保存。 101 | 102 | ## 2. 默认配置 103 | SDK自带一套保底默认配置,用户可以调用的API修改保底默认配置,设置的参数可以从云端配置网站获得 ,参数值为明文json字符串。SDK使用配置时,如果云端配置第一次无法获取, 则使用保底默认配置。其他情况仍走之前云端配置逻辑。 104 | 105 | ## 3. 客户端自定义配置(1.8.2) 106 | 使用用户设置的自定义配置,设置的参数值为和云端配置相同格式的明文json字符串。设置成功后,一直使用这套配置,配置的更新由用户主动调用API更新实现(详见QAVCustomSpearEngine)。采用这种方案,客户端不再从腾讯云自动更新配置。 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /SPEARConfig_pics/image001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image001.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image002.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image003.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image004.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image005.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image006.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image007.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image008.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image009.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image010.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image011.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image012.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image013.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image014.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image015.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image016.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image017.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image018.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image018.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image019.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image019.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image020.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image021.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image021.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image022.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image023.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image023.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image024.png -------------------------------------------------------------------------------- /SPEARConfig_pics/image025.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/SPEARConfig_pics/image025.png -------------------------------------------------------------------------------- /avmonitor_pics/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/avmonitor_pics/1.jpg -------------------------------------------------------------------------------- /avmonitor_pics/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/avmonitor_pics/2.jpg -------------------------------------------------------------------------------- /avmonitor_pics/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/avmonitor_pics/3.jpg -------------------------------------------------------------------------------- /avmonitor_pics/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/avmonitor_pics/4.jpg -------------------------------------------------------------------------------- /avmonitor_pics/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/avmonitor_pics/5.jpg -------------------------------------------------------------------------------- /avmonitor_pics/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/avmonitor_pics/6.jpg -------------------------------------------------------------------------------- /avmonitor_pics/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/avmonitor_pics/7.jpg -------------------------------------------------------------------------------- /avmonitor_pics/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/avmonitor_pics/8.jpg -------------------------------------------------------------------------------- /demoList.md: -------------------------------------------------------------------------------- 1 | ### 互动直播场景 2 | 3 | #### 随心话 4 | 基于互动直播sdk的网络视频电话场景解决方案演示 5 | * ![](https://mc.qcloudimg.com/static/img/eeab202e8681e4d73ae251c4df3006a6/image.jpg) 6 | * Android https://github.com/zhaoyang21cn/ILiveSDK_Android_Demos/tree/master/tdemovideocall 7 | * ios https://github.com/zhaoyang21cn/ILiveSDK_iOS_Demos/tree/master/ILiveCall 8 | 9 | #### 随心播 10 | 完整的集成了互动直播功能的demo。开发者可以参考此方案进行自己app的开发。 11 | * ![](https://mc.qcloudimg.com/static/img/e174cda56d80adf92e2ab73ccd56aa05/image.jpg) 12 | * Android https://github.com/zhaoyang21cn/ILiveSDK_Android_Demos/tree/master/suixinbo 13 | * iOS https://github.com/zhaoyang21cn/iOS_Suixinbo 14 | 15 | #### 主播变脸 16 | * ![](https://mc.qcloudimg.com/static/img/8b82ceda045bebe51d057b9e9aa2b036/image.jpg) 17 | 18 | #### 随心聊 19 | 提供了好友,群组,发送文本、图片、语音、消息等IM功能的demo。 20 | * ![](https://mc.qcloudimg.com/static/img/78016e44249ecdf7891605171e47b7b8/image.jpg) 21 | * Android https://github.com/zhaoyang21cn/Android_Suixinliao 22 | * iOS https://github.com/zhaoyang21cn/iOS_Suixinliao 23 | 24 | 25 | #### 实况转播实时评论 26 | * 即将推出 27 | 28 | #### 纯音频录制 29 | * 即将推出 30 | 31 | ### 互动直播小demo 32 | 33 | #### 快速开始一个直播 34 | * Android https://github.com/zhaoyang21cn/ILiveSDK_Android_Demos/tree/master/tdemolive 35 | * ios 36 | 37 | 38 | #### 自定义画面采集 39 | * 如果有需要对主播的画面进行自定义美颜、变形处理的,可以参考这个解决方案 40 | * Android https://github.com/zhaoyang21cn/ILiveSDK_Android_Demos/tree/master/customstream 41 | * iOS https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/ios%E8%87%AA%E5%AE%9A%E4%B9%89%E7%94%BB%E9%9D%A2%E9%87%87%E9%9B%86%E6%B5%81%E7%A8%8B%E6%96%87%E6%A1%A3.md 42 | 43 | 44 | #### 直播和观众画面大小自定义 45 | ![](https://mc.qcloudimg.com/static/img/d7f8c199d0497330096321e4aaeb481f/resize.jpg) 46 | 47 | 48 | #### 观众画面随主播画面自动旋转 49 | * https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/%E5%B1%8F%E5%B9%95%E6%97%8B%E8%BD%AC%E6%96%B9%E6%A1%88.md 50 | 51 | #### 画面对焦 52 | * Android自动对焦 在ILVLiveCOnfig中设置autoFocus(true) 53 | * iOS手工对焦 https://github.com/zhaoyang21cn/ILiveSDK_iOS_Demos/tree/master/FocusDemo 54 | 55 | #### 实时显示直播质量 56 | * iOS https://github.com/zhaoyang21cn/iOS_Suixinbo 57 | 58 | 59 | ### 开发辅助工具 60 | 61 | ### AV_Monitor是帮助用户定位排除网络问题的实时监控工具。 62 | * https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/AV_Monitor.md 63 | 64 | ### SPEAR引擎流控用来配置直播时候的码率等相关属性。 65 | * https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/SPEARConfig.md 66 | -------------------------------------------------------------------------------- /doc2/AVSDK 1.8.4转置功能升级指南.md: -------------------------------------------------------------------------------- 1 | ## AVSDK 1.8.4转置功能升级指南 2 | 3 | ### 名词解释 4 | 5 | * 转置:终端app根据手机的重力传感器的反馈,把采集的视频内容进行旋转,保持正向角度。 6 | 7 | ### 背景 8 | 9 | 由于视频采集端和播放端各自都有独立的角度变化,会造成视频播放的时候经常出现和采集端画面不一致的情况。这个看似简单的问题在叠加了前后摄像头切换、画面裁剪拉伸、录制、不同的播放要求等变量后,会变得异常复杂。 10 | 11 | 为了解决这个问题,AVSDK从1.8.2开始,逐步完善了对视频采集和播放的转置能力,在1.8.4版本中有了全面的解决方案。 12 | 13 | 此文档旨在为开发者提供从AVSDK当前版本升级到1.8.4中可能遇到的兼容性问题提供解决方案。 14 | 15 | ##### 如果您使用的是iLive SDK,则不需要考虑这个问题。 16 | 17 | ## 升级AVSDK 1.8.4可能遇到的转置兼容性问题 18 | 19 | 未开客户端转置以前的版本,观看AVSDK 1.8.4的版本开了客户端转置的视频时,视频有可能被拉伸或者旋转。 20 | 21 | 22 | ## 如何解决这个兼容性问题 23 | 24 | ### 一 从1.8.1之前的版本(包含1.8.1)升级: 25 | 26 | 不建议直接升级1.8.4, 需要先升级到1.8.2。步骤如下: 27 | 28 | 1. 升级AVSDK到1.8.2,并将转置开关设置为关(iOS把QAVMultiParam的autoRotateVideo为NO,Android设置AVRoomMulti.EnterParam.Builder.isDegreeFixed为false) 29 | 2. 参考附录中的指南升级ios OpenGL渲染代码。 30 | 3. 新app与线上使用AVSDK1.8.1的app进行联调,调试好渲染逻辑,并做好iOS/Android互看适配工作; 31 | 4. 待基于AVSDK 1.8.2版本的app普及后,启动AVSDK1.8.4的升级; 32 | 5. 在腾讯云后台提交[工单](https://console.qcloud.com/workorder/category/create?level1_id=29&level2_id=37&level1_name=%E8%A7%86%E9%A2%91%E4%B8%8E%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1&level2_name=%E4%BA%92%E5%8A%A8%E7%9B%B4%E6%92%AD%20%20ILVB),问题类型选择`其他问题`,问题描述填写`添加转置白名单申请-公司名-腾讯云账号(XXXXXXX)-申请白名单的sdkappid(XXXXXXX)`; 33 | 6. 待工单处理完毕,升级AVSDK 1.8.4,并做好iOS/Android互看适配工作,以及与线上版本兼容测试; 34 | 7. 待基于AVSDK 1.8.4版本的app普及后,提交[工单](https://console.qcloud.com/workorder/category/create?level1_id=29&level2_id=37&level1_name=%E8%A7%86%E9%A2%91%E4%B8%8E%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1&level2_name=%E4%BA%92%E5%8A%A8%E7%9B%B4%E6%92%AD%20%20ILVB),问题类型选择`其他问题`,问题描述填写`移除转置白名单申请-公司名-腾讯云账号(XXXXXXX)-申请白名单的sdkappid(XXXXXXX)`; 35 | 36 | 37 | 38 | ### 二 . 从1.8.2版本升级: 39 | 40 | 如果客户端的转置开关是关闭的(iOS把QAVMultiParam的autoRotateVideo为NO,Android设置AVRoomMulti.EnterParam.Builder.isDegreeFixed为false),那么: 41 | 42 | 1. 在腾讯云后台提交[工单](https://console.qcloud.com/workorder/category/create?level1_id=29&level2_id=37&level1_name=%E8%A7%86%E9%A2%91%E4%B8%8E%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1&level2_name=%E4%BA%92%E5%8A%A8%E7%9B%B4%E6%92%AD%20%20ILVB),问题类型选择`其他问题`,问题描述填写`添加转置白名单申请-公司名-腾讯云账号(XXXXXXX)-申请白名单的sdkappid(XXXXXXX)`; 43 | 2. 待工单处理完毕,升级AVSDK 1.8.4,并参考附录中的指南升级ios OpenGL渲染代码。 44 | 3. 做好iOS/Android互看适配工作,以及与线上版本兼容测试; 45 | 5. 待基于AVSDK 1.8.4版本的app普及后,提交[工单](https://console.qcloud.com/workorder/category/create?level1_id=29&level2_id=37&level1_name=%E8%A7%86%E9%A2%91%E4%B8%8E%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1&level2_name=%E4%BA%92%E5%8A%A8%E7%9B%B4%E6%92%AD%20%20ILVB),问题类型选择`其他问题`,问题描述填写`移除转置白名单申请-公司名-腾讯云账号(XXXXXXX)-申请白名单的sdkappid(XXXXXXX)`; 46 | 47 | 48 | 否则: 49 | 50 | 1. 升级AVSDK 1.8.4,并参考附录中的指南升级ios OpenGL渲染代码; 51 | 2. 待基于AVSDK 1.8.4版本的app普及后,提交[工单](https://console.qcloud.com/workorder/category/create?level1_id=29&level2_id=37&level1_name=%E8%A7%86%E9%A2%91%E4%B8%8E%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1&level2_name=%E4%BA%92%E5%8A%A8%E7%9B%B4%E6%92%AD%20%20ILVB),问题类型选择`其他问题`,问题描述填写`移除转置白名单申请-公司名-腾讯云账号(XXXXXXX)-申请白名单的sdkappid(XXXXXXX)`; 52 | 53 | ### 三 . 从1.8.3版本升级: 54 | 55 | 1. 在腾讯云后台提交[工单](https://console.qcloud.com/workorder/category/create?level1_id=29&level2_id=37&level1_name=%E8%A7%86%E9%A2%91%E4%B8%8E%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1&level2_name=%E4%BA%92%E5%8A%A8%E7%9B%B4%E6%92%AD%20%20ILVB),问题类型选择`其他问题`,问题描述填写`查询转置白名单申请-公司名-腾讯云账号(XXXXXXX)-申请白名单的sdkappid(XXXXXXX)`; 56 | 2. 收到工单回复后, 57 | 58 | **如果转置开关是打开的:** 59 | 60 | * 升级AVSDK 1.8.4,并参考附录中的指南升级ios OpenGL渲染代码; 61 | * 进行iOS/Android互看适配工作,以及与线上版本兼容测试; 62 | * 测试完成后,升级AVSDK 1.8.4版本到现网; 63 | 64 | **如果转置开关是关闭的:** 65 | 66 | * 进行iOS/Android互看适配工作,以及与线上版本兼容测试; 67 | * 测试完成后,升级AVSDK 1.8.4版本到现网; 68 | * 待基于AVSDK 1.8.4版本的app普及后,提交[工单](https://console.qcloud.com/workorder/category/create?level1_id=29&level2_id=37&level1_name=%E8%A7%86%E9%A2%91%E4%B8%8E%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1&level2_name=%E4%BA%92%E5%8A%A8%E7%9B%B4%E6%92%AD%20%20ILVB),问题类型选择`其他问题`,问题描述填写`移除转置白名单申请-公司名-腾讯云账号(XXXXXXX)-申请白名单的sdkappid(XXXXXXX)`; 69 | 70 | ### 四 自定义采集与渲染 71 | 72 | 自定义采集注意点: 73 | 74 | * ios调用fillExternalCaptureFrame时,SDK底层会自动补充角度值; 75 | * Android刚需要自己手动填写角度值(具体值可参考[角度方案](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/%E8%A7%92%E5%BA%A6%E6%96%B9%E6%A1%88.md))。**要保证在互通时画面方向正确,Android端首先参考[考角度方案](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/%E8%A7%92%E5%BA%A6%E6%96%B9%E6%A1%88.md)填对之后,这样SDK才不会将画面转置出错;**; 76 | * 在不开转置情况下:fillExternalCaptureFrame里填入的角度值是多少,传给观众的值就是多少; 77 | * 在开转置情况下:主播在fillExternalCaptureFrame之后,SDK还会对画面进行转置,并修改角度值为0, 然后上行视频数据包,这样传给观众的就一直是0, 观众端需要根据宽高来判断是否有横屏; 78 | 79 | 自定义渲染注意点: 80 | 81 | * 因之前的的画面都带有角度值,业务方主要是根据角度值来确定画面方向。 82 | * AVSDK1.8.4 在开转置之后,传入的方向始终为0, 那么用户需要根据画面的宽高比来确定是否为横竖屏:`宽>高为横屏`,`宽 < 高为竖屏`。用户要在之前适配好渲染逻辑的代码里面,补充好宽高比来确定是否为横竖屏逻辑。 83 | 84 | **如果只做了自定义采集,但没有自定义渲染的用户,渲染部分还是可以参考附录中的指南升级ios OpenGL渲染代码**; 85 | 86 | 在确认好以上两部分修改后,做好与老版本的兼容测试,然后升级到现网。 87 | 88 | 89 | ## 附录 OpenGL代码升级指南 90 | 91 | 1. 更新[随心播](https://github.com/zhaoyang21cn/iOS_Suixinbo)代码, 92 | 2. 参考随心播opengl代码,替换以下内容 93 | 94 | ![](https://mc.qcloudimg.com/static/img/94f24136772e38c77fe40a1968163539/mergeopengl.png) 95 | 96 | 3. 如果开发者的渲染代码已经自己修改过,那么参考2中替换项,并根据自身需要进行同步(核心逻辑在TCAVFrameDispatcher和AVGLCustomRenderView中)。 -------------------------------------------------------------------------------- /doc2/Android_ILiveSDK_BeforeHand.md: -------------------------------------------------------------------------------- 1 | ## 一 下载Demo 2 | 点击下载[Android Demo](https://github.com/zhaoyang21cn/ILiveSDK_Android_Demos)的代码。代码里包含两个示例:
3 | 4 | 1. tdemolive目录下是一个最简单的互动直播示例,演示了最关键的几个接口的调用。使用方法可以参考github上的说明。 5 | 2. 随心播代码在suixinbo目录下。演示了包括界面和后台交互的完整的直播流程。 6 | 7 | ## 二 修改配置 8 | 9 | 1. 把随心播代码中的appid和accountType修改成开发者自己的。
10 | ![](https://mc.qcloudimg.com/static/img/62890dee5794a2ce94404ba762624b94/idntype.png) 11 | 2. 注释maven.oa.com的引用,改成jcenter库地址。
12 | ![](https://mc.qcloudimg.com/static/img/8c4c9bf238499dec32aca993d9ff7ad4/respositories.png) 13 | 14 | 15 | ## 三 运行 16 | 编译运行工程,在启动界面选择随心播。 17 | 18 | * ![主界面](https://mc.qcloudimg.com/static/img/1be6185cdb0f61756c85e230a9fc0514/2.png) 19 | * ![直播界面](https://mc.qcloudimg.com/static/img/ccf7ca496a22ec0aed9d4446f30ba85f/1.png) 20 | 21 | 22 | ## 四 集成到开发者自己的代码工程里 23 | ### 1 引入SDK 24 | * **aar方式集成**,(强烈推荐)
25 | 如果你使用的Android Studio开发,那么导入iliveSDK非常简单。只需一行代码就可以搞定了 26 | 27 | compile 'com.tencent.ilivesdk:ilivesdk:X.X.X' 28 | 29 | (X.X.X 替换成对应版本号 比如0.3.7)。同步完成之后可以在build文件夹中找到ilivesdk文件夹。
30 | ![](https://mc.qcloudimg.com/static/img/ecd51eab082087cd2049a6a06a84ea76/ilivelocation.png) 31 | 32 | 33 | * **传统库类方式集成**,
34 | 在腾讯云官网[下载音视频库类](https://console.qcloud.com/avc/avSdkDownload)。需要把so文件和jar包文件分别放到对应jnilibs和libs里面。 35 | ![](https://mc.qcloudimg.com/static/img/e3cc8175676d647dd657beebb11cc2e3/1.png) 36 | ### 2 配置服务修改后台server地址 37 | 目前随心播后台主要用来维护直播房间列表。如果复用随心播客户端代码,需要修改随心播后台地址为业务方自己部署的服务器地址。
38 | 39 | | 接口| 说明 | 40 | |---------|---------| 41 | | GET_MYROOMID | 获取自己分配的房间号 | 42 | | NEW_ROOM_INFO | 创建新房间 | 43 | | STOP_ROOM | 退出房间 | 44 | | GET_LIVELIST | 获取房间列表 | 45 | | SEND_HEARTBEAT | 房间心跳 | 46 | | GET_COS_SIG | 图片上传相关 | 47 | 48 | ![](https://mc.qcloudimg.com/static/img/06919328fe28d9088170fc2a6b0f7ee9/server.png) 49 | 50 | ### 3 添加混淆配置 51 | * 混淆相关
52 | 53 | -keep class com.tencent.**{*;} 54 | -dontwarn com.tencent.** 55 | 56 | -keep class tencent.**{*;} 57 | -dontwarn tencent.** 58 | 59 | -keep class qalsdk.**{*;} 60 | -dontwarn qalsdk.** 61 | 62 | ### 4 配置service 63 | ![](https://mc.qcloudimg.com/static/img/afa18e51202e3e80232841d215d90f7b/qalservice.png) 64 | ### 5 配置权限 65 | ![](https://mc.qcloudimg.com/static/img/55db2326bef2d0270ab17e81d945da22/rights.png) 66 | ### 6 删除非armeabi架构so 67 | * 由于目前只支持armeabi架构,如果工程(或依赖库)中有多架构,需要在build.gradle中添加以下配置
(如果包含子工程子工程也要加) 68 |
69 | android{
70 |     defaultConfig{
71 |         ndk{
72 |             abiFilter 'armeabi'
73 |         }
74 |     }
75 | }
76 | 
77 | 
78 | 
79 | 
80 | 


--------------------------------------------------------------------------------
/doc2/Android_ILiveSDK_Live.md:
--------------------------------------------------------------------------------
  1 | #ILiveSDK直播基础接口简介
  2 | ##简单直播流程示例
  3 | 
  4 | ![](http://mc.qcloudimg.com/static/img/e6632b362fbc90745505823b1dc295bd/image.png)
  5 | 
  6 | 
  7 | ###1 ILiveSDK初始化
  8 | 
  9 | | 接口名|  接口描述  |
 10 | |---------|---------|
 11 | | **initSDK** | iLiveSDK的部分类的预初始化,是所有行为的第一步,告知身份appId|
 12 | 
 13 | 
 14 | | 参数类型| 说明 |
 15 | |---------|---------|
 16 | | Conext | 建议用AppcalicationContext |
 17 | | int | 传入业务方appid |
 18 | | int | 传入业务方 accounttype |
 19 | 
 20 | *示例
 21 |   
 22 | ```java 
 23 | ILiveSDK.getInstance().initSdk(getApplicationContext(), appid, accoutype);
 24 | ```  
 25 | 
 26 | 
 27 | ###2 账号登录
 28 | | 接口名|  接口描述  |
 29 | |---------|---------|
 30 | | **iLiveLogin** | 使用托管方式或独立模式,在获取到用户的sig后,使用登录接口,告知后台音视频模块上线了(包括avsdk)|
 31 | 
 32 | | 参数类型| 说明 |
 33 | |---------|---------|
 34 | | String | 用户id,在直播过程中的唯一标识  |
 35 | | String | 鉴权的密钥Sig 如果是独立登录方式,是业务方后台计算生成后下发的|
 36 | | ILiveCallBack | 帐号登录回调接口。通知上线是否成功 |
 37 | 
38 | *示例 39 | 40 | ```java 41 | ILiveLoginManager.getInstance().iLiveLogin(ILiveSDK.getInstance().getMyUserId(), "123456", new ILiveCallBack() { 42 | @Override 43 | public void onSuccess(Object data) { 44 | bLogin = true; 45 | Toast.makeText(ContactActivity.this, "login success !", Toast.LENGTH_SHORT).show(); 46 | } 47 | 48 | @Override 49 | public void onError(String module, int errCode, String errMsg) { 50 | Toast.makeText(ContactActivity.this, module + "|login fail " + errCode + " " + errMsg, Toast.LENGTH_SHORT).show(); 51 | } 52 | }); 53 | ``` 54 | ###3 创建房间 55 | 56 | | 接口名| 接口描述 | 57 | |---------|---------| 58 | | **createRoom** | 创建一个直播,只有在初始化和登录成功之后才能创建直播| 59 | 60 | | 参数类型| 说明 | 61 | |---------|---------| 62 | | int | 房间id 房间唯一标识 建议由业务方后台统一分配 | 63 | | ILiveRoomOption | 房间配置项 可以设置角色 权限 主播ID 摄像头参数等 具体参考类ILiveRoomOption | 64 | | ILiveCallBack | 创建房间回调接口。通知创建房间是否成功 | 65 | 66 | ```java 67 | //创建房间配置项 68 | ILiveRoomOption hostOption = new ILiveRoomOption(null). 69 | controlRole("Host")//角色设置 70 | .authBits(AVRoomMulti.AUTH_BITS_DEFAULT)//权限设置 71 | .cameraId(ILiveConstants.FRONT_CAMERA)//摄像头前置后置 72 | .videoRecvMode(AVRoomMulti.VIDEO_RECV_MODE_SEMI_AUTO_RECV_CAMERA_VIDEO);//是否开始半自动接收 73 | //创建房间 74 | ILiveRoomManager.getInstance().createRoom(room, hostOption, new ILiveCallBack() { 75 | @Override 76 | public void onSuccess(Object data) { 77 | Toast.makeText(LiveActivity.this, "create room ok", Toast.LENGTH_SHORT).show(); 78 | } 79 | 80 | @Override 81 | public void onError(String module, int errCode, String errMsg) { 82 | Toast.makeText(LiveActivity.this, module + "|create fail " + errMsg + " " + errMsg, Toast.LENGTH_SHORT).show(); 83 | } 84 | }); 85 | ``` 86 | ###4 加入房间 87 | | 接口名| 接口描述 | 88 | |---------|---------| 89 | | **joinRoom** | 观众角色调用加入房间接口| 90 | 91 | 92 | | 参数类型| 说明 | 93 | |---------|---------| 94 | | int | 房间id 房间唯一标识 建议由业务方后台统一分配 | 95 | | ILiveRoomOption | 房间配置项 可以设置角色 权限 主播ID 摄像头参数等 具体参考类ILiveRoomOption | 96 | | ILiveCallBack | 加入房间回调接口。通知加入房间是否成功 | 97 |
98 | 99 | ```java 100 | 101 | 102 | 103 | //加入房间配置项 104 | ILiveRoomOption memberOption = new ILiveRoomOption(hostId) 105 | .autoCamera(false) //是否自动打开摄像头 106 | .controlRole("NormalMember") //角色设置 107 | .authBits(AVRoomMulti.AUTH_BITS_JOIN_ROOM | AVRoomMulti.AUTH_BITS_RECV_AUDIO | AVRoomMulti.AUTH_BITS_RECV_CAMERA_VIDEO | AVRoomMulti.AUTH_BITS_RECV_SCREEN_VIDEO) //权限设置 108 | .videoRecvMode(AVRoomMulti.VIDEO_RECV_MODE_SEMI_AUTO_RECV_CAMERA_VIDEO) //是否开始半自动接收 109 | .autoMic(false);//是否自动打开mic 110 | //加入房间 111 | ILVLiveManager.getInstance().joinRoom(room, memberOption, new ILiveCallBack() { 112 | @Override 113 | public void onSuccess(Object data) { 114 | bEnterRoom = true; 115 | Toast.makeText(LiveActivity.this, "join room ok ", Toast.LENGTH_SHORT).show(); 116 | logoutBtn.setVisibility(View.INVISIBLE); 117 | backBtn.setVisibility(View.VISIBLE); 118 | } 119 | 120 | @Override 121 | public void onError(String module, int errCode, String errMsg) { 122 | Toast.makeText(LiveActivity.this, module + "|join fail " + errMsg + " " + errMsg, Toast.LENGTH_SHORT).show(); 123 | } 124 | }); 125 | ``` 126 | 127 | 128 | ###设置渲染层 129 | > 渲染层级示例图 在界面层xml插入一个AVRootView,音视频数据最终是通过AVRootView渲染出来。考虑多屏互动情况,AVRootView实际上不是一层View而是多层AVVideoView的叠加。直播业务默认主播在第0层默认最大,其他互动观众分别在1,2,3层。每层大小都可以动态调节。 130 | > 131 | 132 | ![](http://mc.qcloudimg.com/static/img/d063a1980cc046cafa0444df0b609d02/image.png) 133 | * 示例 134 | 135 | ```java 136 | 141 | 142 | 143 | avRootView = (AVRootView) findViewById(R.id.av_root_view); 144 | ILVLiveManager.getInstance().setAvVideoView(avRootView); 145 | ``` 146 | 147 | [信令及上麦参见](./ILVLiveSenior.md) 148 | -------------------------------------------------------------------------------- /doc2/Architecture.md: -------------------------------------------------------------------------------- 1 | ## 互动直播系统架构 2 | 腾讯视频云基于QQ多年音视频领域的积累,针对移动时代复杂多变的网络环境,精心设计了这款时延低,功能强大的互动直播产品。 3 | ### 架构说明 4 | 1. 延迟低。基于UDP或UDT的定制协议,可以在最大限度上保障低延迟; 5 | 2. 私密性好。定制协议也可以非常好地保护高价值的视频内容不被盗链侦听; 6 | 3. 扩展性强。如果需要和音视频流精密同步的自定义数据,例如实时面部识别,也可以在定制协议上进行扩展; 7 | 4. 兼容性好。对于已经有观看端的用户,或者web、H5用户,也可以采用旁路推流的方式,以通用流媒体协议为其提供服务; 8 | 5. 采用定制协议和采用通用协议的用户,信令和消息也可以实时互通; 9 | 10 | ![腾讯互动直播系统架构](https://mc.qcloudimg.com/static/img/50aafdfc8b501b497075e74b0b5f1128/1.png) 11 | 12 | ### 数据交互时序说明 13 | 1. 步骤1和2解释了独立帐号模式下,app用户完成腾讯互动直播身份认证的过程。
14 | 如果采用托管帐号模式,则不需要开发者server参与,直接调互动直播sdk login接口即可; 15 | 2. 开播、观看、上麦等音视频接口的调用必须在进房间成功之后; 16 | 3. 只要app业务逻辑允许,在调用相应的接口后,任何用户都有上麦能力; 17 | 4. 开发者后台server可以通过腾讯互动直播给app里的用户或者群组push消息。 18 | 19 | ![腾讯互动直播数据交互](https://mc.qcloudimg.com/static/img/4094feaf383cf1e3c5714bd3f9dbfc8e/hudongzhibo.png) 20 | 21 | ### 互动直播代码结构说明 22 | 1. iLive SDK封装了之前诸多SDK的接口,统一提供基础的账户、消息和音视频能力; 23 | 2. 为了方便开发者使用,我们在iLive SDK基础上,包装了互动直播常用的业务逻辑,提供了Live SDK。推荐开发者直接在Live SDK基础上进行开发; 24 | 3. 在Live SDK基础上,我们又提供了一个demo app,叫随心播。通过这个demo app,开发者可以直接体验互动直播的场景功能,也可以作为app UI开发的参考。 25 | 26 | 27 | ![腾讯互动直播代码结构](https://mc.qcloudimg.com/static/img/0e11b392263468750268184075781f23/6.png) 28 | 29 | -------------------------------------------------------------------------------- /doc2/IE_ILiveSDK_BeforeHand.md: -------------------------------------------------------------------------------- 1 | # 下载代码 2 | 3 | ## 简介 4 | 互动直播SDK for IE,下文称为ILiveSDK(IE),是互动直播在IE平台上的SDK。通过ActiveX实现了在IE上进行互动直播、上麦和基础IM的能力。 5 | 6 | ## 支持的浏览器 7 | 32位IE9,32位IE10,IE11 8 | 9 | ## 下载SDK和DEMO 10 | demo工程是基于ILiveSDK(IE)开发的互动直播应用。应用名为随心播,可以与其他终端的随心播互通。 11 | 您可以直接在这里[在线体验](https://sxb.qcloud.com/webdemo/index.html)其效果。 12 | 也可以在[github](https://github.com/zhaoyang21cn/ILiveSDK_Web_Demos)下载ILiveSDK(IE)及其demo。其中包含了ILiveSDK(IE),接口文档,js接口文件和接口调用示例等,具体如下: 13 | 14 | 15 | 文件 | 说明 | 16 | ----|------| 17 | /suixinbo | demo随心播工程,可以用IE打开index.html | 18 | iLiveSDK/iLiveSDK.cab | 互动直播组件,业务层不会直接与此文件交互 | 19 | iLiveSDK/iLiveSDK.js | 互动直播接口,封装了iLiveSDK.cab的接口供业务层调用 | 20 | /doc | 相关文档 | 21 | /tools | 开发者工具 | 22 | 23 | 24 | ## demo运行及其注意事项 25 | 运行demo可以对ILiveSDK(IE)具备的能力有个直观的印象。您可以参照如下步骤运行demo: 26 | 27 | 1. 把随心播代码中的appid和accountType修改成开发者自己的。即在demo.js中找到OnInit方法,找到`sdk = new ILiveSDK(1400027849, 11656, "iLiveSDKCom")`语句,用自己的`SDKAppID`和`accountType`替换前两个参数。如何获取这两个参数,可以参考[快速参数配置](https://www.qcloud.com/document/product/268/7599)。 28 | 2. 将[随心播后台代码](https://github.com/zhaoyang21cn/SuiXinBoPHPServer)部署到自己服务器上,并按照文档修改后台的秘钥。 29 | 2. 用IE打开index.html,并允许activeX控件,可以看到注册和登录界面。 30 | ![登录界面](http://mc.qcloudimg.com/static/img/cf9dec67f37159dc9fec9d529dcf47f1/image.png) 31 | 3. 登录成功后可以看到当前正在直播的房间列表(房间是ILiveSDK的概念,后文详述)。您也可以自己创建一个直播。![房间列表界面](http://mc.qcloudimg.com/static/img/82fcdb2dfad54efd80d3c9ed4b5c5d8a/image.png) 32 | 4. 进入一个房间,可以看到直播的视频、群消息,当前房间成员等。您可以打开摄像头进行直播,给其他房间成员发消息等。![房间](http://mc.qcloudimg.com/static/img/43f1047c1d00f70de63b9a287ff55973/image.png) 33 | 34 | ## 将iLiveSDK(IE)集成入自己的工程 35 | 集成ILiveSDK(IE)仅需使用javastript。将SDK引入工程的步骤如下: 36 | 37 | 1. 将cab文件和iLiveSDK.js放入电脑任意位置 38 | 2. 在html页面中添加` 39 | ` 40 | 3. 在html页面中添加js接口文件 41 | 4. 调用iLiveSDK中的接口实现业务需求 42 | 43 | ## SDK日志位置 44 | 日志地址:%appdata%\Tencent\iLiveSDK(在开始菜单运行中执行) 45 | -------------------------------------------------------------------------------- /doc2/IE_ILiveSDK_Interactive.md: -------------------------------------------------------------------------------- 1 | # 直播接口 2 | 3 | iLiveSDK中的音视频通讯能力被抽象为房间这个概念。在同一个房间内的成员可以看到房间内其他成员的音视频,每个房间同时最多可以有四路视频。iLiveSDK(IE)提供了房间管理,音视频设备管理等功能,方便用户建立互动视频。具体的直播业务流程如下: 4 | 5 | ![业务流程](http://mc.qcloudimg.com/static/img/e6632b362fbc90745505823b1dc295bd/image.png) 6 | 7 | ## 创建对象 8 | 创建iliveSDK对象供后续使用。 9 | 10 | ``` 11 | //iLiveSDK是cab组件的id 12 | var sdk = new ILiveSDK(sdkappid, accounttype, "iLiveSDK"); 13 | ``` 14 | 15 | ## 初始化 16 | 使用其他各项功能前必须将iLiveSDK初始化。 17 | 18 | ``` 19 | sdk.init(function () { 20 | alert("init succ"); 21 | }, function (errMsg) { 22 | alert("错误码:" + errMsg.code + " 错误信息:" + errMsg.desc); 23 | }); 24 | ``` 25 | 26 | ## 登录 27 | 用户在登录后才能使用消息通讯,互动视频等功能。登录需要填写用户id和签名。其中签名是由[腾讯登录服务](https://www.qcloud.com/document/product/269/1507)提供的。 28 | 29 | ``` 30 | sdk.login(id, sig, function () { 31 | alert("login succ"); 32 | }, function (errMsg) { 33 | alert("错误码:" + errMsg.code + " 错误信息:" + errMsg.desc); 34 | }); 35 | ``` 36 | 37 | ## 音视频权限管理 38 | 39 | **业务层需重点关注房间成员的音视频权限**。 只有主播或者需要上麦的观众才能拥有音视频上行的权限。在进入或者创建房间时需要填写正确的权限(详见下文进入房间)。另外成员允许在房间内改变自己的权限。 40 | 您可以在腾讯云[控制台配置](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/SPEARConfig.md)自身业务需要的角色及其权限,腾讯云服务器会根据房间成员不同的权限分配不同的[接入机](https://www.qcloud.com/document/product/268/7651)。错误配置权限可能导致不必要的带宽支出和观众异常上行数据等问题。 41 | 42 | 43 | 44 | ## 进入/创建房间 45 | 创建房间可以设置角色权限,房间号,房间号不能重复。 46 | 47 | ```js 48 | sdk.createRoom(roomid, "LiveMaster", function () { 49 | alert("create room succ"); 50 | }, function (errMsg) { 51 | alert("错误码:" + errMsg.code + " 错误信息:" + errMsg.desc); 52 | }); 53 | ``` 54 | 加入房间可以填写角色权限,房间号。 55 | 56 | ```js 57 | sdk.joinRoom(roomid, "Guest", function () { 58 | alert("join room succ"); 59 | }, function (errMsg) { 60 | alert("错误码:" + errMsg.code + " 错误信息:" + errMsg.desc); 61 | }); 62 | ``` 63 | 64 | ## 设备管理 65 | 66 | ### 打开摄像头 67 | 在房间中拥有上行权限的成员打开摄像头,其他房间成员就可以获取视频画面数据。没有权限的成员的上行数据会被服务器丢弃。在打开摄像头前可以先调用接口获取当前的摄像头列表。 68 | 69 | ```js 70 | var szRet = sdk.getCameraList(); 71 | if (szRet.code != 0) { 72 | alert("获取摄像头列表出错; 错误码:" + szRet.code); 73 | return; 74 | } 75 | var nRet = sdk.openCamera(szRet.cameras[0].id); 76 | if (nRet != 0) { 77 | alert("打开摄像头失败; 错误码:" + nRet); 78 | } 79 | ``` 80 | ### 关闭摄像头 81 | 需要停止视频时,需要关闭摄像头。 82 | 83 | ```js 84 | var nRet = sdk.closeCamera(); 85 | ``` 86 | ### 打开麦克风 87 | 88 | ```js 89 | var nRet = sdk.openMic(); 90 | ``` 91 | ### 关闭麦克风 92 | 93 | ```js 94 | var nRet = sdk.closeMic(); 95 | ``` 96 | ## 视频渲染 97 | 收到每个用户的视频数据后,需要使用渲染控件来渲染收到的视频 98 | 99 | ```js 100 | render.setIdentifer( userid ); //渲染控件设置了用户id后,收到此用户的视频数据,将会自动渲染 101 | ``` 102 | 用户的视频数据停止后,需要对渲染控件进行释放 103 | 104 | ```js 105 | render.freeRender(); 106 | ``` 107 | 108 | ## 美颜 109 | 设置美颜程度 0~10 110 | 111 | ```JS 112 | sdk.setBeauty(beauty); 113 | ``` 114 | 115 | 设置美白程度 0~10 116 | 117 | ```JS 118 | sdk.setWhite(white); 119 | ``` 120 | 121 | 销毁美颜滤镜资源;如果开启了美颜功能,在 相机关闭 时,调用即可 122 | 123 | ```JS 124 | sdk.destroyFilter(); 125 | ``` 126 | 127 | 说明: 128 | 1. sdk默认关闭美颜 129 | 2. 美颜 和 美白程度都设置为0,sdk自动关闭美颜功能;其中一项不为0,sdk打开美颜功能 130 | 3. sdk.destroyFilter 接口建议在关闭相机后调用 131 | 132 | 133 | 134 | 135 | 136 | ## 退出房间 137 | 退出房间并回收资源 138 | 139 | ```js 140 | sdk.quitRoom(function () { 141 | alert("quit room succ"); 142 | }, function (errMsg) { 143 | alert("错误码:" + errMsg.code + " 错误信息:" + errMsg.desc); 144 | }); 145 | ``` 146 | 147 | 148 | 149 | 150 | ## 登出 151 | 登录的逆操作 152 | 153 | ``` 154 | sdk.logout(function () { 155 | alert("logout succ"); 156 | }, function (errMsg) { 157 | alert("错误码:" + errMsg.code + " 错误信息:" + errMsg.desc); 158 | }); 159 | ``` 160 | 161 | ## 在线状态 162 | 用户登录后是有在线状态的,每个账号同时只能在一个终端登录。在其他终端登录时将会把当前终端的登录踢下线,当前终端会收到被踢下线通知。 163 | sdk允许设置踢下线通知的监听,业务层收到通知后可以在上层处理登录态的变化。 164 | ``` 165 | sdk.setForceOfflineListener(function() { 166 | alert("您已被踢下线,请重新登录"); 167 | }); 168 | ``` 169 | -------------------------------------------------------------------------------- /doc2/IE_ILiveSDK_Live.md: -------------------------------------------------------------------------------- 1 | # 互动消息 2 | 3 | iLiveSDK(IE)提供了消息通讯的功能。基于消息通讯可以实现房间内成员的群消息,两个用户之间的C2C消息(不用加好友)。当前SDK只支持发文本消息和自定义消息。 4 | 5 | ## 发群消息 6 | 当前仅支持给当前所在房间发群消息,房间内其他成员都会收到改消息。 7 | 8 | ```JS 9 | //ILiveMessageElem, ILiveMessage的参数说明详见接口文档 10 | var elem = new ILiveMessageElem(0, "message content"); 11 | var elems = []; 12 | elems.push(elem); 13 | var message = new ILiveMessage(elems); 14 | sdk.sendGroupMessage(message, function () { 15 | alert("send message succ"); 16 | }, function (errMsg) { 17 | alert("错误码:" + errMsg.code + " 错误信息:" + errMsg.desc); 18 | }); 19 | ``` 20 | 21 | ## 接收群消息 22 | 设置群消息监听后可以收到群消息,群消息可以在初始化后设置。 23 | 24 | ```JS 25 | sdk.setGroupListener(function (msg) { 26 | //msg的定义详见接口文档 27 | }) 28 | ``` 29 | 30 | ## 发C2C消息 31 | C2C消息指的是两个用户之间的点对点聊天消息。邀请房间成员上麦等消息可以在业务层通过C2C自定义消息实现。具体的实现可以参考demo。 32 | 33 | ```JS 34 | //ILiveMessageElem, ILiveMessage的参数说明详见接口文档 35 | var elem = new ILiveMessageElem(0, "message content"); 36 | var elems = []; 37 | elems.push(elem); 38 | var message = new ILiveMessage(elems); 39 | sdk.sendC2CMessage("somebody", message, function () { 40 | alert("send message succ"); 41 | }, function (errMsg) { 42 | alert("错误码:" + errMsg.code + " 错误信息:" + errMsg.desc); 43 | }); 44 | ``` 45 | 46 | ## 接收C2C消息 47 | 设置C2C消息监听后可以收到C2C消息,C2C消息可以在初始化后设置。 48 | 49 | ```JS 50 | sdk.setC2CListener(function (msg) { 51 | //msg的定义详见接口文档 52 | }) 53 | ``` 54 | 55 | 56 | ## 连麦互动 57 | 上麦行为主要通过修改音视频权限达到。其中上麦流程是 58 | 59 | > 切换角色 --> 打开摄像头 -->渲染画面 60 | 61 | 下麦流程是 62 | 63 | > 切换角色 --> 关闭摄像头 -->结束渲染 64 | 65 | 您可以在控制台[配置场景和角色](https://www.qcloud.com/document/product/268/7599),然后调用接口切换角色: 66 | 67 | ```js 68 | //其中liveMaster是控制台配置的角色 69 | sdk.changeRole("LiveMaster"); 70 | ``` 71 | -------------------------------------------------------------------------------- /doc2/Introduction.md: -------------------------------------------------------------------------------- 1 | ### 互动直播是什么 2 | 互动直播 (Interactive Live Video Broadcasting),顾名思义,就是有音频、视频、消息等互动能力的直播。
3 | 如果说普通直播就象一个电视台,把节目信号发射出去供电视机前的观众观看。
4 | 那么互动直播就像春晚的舞台,有演员,有观众,演员和观众还可以互动。当然就象春晚一样,可以进行录像和实时转播给电视台,供电视机前的观众观看。
5 | 互动直播房间可支持8路音视频同时播放,同一房间最高支持100万人并发,非常适合大规模秀场直播、视频社交、在线教育、远程咨询、多机位在线媒体转播等应用领域 6 | ![直播和互动直播的比较](https://mccdn.qcloud.com/static/img/684a6a66a62cb830c9cfb29848987210/image.png) 7 | 8 | ### 互动直播的能力列表 9 | 10 | | 名称|说明 | 典型场景| 11 | | ------------- |:-------------:| :-----:| 12 | | **多路音视频** | 多路音视频,多人同房间互相音视频通话 | 主播邀请观众上麦互动,多主播远程辩论,嘉宾评论等等| 13 | | **云通信** | IM功能| 群聊消息、送礼、红包等功能| 14 | | **录制** | 将互动直播房间内的表演录制成视频文件 | 重大活动回放 | 15 | | **推流** | 将视频信号推送给别的直播观众 | 直播分享 | 16 | | **录屏** | 将手机屏幕上的内容录制下来并推流出去 | 游戏、远程辅助等等 | 17 | | **合流** | 将主播的视频叠加在第三方的视频流上一起播放 | 游戏、体育解说 | 18 | | **屏幕分享** | 户把屏幕指定区域动态展示给同房间用户 | 远程教学,金融证券展示走势图 | 19 | | **美颜** |美颜 降噪、磨皮、美白 | 秀场类大型直播、可视通信 | 20 | | **人脸识别** | 识别采集到的人脸画面以及五官位置 | 人像定位,人像二次处理 | 21 | | **变脸** | 对视频中的人脸进行变化处理 | 视频变脸 | 22 | | **混音** | 在主播的视频中叠加背景音 | mv播放,动态特效 | 23 | | **鉴黄** | 从云端对直播画面进行截帧、存储和自动画图鉴别 | 大型秀场类直播内容审核 | 24 | | **水印** | 添加logo图片到互动直播画面 | 应对政策、内容和品牌推广| 25 | 26 | ### 主要音视频参数 27 | 28 | | 名称|说明 | 29 | | ------------- |:-------------:| 30 | |最多同时音视频 |8路| 31 | |同房间最多观众数|100万| 32 | |视频分辨率|320×240, 480×360,640×368,640×480,960×540,1280×720| 33 | |图像编码码率范围| 30~1500kbps| 34 | |延迟范围|150~400ms| 35 | |抗丢包率|30%| 36 | |音频采样率|8000,16000,48000| 37 | |房间进入速度|WIFI:950ms, 4G:1504ms| 38 | 39 | 40 | 41 | ##### 以上功能和指标是为了满足大多数用户,如果您有特殊指标和功能需求,欢迎定制。 42 | -------------------------------------------------------------------------------- /doc2/Mac_ILiveSDK_BeforeHand.md: -------------------------------------------------------------------------------- 1 | ## 一 下载Demo 2 | 点击下载[Mac Demo](https://github.com/zhaoyang21cn/iLiveSDK_Mac_Suixinbo)的代码。演示了包含界面和后台交互的完整直播流程:
3 | 4 | ## 二 解压SDK压缩包 5 | 6 | 由于Github上有100MB文件上传限制,所以随心播工程中将QAVSDK压缩后再上传,要使随心播正常运行,请开发人员解压iLiveSDK_Mac_Suixinbo/SuixinboForMac/FrameworksMac/AVSDK.zip 到当前目录,解压后目录如下图所示: 7 | 8 | ![](http://mc.qcloudimg.com/static/img/e70b619d7c575b395680c4242f528f4f/image.png) 9 | 10 | ## 三 运行 11 | 12 | 1、直接运行安装包(下载的Demo工程中,SuiXinBoForMac.dmg可以直接运行) 13 | 14 | 2、编译源码运行工程。(最低支持MacOS 10.7) 15 | 16 | 效果图如下: 17 | 18 | *
19 | 20 | 21 | *
22 | 23 | 24 | ## 四 集成到开发者自己的代码工程里 25 | ### 1 引入SDK并导入项目 26 | 27 | 参照以上 第二步,并将FrameworksMac中的所有SDK添加到自己的工程中 28 | 29 | ### 2 修改工程配置 30 | 将下载好的SDK复制到工程目录下,工程目录右键,Add Files to " you projectname",在demo中如下图所示: 31 | 32 | 1. Build Settings/Linking/Other Linker Flags,增加 -ObjC 配置,如下图所示: 33 | ![](http://mc.qcloudimg.com/static/img/9e48e62964428b6b12e11c262ff29178/image.png) 34 | 35 | 2.设置最低版本大于或等10.7,Build Settings -> macOS Deployment Target -> macOS 10.7,如下图所示: 36 | 37 | ![](http://mc.qcloudimg.com/static/img/592954bf985115b7089147800a3667c8/image.png) 38 | 39 | 若上述步骤均无误,则工程编译可以通过了。 40 | 41 | ### 3 添加系统库 42 | 添加以下系统库比较方便的方法是直接从随心播工程中,将SystemLibrarys组拖到自己的工程目录下 43 | 44 | | 需要增加的系统库 | 45 | |------------| 46 | |QuartzCore.framework| 47 | |CoreTelephony.framework| 48 | |CoreWLAN.framework| 49 | |Foundation.framework| 50 | |SystemConfiguration.framework| 51 | |libc++.tbd| 52 | |libiconv.tbd| 53 | |libresolv.9.tbd| 54 | |libsqlite3.tbd| 55 | |libstdc++.6.tbd| 56 | |libz.tbd| 57 | 58 | ## 4 添加腾讯相关依赖库 59 | 60 | |序号|名称|所在文件夹|说明|是否必须| 61 | |--|--|--|--|--| 62 | |1|QAVSDK.framework|FrameworksMac/AVSDK/|音视频SDK|必须| 63 | |2|xplatform.framework|FrameworksMac/AVSDK/|音视频跨平台支持库|必须| 64 | |3|IMCore.framework|FrameworksMac/IMSDK/|即时通讯核心库|必须| 65 | |4|ImSDK.framework|FrameworksMac/IMSDK/|即时通讯Mac平台封装库|必须| 66 | |5|QALSDK.framework|FrameworksMac/IMSDK/|即时通讯网络模块SDK|必须| 67 | |6|TLSSDK.framework|FrameworksMac/IMSDK/|即时通讯登录服务SDK|必须| 68 | |7|ILiveSDK.framework|FrameworksMac/|互动直播基础功能SDK|必须| 69 | |8|TILFilterSDK.framework|FrameworksMac/|互动直播美颜依赖库|非必须| 70 | 71 | -------------------------------------------------------------------------------- /doc2/Mac_ILiveSDK_Interactive.md: -------------------------------------------------------------------------------- 1 | # 互动消息和上麦 2 | 3 | ### 准备 4 | 无论是发送消息还是上麦,都需要在创建或进入房间前设置事件和消息监听。示例: 5 | ``` 6 | //添加im消息监听 7 | //用addMessageListener添加的监听对象,在对象销毁时,必须要调用removeMessageListener,否则会添加多个消息监听,导致收到多个消息的情况 8 | [[[ILiveSDK getInstance] getTIMManager] addMessageListener:self]; 9 | ``` 10 | 11 | ### 1 发送消息 12 | 13 | |接口名|接口描述| 14 | |---|---| 15 | |sendC2CMessage:message:succ:fail:|发送C2C消息| 16 | |sendOnlineC2CMessage: succ: failed:|发送C2C在线消息| 17 | |sendGroupMessage: succ: failed:|发送Group消息| 18 | |sendOnlineGroupMessage: succ: failed:|发送Group在线消息| 19 | 20 | **普通消息和在线消息的区别:** 21 | 22 | 1、发送普通消息,接收方一定能接收到(如果接收方不在线,则下次登录时会再次接收到) 23 | 24 | 2、发送在线消息,接收方在线,则能收到消息,如果不在线,则收到消息,且以后登录也无法收到消息 25 | 26 | 以上接口的调用发发类似,下面是发送“群在线消息”的示例代码: 27 | 28 | ``` 29 | //1、发送消息 30 | TIMTextElem *elem = [[TIMTextElem alloc] init]; 31 | elem.text = @"msg text"; 32 | 33 | TIMMessage *msg = [[TIMMessage alloc] init]; 34 | [msg addElem:elem]; 35 | 36 | __weak typeof(self) ws = self; 37 | [[ILiveRoomManager getInstance] sendOnlineGroupMessage:msg succ:^{ 38 | NSLog(@"send msg succ"); 39 | } failed:^(NSString *module, int errId, NSString *errMsg) { 40 | NSLog(@"send msg fail.M=%@,errId=%d,errMsg=%@",module,errId,errMsg); 41 | }]; 42 | ``` 43 | 44 | ``` 45 | // 2. 消息接收(所有的IM消息都在onNewMessage:中回调) 46 | - (void)onNewMessage:(NSArray *)msgs 47 | { 48 | //如果没有addMessageListener添加监听对象,则不会收到onNewMessage回调 49 | NSLog(@"收到消息,在这里解析消息,详细解析步骤,可参考demo程序"); 50 | } 51 | ``` 52 | 53 | ### 2 上麦 54 | #### 2.1 主播邀请上麦流程图: 55 | ![](http://mc.qcloudimg.com/static/img/ccbafe376da2e175ff41bd681856581e/image.png) 56 | ------ 57 | #### 2.2 观众请求上麦流程图: 58 | ![](http://mc.qcloudimg.com/static/img/4d21a6ce428740fa16ebc58a0675b3e7/image.png) 59 | ------ 60 | #### 2.3 接口 61 | 62 | ** 注:控制信令全部是通过发送自定义消息实现 ** 63 | 64 | ##### 2.3.1 邀请上麦 65 | 66 | ``` 67 | //消息组装 68 | NSString *dataStr = @""; 69 | NSError *error; 70 | //自定定义消息的data是键-值对,在demo中以kMsgCmdKey作为命令字的key,kMsgDataKey作为其他参数的key 71 | //命令字是用户自己定义的,只需要用的app中统一即可 72 | NSDictionary *sendDic = [NSDictionary dictionaryWithObjectsAndKeys:@(AVIMCMD_Multi_Host_Invite), kMsgCmdKey, dataStr, kMsgDataKey,nil]; 73 | NSData *sendData = [NSJSONSerialization dataWithJSONObject:sendDic options:NSJSONWritingPrettyPrinted error:&error]; 74 | if(error != nil){ 75 | NSLog(@"serialization msg fail"); 76 | return; 77 | } 78 | TIMCustomElem *imCustomElem = [[TIMCustomElem alloc] init]; 79 | [imCustomElem setData:sendData]; 80 | TIMMessage *imMessage = [[TIMMessage alloc] init]; 81 | [imMessage addElem:imCustomElem]; 82 | __weak typeof(self) ws = self; 83 | 84 | [[ILiveRoomManager getInstance] sendOnlineC2CMessage:recvId message:imMessage succ:^{ 85 | NSLog(@"发送连麦消息邀请成功"); 86 | } failed:^(NSString *module, int errId, NSString *errMsg) { 87 | NSLog(@"发送连麦邀请失败,M=%@,code=%d,Msg=%@",module,errId,errMsg); 88 | }]; 89 | ``` 90 | ##### 2.3.2 上麦接口 91 | 92 | ``` 93 | - (void)onNewMessage:(NSArray *)msgs 94 | { 95 | //收到消息,解析,判断是否为邀请上麦消息,如果是做上麦操作,解析方法详见demo 96 | ... 97 | //上麦步骤:修改角色->打开相机->打开Mic 98 | __weak typeof(self) ws = self; 99 | ILiveRoomManager *manager = [ILiveRoomManager getInstance]; 100 | //kSxbRole_InteractHD是demo的角色名,开发者需要改成自己的appid在控制台配置的角色名 101 | [manager changeRole:kSxbRole_InteractHD succ:^ { 102 | NSLog(@"上麦:改变角色成功"); 103 | [manager enableCamera:CameraPosFront enable:YES succ:^{ 104 | NSLog(@"上麦:打开摄像头成功"); 105 | [manager enableMic:YES succ:^{ 106 | NSLog(@"上麦:打开麦克风成功"); 107 | NSLog(@"上麦:上麦成功"); 108 | } failed:^(NSString *module, int errId, NSString *errMsg) { 109 | NSLog(@"上麦:打开麦克风失败,M=%@,code=%d,Msg=%@",module,errId,errMsg); 110 | }]; 111 | } failed:^(NSString *module, int errId, NSString *errMsg) { 112 | NSLog(@"上麦:打开摄像头失败,M=%@,code=%d,Msg=%@",module,errId,errMsg); 113 | }]; 114 | } failed:^(NSString *module, int errId, NSString *errMsg) { 115 | NSLog(@"上麦:切换角色失败,M=%@,code=%d,Msg=%@",module,errId,errMsg); 116 | }]; 117 | } 118 | ``` 119 | ##### 2.3.3 设置上麦者渲染画面的区域接口 120 | 121 | |接口名|接口描述| 122 | |---|---| 123 | |addRenderAt:forIdentifier:srcType:|添加渲染界面的区域,以及设置渲染视图对应的key(通常使用渲染视图对应用户的id)| 124 | 125 | |参数类型|参数名|说明| 126 | |---|---|---| 127 | |CGRect|rect|视图渲染区域| 128 | |NSString|forIdentifier|视图对应的key,用作业务逻辑,通常使用画面对应的用户id| 129 | |avVideoSrcType|srcType|视频源类型| 130 | 131 | ``` 132 | - (BOOL)onEndpointsUpdateInfo:(QAVUpdateEvent)event updateList:(NSArray *)endpoints 133 | { 134 | TILLiveManager *manager = [TILLiveManager getInstance]; 135 | switch (event) 136 | { 137 | case ILVLIVE_AVEVENT_CAMERA_ON: 138 | { 139 | for (NSString *user in users) 140 | { 141 | //user:事件对应的用户id 142 | ILiveFrameDispatcher *frameDispatcher = [[ILiveRoomManager getInstance] getFrameDispatcher]; 143 | ILiveRenderViewForMac *view = [frameDispatcher addRenderAt:NSMakeRect(0, 0, 640, 480) forIdentifier:user srcType:QAVVIDEO_SRC_TYPE_CAMERA]; 144 | [self.window.contentView addSubview:view]; 145 | } 146 | } 147 | break; 148 | } 149 | return YES; 150 | } 151 | ``` 152 | 若上述步骤均无误,则可以实现主播邀请观众连麦,观众成功上麦,直播间中出现多路画面(主播和互动观众的)。 153 | -------------------------------------------------------------------------------- /doc2/Mac_ILiveSDK_Live.md: -------------------------------------------------------------------------------- 1 | # ILiveSDK直播流程图: 2 | 3 | ![](http://mc.qcloudimg.com/static/img/06d2fb5027be53492249d4b81bd2f5a5/image.png) 4 | 5 | 6 | # 1 初始化ILiveSDK 7 | 在应用启动时初始化ILiveSDK。 8 | 9 | |接口名|接口描述| 10 | |---|---| 11 | |initSdk: accountType:|ILiveSDK内部类初始化,告知AppId。内部包含了IMSDK的初始化| 12 | 13 | |参数类型|参数名|说明| 14 | |---|---|---| 15 | |int|appId|传入业务方appid| 16 | |int|accountType|传入业务方 accountType| 17 | 18 | *示例: 19 | ``` 20 | [[ILiveSDK getInstance] initSdk:SuixinboSdkAppId accountType:SuixinboAccountType]; 21 | ``` 22 | 23 | # 2 帐号登录 24 | 25 | 用户帐号系统由用户自己的服务器维护。需要用户自己的业务后台生成Sig,客户端拿到这个Sig再登录腾讯云后台。[详情](https://www.qcloud.com/doc/product/269/1508) 26 | 27 | |接口名|接口描述| 28 | |---|---| 29 | |iLiveLogin: sig: succ: failed:|独立模式登录到腾讯云后台| 30 | 31 | |参数类型|参数名|说明| 32 | |---|---|---| 33 | |NSString|uid|用户在独立模式下注册的帐号| 34 | |NSString|sig|用户在业务方后台获取到的签名| 35 | |TCIVoidBlock|succ|登录成功回调| 36 | |TCIErrorBlock|failed|登录失败回调| 37 | 38 | *示例: 39 | ``` 40 | [[ILiveLoginManager getInstance] iLiveLogin:@"这里是帐号id" sig:@"这里是签名字符串" succ:^{ 41 | NSLog(@"登录成功"); 42 | } failed:^(NSString *moudle, int errId, NSString *errMsg) { 43 | NSLog(@"登录失败"); 44 | }]; 45 | ``` 46 | 47 | # 3 创建房间(进入房间) 48 | 49 | ## 3.1 主播创建房间 50 | 51 | |接口名|接口描述| 52 | |---|---| 53 | |createRoom: option: succ: failed:|主播创建直播间,自动渲染本地画面,开始直播| 54 | 55 | |参数类型|参数名|说明| 56 | |---|---|---| 57 | |int|roomId|房间号。业务方后台生成的房间号,需保证唯一性| 58 | |ILiveRoomOption|option|主播创建房间时的配置项,使用defaultHostLiveOption接口获取主播默认配置即可| 59 | |TCIVoidBlock|succ|创建房间成功回调| 60 | |TCIErrorBlock|failed|创建房间失败回调| 61 | 62 | *示例: 63 | ``` 64 | //如果使用美颜sdk,需要设置本地画面代理,详情参考LiveWindowController+Beauty.m中的实现 65 | //[[ILiveRoomManager getInstance] setLocalVideoDelegate:self]; 66 | 67 | //开发者可以详细了解下option的各个参数配置,这很重要 68 | ILiveRoomOption *option = [ILiveRoomOption defaultHostLiveOption]; 69 | option.controlRole = @"user"; //这里填写开发者自己的账号系统下的角色名 70 | option.roomDisconnectListener = self; //房间失去连接的回调通知 71 | option.memberStatusListener = self; //房间内用户的事件回调 72 | __weak typeof(self) ws = self; 73 | [[ILiveRoomManager getInstance] createRoom:(int)_item.info.roomnum option:option succ:^{ 74 | NSLog(@"创建房间成功"); 75 |    //如果要设置麦克风音量,则需要设置下面两个代理,详细实现参照demo的LiveWindowController+Audio.m文件 76 |    [[[ILiveSDK getInstance] getAVContext].audioCtrl registerAudioDataCallback:QAVAudioDataSource_VoiceDispose]; 77 | [[[ILiveSDK getInstance] getAVContext].audioCtrl registerAudioDataCallback:QAVAudioDataSource_NetStream]; 78 | } failed:^(NSString *module, int errId, NSString *errMsg) { 79 | NSLog(@"创建房间失败,module=%@,code=%d,msg=%@",module,errId,errMsg); 80 | }]; 81 | ``` 82 | 83 | ## 3.2 观众进入房间 84 | 85 | |接口名|接口描述| 86 | |---|---| 87 | |joinRoom: option: succ: failed:|观众进入直播间,自动拉去远程画面并渲染,开始观看直播| 88 | 89 | |参数类型|参数名|说明| 90 | |---|---|---| 91 | |int|roomId|房间号。业务方后台生成的房间号,需保证唯一性| 92 | |ILiveRoomOption|option|观众进入房间时的配置项,使用defaultGuestLiveOption接口获取观众默认配置即可| 93 | |TCIVoidBlock|succ|进入房间成功回调| 94 | |TCIErrorBlock|failed|进入房间失败回调| 95 | 96 | *示例: 97 | ``` 98 | //参数意义见创建房间 99 | //用户成功加入房间后,如果打开摄像头,则会收到onEndpointsUpdateInfo回调,在onEndpointsUpdateInfo回调中,添加上渲染视图即可 100 | ILiveRoomOption *option = [ILiveRoomOption defaultGuestLiveOption]; 101 | option.controlRole = _item.info.roleName; 102 | option.memberStatusListener = self; 103 | [[ILiveRoomManager getInstance] joinRoom:(int)_item.info.roomnum option:option succ:^{ 104 | NSLog(@"加入房间成功"); 105 | } failed:^(NSString *module, int errId, NSString *errMsg) { 106 | NSLog(@"加入房间失败.M=%@,errId=%d,errMsg=%@",module,errId,errMsg); 107 | }]; 108 | ``` 109 | 110 | 若以上步骤均无误,则主播开始直播,观众观看直播的整个流程就结束了。 111 | -------------------------------------------------------------------------------- /doc2/avmonitor.md: -------------------------------------------------------------------------------- 1 | # AV_Monitor功能和使用介绍 2 | 3 | ## 内容提要 4 | 5 | AV\_Monitor是帮助用户定位排除网络问题的实时监控工具。地址是[http://avq.avc.qcloud.com/monitor.html](http://avq.avc.qcloud.com/monitor.html)。 6 | 7 | ## 基本功能 8 | 9 | ![基本界面](https://mc.qcloudimg.com/static/img/3be70ac5c099785144a2209e5b8ada2d/1.jpg) 10 | 11 | 界面最上方是查询条件录入文本框,SdkAppid、账号(Identifier)、查询时间段,都是必填项目。界面左边竖排的两个文本框,主要用于显示某些上报具体的取值,方便开发同事定位问题。例如,在下图中点击进入房间的红色点就可以在左侧文本框里看到一些基本信息,如CPU、操作系统、网络类型、机型、SDK版本等 12 | ![基本界面](https://mc.qcloudimg.com/static/img/8a46acbbfb69ab95dc75622c2442ef6e/2.jpg) 13 | 14 | 同样是这张图,在曲线上方显示地列出了所查询用户的一些常用的基本信息,其中需要关注以下几项: 15 | 16 | * Tinyid,即基本信息左侧最下面的uin:xxxxxx,这个有时候开发查问题需要用 17 | * 是否代理机,在DC上的用户,这里显示“否”;在OC上的用户,这里显示“是” 18 | * 传输协议,通常主播类型都是UDT 19 | * 客户端IP,可以看到用户侧的省份运营商 20 | * 接口机IP,可以查看分配的接入机IP和客户端是否匹配,但目前只能显示内网IP,需要腾讯开发在内部网站tnm2.oa.com查询 21 | 22 | 最后,上图中最右边的图表目录是各种曲线图表的快捷入口,点击即达想要的位置 23 | 24 | ## 下行质量监控图表 25 | 26 | 顾名思义,主要用于展示观众端的各种动作和状态,下面注意列举各图表展示的内容和使用场景 27 | 28 | ### 下行总丢包率 29 | 30 | ![基本界面](https://mc.qcloudimg.com/static/img/6e591a59fbce40ae67288180221363d6/3.jpg) 31 | 32 | * 丢包率曲线 33 | 最下面的紫色曲线是丢包率曲线,每2s一个点,反应的是用户当前的网络状况。高丢包率会导致音视频卡顿,而出现高丢包通常说明用户可能网络质量较差。例如,上图中丢包率曲线显示,在用户开播的时候有短时的丢包情况,而其他时间丢包率为0,说明其整体网络状况良好 34 | 35 | * 红色点 36 | 红色点代表用户一次进房间的动作。红点是可以用鼠标点的,点了之后图表上方的基本信息和左侧的文本框里会刷新出该用户这次进房间时所携带的基本信息 37 | 38 | * 蓝色点 39 | 蓝色点代表用户一次退出房间的动作。由于用户可能不退出房间直接杀进程,所以蓝色点可能会比真实情况晚90s(后台的超时时间)。鼠标放在蓝色点上会弹出提示信息,可以看到是正常退出还是超时退出 40 | 41 | * 黄色点 42 | 黄色点是说明用户在使用过程中IP发生了改变,极有可能发生了网络切换但又没退出房间 43 | 44 | ### 下行总码率 45 | 46 | ![基本界面](https://mc.qcloudimg.com/static/img/b9ff74ce4eebc604bc4cc29efbbcd8b0/4.jpg) 47 | 48 | 下行总码率=下行视频码率+下行音频码率(包含各自的FEC)。点击下行总码率的任意一个点,都可以得到主播的TinyID,而通过这个TinyID就可以查看主播的状态信息,不用再去找业务开发要主播ID了,事实证明这个功能非常的有用 49 | 50 | ### 下行音频码率 51 | 52 | 顾名思义,需要注意的是,由于音频最高会有100%的FEC,网络不好的时候和平时码率可能会相差1一倍 53 | 54 | #### 其他下行图标 55 | 56 | * 下行大画面总帧率,顾名思义 57 | * 下行大画面总帧率,顾名思义,帧率越低,画面越不流畅 58 | * 下行辅路总帧率/总码率,屏幕分享的帧率码率 59 | 60 | ## 上行质量监控图表 61 | 62 | ### 上行总丢包率 63 | 64 | ![基本界面](https://mc.qcloudimg.com/static/img/ffabf311e59c99646782dc4d1411997f/5.jpg) 65 | 66 | 与下行丢包率视图相比,这里只多了一个粉色点,代表获取/清除视频位。这是主播独有的动作,即开播前需要向后台申请视频位成功,后台才会将该主播的视频流转给观众。若该主播30s内没有任何视频数据上行,那么后台将会清理视频位;如果主播后来仍要上行视频流,则需要重新申请视频位。 67 | 68 | ### 时延(ms) 69 | 70 | ![基本界面](https://mc.qcloudimg.com/static/img/f32e79a8a9e6395ddc21641a03193478/6.jpg) 71 | 72 | 时延,是指客户端到接口机Hello包的RTT。通常网络变差时延时就会变大,造成视频卡顿。需要注意的是,有时候CPU高也会引起延时变大,这是由于CPU高占用使得Hello包的处理进程无法正常处理回包导致的 73 | 74 | ## 其他监控图表 75 | 76 | ![基本界面](https://mc.qcloudimg.com/static/img/cec6522e4e762f480350ea0b82e8022f/7.jpg) 77 | 78 | 应用的CPU使用率是指SDK的CPU占用情况,设备的CPU使用率是指App整体占用情况。需要注意的是,最近iPhone遇到某些场景下CPU降频导致CPU整体占用过高的问题,需要具体情况具体分析 79 | 80 | 81 | # 互动直播音视频后台Q&A 82 | 83 | ## 关于“房间”的认知 84 | 85 | 对于互动直播音视频后台而言,房间主要用于实现用户群体的隔离,用户在不同的房间可以看到不同主播的视频流,这个和现实中秀场的概念是想通的。房间是用`房间ID`标识的,类型为32位整形数字,由**_业务方生成和管理_**,不同的房间应该使用不同的`房间ID`。 86 | 87 | 注意,音视频的`房间ID`与IM群组ID是没有任何关联的,但通常业务在使用过程中其实是将*音视频房间*和*IM群组*做了一一对应的,即可以用IM群组ID作为音视频`房间ID`或在二者之间建立映射,这个都是业务方自己根据实际需要来决策 88 | -------------------------------------------------------------------------------- /doc2/breakEvent.md: -------------------------------------------------------------------------------- 1 | ## 直播中断事件的处理 2 | 在直播过程中,经常会遇到突发事件导致直播被中断。这里列举一些常见事件的处理方式供开发者参考: 3 | >* 来电话 4 | >* 音频中断 5 | >* 切后台 6 | >* 锁屏 7 | >* 断网 8 | >* crash 9 | >* 被踢 10 | 11 | ### 一、来电话 12 | 无需做任何处理 13 | 14 | 来电话时,来电界面会覆盖当前直播界面,参考切后台处理 15 | 16 | ### 二、音频中断 17 | 无需做任何处理 18 | 19 | 发产生音频中断(如闹钟事件)时,分两种情况: 20 | 21 | >* 无新界面,不影响当前播放(录制)视频及语音 22 | >* 有新界面,参考切后台处理 23 | 24 | ### 三、切后台 25 | #### Android 26 | Android应用在切后台时,ILiveSDK中为用户提供了三种模式: 27 | 28 | 模式名称|模式说明 29 | :--|:--: 30 | VIDEOMODE_BSUPPORT|支持后台模式,应用切到后台时依然默默地播放(录制)视频和语音 31 | VIDEOMODE_NORMAL|普通模式(*默认*),应用切到后台时,暂停播放(录制)视频和语音,回到前台时恢复 32 | VIDEOMODE_BMUTE|后台静默模式,应用切到后台,关闭所有音视频上下行数据,回到前台时恢复 33 | 34 | #### iOS 35 | iOS分两种情况: 36 | >* 界面被覆盖,此时会暂停播放(录制)视频和语音,回到前面时恢复 37 | >* 切到后台,短时间只会暂停(同上),长时间会被回收(系统机制) 38 | 39 | *PS: 在直播房间时,如果90秒无上行数据,音视频房间会被后台收回* 40 | 41 | ### 四、锁屏 42 | #### Android 43 | 同切后台,用户可以在应用中自行设置保活模式,避免锁屏 44 | #### iOS 45 | ILiveSDK内部设置保活模式,不会锁屏(进入房间保活,退出房间不保活) 46 | 47 | ### 五、断网 48 | 在网络中断时,SDK内部会尝试重连,用户可自行监控系统网络状态 49 | 50 | 如需了解SDK内部网络状态,可参考[ILiveQualityData](https://github.com/zhaoyang21cn/ILiveSDK_Android_Demos/blob/master/doc/ILiveSDK/quality.md) 51 | 52 | 如房间超过90秒没有上行数据,音视频房间会被回收,会上抛onRoomDisconnect事件 53 | 54 | ### 六、app crash 55 | ILiveSDK内置了[bugly上报](https://bugly.qq.com/v2/),可以方便用户迅速定位到问题。 56 | 57 | 同时用户只需记录当前直播房间(roomid)及直播状态,在应用重启后,可以回到原直播房间,恢复直播。如时间较短(*未超过90秒*),观众端只会感到画面卡顿(*此时可以根据相应事件做出友好提示*) 58 | 59 | 用户可以在监听onEndpointsUpdateInfo事件中的关摄像头事件做出友好提示。 60 | 61 | 62 | ### 七、被踢 63 | 多终端登录时,会收到被踢事件,此时建议用户重新登陆(如果恢复需自己记录状态) 64 | 65 | #### Android 66 | 可以在ILiveLoginManager类调用setUserStatusListener监听强制下线事件通知 67 | 68 | ```java 69 | public interface TILVBStatusListener { 70 | void onForceOffline(int error, String message); 71 | } 72 | ``` 73 | 74 | #### IOS 75 | 76 | ##### 1. 设置用户状态监听 77 | ``` 78 | //设置用户状态监听 79 | [[ILiveSDK getInstance] setUserStatusListener:[[LiveUserStatusListener alloc] init]]; 80 | ``` 81 | 82 | ``` 83 | //用户状态监听类 84 | @interface LiveUserStatusListener : NSObject 85 | @end 86 | 87 | @implementation LiveUserStatusListener 88 | //被踢 89 | - (void)onForceOffline{ 90 | } 91 | //票据过期 92 | - (void)onUserSigExpired{ 93 | } 94 | ``` 95 | ##### 2. 回调中处理业务逻辑 96 | ``` 97 | - (void)onForceOffline{ 98 | //被踢下线(以下处理逻辑可做参考,具体可由自身业务决定) 99 | //1、如果未处于直播间,可跳转到用户登录界面 100 | //2、如果处于直播间 101 | //(1)保存直播状态信息,如房间id,房间标题等并退出直播间 102 | //(2)重新登录后,根据直播状态信息恢复(进入)直播间 103 | } 104 | ``` -------------------------------------------------------------------------------- /doc2/custom.md: -------------------------------------------------------------------------------- 1 | ## 功能定制 2 | 3 | 如果您的业务场景非常特殊,翻遍完我们的文档和demo代码,都不能满足需求。
4 | 您可以自己拿到im sdk和avsdk的接口,自由操作信令、群组、音视频接口进行定制。
5 | 6 | * Android 7 | 8 | #####获取IM管理器实例 9 | 10 | ``` 11 | TIMManager imManager = ILiveSDK.getTIMManager(); 12 | ``` 13 | 14 | 查看Android IMSDK接口的详细信息请点击[这里](https://www.qcloud.com/document/product/269/1557) 15 | 16 | #####获取AV上下文实例 17 | 18 | ``` 19 | AVContext avContext = ILiveSDK.getAVContext(); 20 | ``` 21 | 22 | 查看Android AVSDK接口的详细信息请点击[这里](https://www.qcloud.com/document/product/268/3823) 23 | 24 | * ios 25 | 26 | 27 | #####获取IM管理器实例 28 | 29 | ``` 30 | TIMManager *imManager = [[ILiveSDK getInstance] getTIMManager]; 31 | ``` 32 | 33 | 查看IOS IMSDK接口的详细信息请点击[这里](https://www.qcloud.com/document/product/269/1565) 34 | 35 | #####获取AV上下文实例 36 | 37 | ``` 38 | QAVContext *avContext = [[ILiveSDK getInstance] getAVContext]; 39 | ``` 40 | 41 | 查看IOS AVSDK接口的详细信息请点击[这里](https://www.qcloud.com/document/product/268/3824) 42 | 43 | 44 | **注意事项:**请在ILiveSDK初始化并登录后再使用以上接口。 45 | 46 | 47 | ## 您是壕不差钱现在就是要快快快上线产品? 48 | 49 | 抱歉,文档里没有解决方案
50 | 不过,我们给您准备了服务绿色通道,请加QQ:3358225043 (请注明企业名称+互动直播) -------------------------------------------------------------------------------- /doc2/docList.md: -------------------------------------------------------------------------------- 1 | ## 产品简介 2 | ### [互动直播功能介绍](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/Introduction.md) 3 | ### [应用场景](https://www.qcloud.com/doc/product/268/3160) 4 | ### [变更历史](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/History.md) 5 | ## 开通与购买指导 6 | #### [如何开通](https://www.qcloud.com/doc/product/268/4899) 7 | #### [价格说明](https://www.qcloud.com/doc/product/268/5127) 8 | 1. [基础网络费用](https://www.qcloud.com/doc/product/268/5128) 9 | 2. [附加能力费用](https://www.qcloud.com/doc/product/268/5129) 10 | 3. [技术支持费用](https://www.qcloud.com/doc/product/268/5130) 11 | 12 | #### [扣费和欠费](https://www.qcloud.com/doc/product/268/3166) 13 | 14 | ## 集成开发 15 | ## 开发预备 16 | ### [了解系统架构](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/Architecture.md) 17 | ### [快速参数配置](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/fastConfig.md) 18 | ### [准备后台接口](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/serverInit.md) 19 | 20 | ## 终端集成 21 | ### Android端集成 22 | 1. [下载代码](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/Android_ILiveSDK_BeforeHand.md) 23 | 2. [直播接口](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/Android_ILiveSDK_Live.md) 24 | 3. [互动消息和上麦接口](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/Android_ILiveSDK_Senior.md) 25 | 26 | ### iOS端集成 27 | 1. [下载代码](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/iOS_ILiveSDK_BeforeHand.md) 28 | 2. [直播接口](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/iOS_ILiveSDK_Live.md) 29 | 3. [互动消息和上麦接口](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/iOS_ILiveSDK_Interactive.md) 30 | 31 | ### Mac端集成 32 | 1. [下载代码](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/Mac_ILiveSDK_BeforeHand.md) 33 | 2. [直播接口](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/Mac_ILiveSDK_Live.md) 34 | 3. [互动消息和上麦接口](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/Mac_ILiveSDK_Interactive.md) 35 | 36 | ### PC端集成 37 | 1. [Windows C++集成](https://www.qcloud.com/document/product/268/5451) 38 | 2. [PC Demo使用说明](https://www.qcloud.com/document/product/268/5453) 39 | 3. [C++ SDK文件清单](https://www.qcloud.com/document/product/268/2473) 40 | 41 | ### web端集成 42 | 1. [web端观看](https://www.qcloud.com/doc/api/258/5704) 43 | 2. [web消息互动](https://www.qcloud.com/doc/product/269/1594) 44 | 45 | 46 | ### [旁路直播](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/pushStream.md) 47 | ### [录制](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/record.md) 48 | ### [截图和鉴黄](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/%E6%88%AA%E5%9B%BE%E5%92%8C%E9%89%B4%E9%BB%84.md) 49 | ## 重要概念 50 | 51 | ### [DC与OC的分配和切换](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/ocdc.md) 52 | 53 | ### 账号登录集成 54 | * [账号登录集成说明](https://www.qcloud.com/doc/product/268/3328) 55 | * [独立模式](https://www.qcloud.com/doc/product/268/3329) 56 | * [托管模式](https://www.qcloud.com/doc/product/268/3330) 57 | * [TLS后台API](https://www.qcloud.com/doc/product/268/3331) 58 | * [密钥和签名相关](https://www.qcloud.com/doc/product/268/3332) 59 | 60 | 61 | ## 常见问题 62 | ### [流控配置](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/spearConfig.md) 63 | ### [质量监控](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/avmonitor.md) 64 | ### [自定义音视频输入流](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/custominput.md) 65 | ### [使用第三方App播放背景音乐](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/musicinput.md) 66 | ### [画面对焦](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/focus.md) 67 | ### [画面旋转和裁剪](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/rotate.md) 68 | ### [直播被中断事件的处理](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/breakEvent.md) 69 | ### [在线人数](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/onlineMember.md) 70 | ### [功能定制](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/custom.md) 71 | ### [日志说明](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/log.md) 72 | ### [日志上报](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/loguploader.md) 73 | ### [AVSDK1.8.4转置方案升级指引](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/AVSDK%201.8.4%E8%BD%AC%E7%BD%AE%E5%8A%9F%E8%83%BD%E5%8D%87%E7%BA%A7%E6%8C%87%E5%8D%97.md) 74 | ### [新老随心播信令兼容](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/%E6%96%B0%E8%80%81%E9%9A%8F%E5%BF%83%E6%92%AD%E4%BF%A1%E4%BB%A4%E5%85%BC%E5%AE%B9%E6%96%87%E6%A1%A3.md) 75 | 76 | 77 | 78 | ##运营相关 79 | ###[微信支付证照要求](https://www.qcloud.com/document/product/268/6048) 80 | ###[大型直播活动准备指南](https://www.qcloud.com/document/product/268/4557) 81 | 82 | -------------------------------------------------------------------------------- /doc2/enterRoomParam.md: -------------------------------------------------------------------------------- 1 | ## 音视频权限管理 2 | 3 | 用户音视频权限,是指一组开关,每个开关对应用户能否在房间内执行某项动作,即**`能否创建房间`**、**`能否加入房间`**、**`能否接收/发送摄像头音视频数据`**和**`能否发送/接收屏幕分享音视频数据`**。 4 | 5 | 用户音视频权限,是作为进入房间**`AVContext.enterRoom(int roomType, AVRoom.Delegate roomDelegate, AVRoom.EnterRoomParam enterRoomParam)`** 的参数**`AVRoomMulti.EnterRoomParam`**传递给SDK的。具体取值如下: 6 | 7 | 权限字段名称| 字段含义 8 | ---- | ---- 9 | AUTH\_BITS\_CREATE\_ROOM |创建房间权限 10 | AUTH\_BITS\_JOIN_ROOM |加入房间的权限 11 | AUTH\_BITS\_RECV_AUDIO |【接收】语音的权限 12 | AUTH\_BITS\_RECV_VIDEO |【接收】摄像头视频数据的权限 13 | AUTH\_BITS\_RECV_SUB |【接收】屏幕分享视频数据的权限(全民直播用不到) 14 | AUTH\_BITS\_SEND_AUDIO |【发送】语音的权限 15 | AUTH\_BITS\_SEND_VIDEO |【发送】摄像头视频数据的权限 16 | AUTH\_BITS\_SEND_SUB |【发送】屏幕分享视频数据的权限(全民直播用不到) 17 | AUTH\_BITS\_DEFUALT |缺省值。拥有所有权限 18 | 19 | 对应到全民直播领域,通常有两个角色,即主播和观众。 20 | 21 | + 主播:毫无疑问应该拥有所有权限,即**`AUTH_BITS_DEFUALT`** 22 | + 观众 23 | + 观众角色**`AVContext.enterRoom()`**时都应该设置成没有“发送”相关的权限,建议 24 | + **`AUTH_BITS_JOIN_ROOM`** 25 | + **`AUTH_BITS_RECV_AUDIO`** 26 | + **`AUTH_BITS_RECV_VIDEO`** 27 | + **`AUTH_BITS_RECV_SUB`** 28 | + 【注意】当观众连麦时,需要调用下一节介绍的**`AVRoomMulti.changeAuthority()`**接口来添加音视频发送权限,才能真正实现连麦,修改完成后观众权限变成 29 | + **`AUTH_BITS_JOIN_ROOM`** 30 | + **`AUTH_BITS_RECV_AUDIO`** 31 | + **`AUTH_BITS_RECV_VIDEO`** 32 | + **`AUTH_BITS_RECV_SUB`** 33 | + **`AUTH_BITS_SEND_AUDIO`** 34 | + **`AUTH_BITS_SEND_VIDEO`** 35 | + **`AUTH_BITS_SEND_SUB`** 36 | + 【注意】观众连麦结束后,需要再次调用的**`AVRoomMulti.changeAuthority()`**接口来取消观众的音视频发送权限,修改完成后观众权限变成 37 | + **`AUTH_BITS_JOIN_ROOM`** 38 | + **`AUTH_BITS_RECV_AUDIO`** 39 | + **`AUTH_BITS_RECV_VIDEO`** 40 | + **`AUTH_BITS_RECV_SUB`** 41 | 42 | 用户音视频权限的合理控制,可以避免不连麦用户使用资费较贵的[核心节点](ttps://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/oddc.md),大幅度节省带宽费用。关于用户音视频权限变更的具体实施细节在下一节详细介绍。 43 | 44 | ## 用户音视频权限动态变更 45 | 46 | 如前所述,腾讯云互动直播的后台接入分为[核心节点和边缘节点](ttps://github.com/zhaoyang21cn/suixinbo_doc/blob/master/doc2/oddc.md),其中核心节点带宽资费较贵,主要用于需要上行音视频数据或实时交互的用户角色(在全民直播业务中可以特指主播和连麦用户);而边缘节点带宽资费较便宜,主要用于不需要上行音视频数据、仅观看的用户角色(在全民直播业务中可以特指除主播和连麦用户之外的所有其他用户) 47 | 48 | 对于需要连麦功能的业务来说,如果所有用户进房间时都设置为`AUTH_BITS_DEFUALT`,那么所有用户都会接入核心节点,从而产生***_较贵的资费_***。所以,最经济的做法是,在进房间(`AVContext.enterRoom()`)的时候,只有主播拥有全部音视频权限(`AUTH_BITS_DEFUALT `),而所有其他用户则只有进入房间和收听/收看权限(`AUTH_BITS_JOIN_ROOM` | `AUTH_BITS_RECV_AUDIO` | `AUTH_BITS_RECV_VIDEO` | `AUTH_BITS_RECV_SUB`) 49 | 50 | 当某个用户要连麦的时候,通过SDK的**`AVRoomMulti.changeAuthority()`**接口为该用户赋予上行音视频的权限(`AUTH_BITS_SEND_AUDIO` | `AUTH_BITS_SEND_VIDEO` | `AUTH_BITS_SEND_SUB`)。此时,该用户会从边缘节点重定向到核心节点,其中重定向动作在SDK内部完成,对App透明,完成后会有回调`OnChangeAuthority()` 51 | 52 | 当连麦用户结束下麦的时候,同样需要调用**`AVRoomMulti.changeAuthority()`**接口收回该用户的音视频上行权限(只保留`AUTH_BITS_RECV_XXX`)。此时,该用户会从核心节点重定向到边缘节点,从而达到节省带宽资费的目的 53 | 54 | ### 连麦用户上麦的具体步骤如下: 55 | 56 | + 调用`boolean AVRoomMulti.changeAuthority()`接口为连麦用户增加音视频上行权限(`AUTH_BITS_SEND_XXX`),如果返回值为True,那么 57 | + 等待`OnChangeAuthority:(int retCode)`回调,判断`retCode`是否等于`av_ok`,如果是,那么 58 | + 打开麦克风和摄像头(具体客户端代码示例待补充...),开始连麦 59 | 60 | ### 连麦用户退出连麦的具体步骤如下: 61 | 62 | + 关闭麦克风和摄像头(具体客户端代码示例待补充...) 63 | + 调用`boolean AVRoomMulti.changeAuthority()`接口为连麦用户去除音视频上行权限,如果返回值为True,那么 64 | + 等待`OnChangeAuthority:(int retCode)`回调,判断`retCode`是否等于`av_ok`,如果是,那么步骤完成,否则报错或重试 -------------------------------------------------------------------------------- /doc2/fastConfig.md: -------------------------------------------------------------------------------- 1 | ### 快速参数配置 2 | 在启动开发前,我们需要进行一些应用、账号、编解码参数的配置。这些配置都可以在腾讯云的控制台完成。 3 | ### 第一步 创建应用 4 | 1. 考虑到一个公司可能会开发多个应用,所以一个腾讯视频云的账号可以创建多个互动直播应用。但不同应用之间的数据是相互隔离的,不能互相访问。如果有多个应用之间需要相互访问,我们建议使用同一个appid, 5 | 2. 进入腾讯云控制台,找到互动直播业务,然后在应用列表点击“创建应用接入”按钮,填写应用名称,点“确定”按钮就创建了一个应用。 6 | 3. 应用创建完成后,在应用列表里可以看到 `SDKAPPID` ,后台会用这个参数来识别应用的身份。 7 | 4. 如果多个应用之间需要相互访问,我们建议使用同一个`SDKAPPID`,开发者来确保不同应用之间的账号分配不会重复。 8 | 9 | ### 第二步 选择账号认证方式 10 | 11 | 1. 为了在互动直播应用中标示用户的身份,我们需要选择一个和腾讯视频云之间进行账号身份认证的方式。 12 | 2. 账号身份认证的方式分`独立模式``托管模式`两种。
13 | 独立模式是指,用户注册和身份验证由开发者负责,开发者和腾讯之间通过签名验证建立信任关系。绝大部分用户都选择这种模式。
14 | 托管模式是指腾讯云为开发者提供APP帐号的密码注册、存储和密码验证。适用于快速体验功能的场景。
15 | 3. 在应用列表中选择我们刚才新建的应用,点击“应用配置”链接。然后在基础配置中找到“账号集成体系”。填写账号名称,选择独立模式或托管模式,确定后可以在页面上看到 `accountType` 。这个参数的值在开发中也会用到。 16 | 17 | ### 第三步 配置场景和角色 18 | 在应用列表中选择我们刚才新建的应用,点击“应用配置”链接。然后选择“SPEAR引擎配置”tab。 19 | 20 | 1. 选择应用场景
21 | 当前默认的场景是实时通信。互动直播业务点”变更场景“链接,选择互动直播场景。 22 | 2. 角色的意义
23 | 角色的意义是用来标示一套音视频编码参数。sdk会按照给的角色名字,拉取对应的音视频编码参数配置。 24 | 3. 添加角色和编解码参数配置
25 | 26 | 在“windows Web/ios/Android“ 三个tab下都选择“添加用户角色及配置”,每个tab下都添加如下三个角色。这三个角色对应互动直播里的开播,进房间和上麦三个场景。
27 | 28 | 29 | * LiveMaster,类型选择 “主播“

30 | ![添加角色](https://mc.qcloudimg.com/static/img/f3baf920bc8938dbf16dc5465f0a2253/jiaose.jpg)

31 | * Guest,类型选择 “观众“

32 | * LiveGuest,类型选择 “连麦观众“
33 | 34 | 35 | 36 | 如果开发者需要了解关于角色和参数的更详细说明,可以参考[这篇文档](https://github.com/zhaoyang21cn/suixinbo_doc/blob/master/SPEARConfig.md)。 -------------------------------------------------------------------------------- /doc2/iOS_ILiveSDK_BeforeHand.md: -------------------------------------------------------------------------------- 1 | ## 一 下载Demo 2 | 点击下载[iOS Demo](https://github.com/zhaoyang21cn/ILiveSDK_iOS_Demos)的代码。代码里包含两个示例:
3 | 4 | 1. tdemolive目录下是一个最简单的互动直播示例,演示了最关键的几个接口的调用。使用方法可以参考github上的说明。 5 | 2. suixinbo目录下是新版随心播代码。演示了包括界面和后台交互的完整的直播流程。 6 | 7 | 8 | ## 二 下载并导入Frameworks 9 | * [下载ILiveSDK,TILLiveSDK,AVSDK,IMSDK](https://github.com/zhaoyang21cn/ILiveSDK_iOS_Demos),并解压到工程目录suixinbo/Frameworks 下,工程最后的目录如下图: 10 | Frameworks目录 11 | 12 | ![Frameworks目录](http://mc.qcloudimg.com/static/img/139b6e97a13c9274c7371a6af6a0a530/image.png) 13 | 14 | AVSDK目录 15 | 16 | ![AVSDK目录](http://mc.qcloudimg.com/static/img/73d52880bdd252174f75e964b7d9c8eb/image.png) 17 | 18 | IMSDK目录 19 | 20 | ![IMSDK目录](http://mc.qcloudimg.com/static/img/819ee738975ccf61b510a58a9469b4ea/image.png) 21 | 22 | * 导入Frameworks,将下载好的SDK复制到工程目录下,工程目录右键,Add Files to " you projectname",在demo中如下图所示: 23 | 24 | ![SDK导入工程](http://mc.qcloudimg.com/static/img/7922154e7bdbbd0a6c24756d5b0a8866/image.png) 25 | 26 | ## 三 运行 27 | 编译运行工程。(如果xcode8编译不过,修改 Bundle Identifier, 随心播工程上的Bundle Identifier在用户真机上可能无法运行,用户重新修改下Bundle Identifier即可,比如在原有id后面加1) 28 | 29 | *
30 | 31 | *
32 | 33 | 34 | ## 四 集成到开发者自己的代码工程里 35 | ### 1 引入SDK并导入项目 36 | 37 | 参照以上 第二步 38 | 39 | ### 2 修改工程配置 40 | 将下载好的SDK复制到工程目录下,工程目录右键,Add Files to " you projectname",在demo中如下图所示: 41 | 42 | 1. Build Settings/Linking/Other Linker Flags,增加 -ObjC 配置,如下图所示: 43 | ![](http://mc.qcloudimg.com/static/img/9e48e62964428b6b12e11c262ff29178/image.png) 44 | 45 | 2. Build Settings/Linking/Bitcode,增加 Bitcode 配置,设置为NO,如下图所示: 46 | ![](http://mc.qcloudimg.com/static/img/f473f6c580a4196af7d3d33edf140bdb/image.png) 47 | 48 | 3. iOS10及以上系统,需在Info.plist中增加设备访问权限配置 49 | ![](http://mc.qcloudimg.com/static/img/e7b7897cb79a5cb9a984938dd4b3fda3/image.png) 50 | 若上述步骤均无误,则工程编译可以通过了。 51 | 52 | ### 3 添加系统库 53 | 添加以下系统库比较方便的方法是直接从随心播工程中,将SystemLibrarys组拖到自己的工程目录下 54 | 55 | | 需要增加的系统库 | 56 | |------------| 57 | |libc++.tbd| 58 | |libstdc++.tbd| 59 | |libstdc++.6.tbd| 60 | |libz.tbd| 61 | |libbz2.tbd| 62 | |libiconv.tbd| 63 | |libresolv.tbd| 64 | |libsqlite3.tbd| 65 | |libprotobuf.tbd| 66 | |UIKit.framework| 67 | |CoreVideo.framework| 68 | |CoreMedia.framework| 69 | |Accelerate.framework| 70 | |Foundation.framework| 71 | |AVFoundation.framework| 72 | |VideoToolbox.framework| 73 | |CoreGraphics.framework| 74 | |CoreTelephony.framework| 75 | |SystemConfiguration.framework| 76 | |AssetsLibrary.framework(ILiveSDK1.4.0,QAVSDK1.9.0之后的包需要添加)| 77 | 78 | ## 五 库类介绍 79 | ----- 80 | |Frameworks文件夹|说明| 81 | |---|---| 82 | |AVSDK|包括音视频相关的所有SDK| 83 | |IMSDK|包括即时通讯相关的所有SDK| 84 | |ILiveSDK|包括ILiveSDK和TILLiveSDK| 85 | 86 | ### 库类清单 87 | |序号|名称|所在文件夹|说明| 88 | |---|---|---|---| 89 | |1|QAVSDK.framework|Frameworks/AVSDK/|音视频SDK| 90 | |2|xplatform.framework|Frameworks/AVSDK/|音视频SDK所依赖的SDK| 91 | |3|IMCore.framework|Frameworks/IMSDK/|即时通讯核心库| 92 | |4|ImSDK.framework|Frameworks/IMSDK/|即时通讯SDK| 93 | |5|IMSDKBugly.framework|Frameworks/IMSDK/|上报SDK| 94 | |6|QALSDK.framework|Frameworks/IMSDK/|即时通讯网络模块SDK| 95 | |7|TLSSDK.framework|Frameworks/IMSDK/|登录服务SDK| 96 | |8|ILiveSDK.framework|Frameworks/ILiveSDK/|互动直播基础功能SDK| 97 | |9|TILLiveSDK.framework|Frameworks/ILiveSDK/|直播SDK(针对直播场景封装的SDK,包括互动连麦等功能)| 98 | -------------------------------------------------------------------------------- /doc2/iOS_ILiveSDK_Interactive.md: -------------------------------------------------------------------------------- 1 | # 互动消息和上麦 2 | 3 | ### 准备 4 | 无论是发送消息还是上麦,都需要在创建或进入房间前设置事件和消息监听。示例: 5 | ``` 6 | TILLiveManager *manager = [TILLiveManager getInstance]; 7 | [manager setAVListener:self]; //设置音视频事件监听 8 | [manager setIMListener:self]; //设置消息监听 9 | ``` 10 | 11 | ### 1 发送文本消息 12 | 13 | |接口名|接口描述| 14 | |---|---| 15 | |sendTextMessage: succ: failed:|发送文本消息| 16 | 17 | |参数类型|参数名|说明| 18 | |---|---|---| 19 | |ILVLiveTextMessage|msg|文本消息类型| 20 | |TCIVoidBlock|succ|发送消息成功回调| 21 | |TCIErrorBlock|failed|发送消息失败回调| 22 | 23 | *示例: 24 | ``` 25 | // 1. 发送文本消息 26 | TILLiveManager *manager = [TILLiveManager getInstance]; 27 | ILVLiveTextMessage *msg = [[ILVLiveTextMessage alloc] init]; 28 | 29 | msg.type = ILVLIVE_IMTYPE_GROUP; //群消息(也可发C2C消息) 30 | msg.text = @"这里是消息的内容"; //消息内容 31 | msg.sendId = @"这里是消息的发送方id"; 32 | msg.sendId = @"这里是消息的接收方id"; 33 | 34 | [manager sendTextMessage:msg succ:^{ 35 | NSLog(@"发送成功"); 36 | } failed:^(NSString *moudle, int errId, NSString *errMsg) { 37 | NSLog(@"发送失败"); 38 | }]; 39 | ``` 40 | 41 | ``` 42 | // 2. 文本消息接收(在文本消息回调中接受文本消息) 43 | - (void)onTextMessage:(ILVLiveTextMessage *)msg 44 | { 45 | NSLog(@"收到消息:%@", msg.text); 46 | } 47 | ``` 48 | ### 2 上麦 49 | #### 2.1 主播邀请上麦流程图: 50 | ![](http://mc.qcloudimg.com/static/img/ccbafe376da2e175ff41bd681856581e/image.png) 51 | ------ 52 | #### 2.2 观众请求上麦流程图: 53 | ![](http://mc.qcloudimg.com/static/img/4d21a6ce428740fa16ebc58a0675b3e7/image.png) 54 | ------ 55 | #### 2.3 接口 56 | ##### 2.3.1 发送自定义消息接口 57 | 58 | |接口名|接口描述| 59 | |---|---| 60 | |sendCustomMessage: succ: failed:|发送自定义消息| 61 | 62 | |参数类型|参数名|说明| 63 | |---|---|---| 64 | |ILVLiveCustomMessage|msg|自定义消息体| 65 | |TCIVoidBlock|succ|发送自定义消息成功回调| 66 | |TCIErrorBlock|failed|发送自定义消息失败回调| 67 | 68 | *示例: 69 | ``` 70 | TILLiveManager *manager = [TILLiveManager getInstance]; 71 | ILVLiveCustomMessage *msg = [[ILVLiveCustomMessage alloc] init]; 72 | msg.cmd = ILVLIVE_IMCMD_INVITE; //邀请信令 73 | msg.type = ILVLIVE_IMTYPE_C2C; //C2C消息类型 74 | msg.recvId = @"这里是消息的接收方id"; 75 | 76 | [manager sendCustomMessage:msg succ:^{ 77 | NSLog(@"邀请成功"); 78 | } failed:^(NSString *moudle, int errId, NSString *errMsg) { 79 | NSLog(@"邀请失败"); 80 | }]; 81 | ``` 82 | ##### 2.3.2 上麦接口 83 | 84 | |接口名|接口描述| 85 | |---|---| 86 | |upToVideoMember: role: succ: failed:|观众上麦,包括打开摄像头、麦克风,切换角色,切换权限等操作| 87 | 88 | |参数类型|参数名|说明| 89 | |---|---|---| 90 | |uint64_t|auth|通话能力权限位,在 QAVCommon.h 文件中可以查看所有权限位定义| 91 | |NSString|role|角色字符串 (由业务方App的控制台生成)| 92 | |TCIVoidBlock|succ|上麦成功回调| 93 | |TCIErrorBlock|failed|上麦失败回调| 94 | 95 | *示例: 96 | ``` 97 | //观众在消息回调中可以收到主播发送自定义消息 98 | - (void)onCustomMessage:(ILVLiveCustomMessage *)msg 99 | { 100 | TILLiveManager *manager = [TILLiveManager getInstance]; 101 | switch (msg.cmd) 102 | { 103 | case ILVLIVE_IMCMD_INVITE: 104 | { 105 | //收到邀请调用上麦接口 106 | [manager upToVideoMember:ILVLIVEAUTH_INTERACT role:@"腾讯云后台配置的角色" succ:^{ 107 | NSLog(@"上麦成功"); 108 | } failed:^(NSString *moudle, int errId, NSString *errMsg) { 109 | NSLog(@"上麦失败"); 110 | }]; 111 | } 112 | break; 113 | } 114 | } 115 | ``` 116 | ##### 2.3.3 设置上麦着渲染画面的区域接口 117 | 118 | |接口名|接口描述| 119 | |---|---| 120 | |addAVRenderView: forKey:|添加渲染界面的区域,以及设置渲染视图对应的key(一般使用渲染视图对应用户的id)| 121 | 122 | |参数类型|参数名|说明| 123 | |---|---|---| 124 | |CGRect|frame|视图渲染区域| 125 | |NSString|key|视图对应的key,用作业务逻辑,一般使用画面对应的用户id| 126 | 127 | *示例: 128 | ``` 129 | - (void)onUserUpdateInfo:(ILVLiveAVEvent)event users:(NSArray *)users 130 | { 131 | TILLiveManager *manager = [TILLiveManager getInstance]; 132 | switch (event) 133 | { 134 | case ILVLIVE_AVEVENT_CAMERA_ON: 135 | { 136 | for (NSString *user in users) 137 | { 138 | //因为主播的渲染位置创建或进入房间的时候已经指定,这里不需要再指定。 139 | //当然也可根据自己的逻辑再此处指定主播的渲染位置。 140 | if(![user isEqualToString:self.host]) 141 | { 142 | [manager addAVRenderView:CGRectMake(20, 20, 120, 160) forKey:user]; 143 | } 144 | } 145 | } 146 | break; 147 | } 148 | } 149 | ``` 150 | 若上述步骤均无误,则可以实现主播邀请观众连麦,观众成功上麦,直播间中出现多路画面(主播和互动观众的)。 151 | -------------------------------------------------------------------------------- /doc2/iOS_ILiveSDK_Live.md: -------------------------------------------------------------------------------- 1 | # ILiveSDK直播流程图: 2 | 3 | ![](http://mc.qcloudimg.com/static/img/06d2fb5027be53492249d4b81bd2f5a5/image.png) 4 | 5 | 6 | # 1 初始化ILiveSDK 7 | 在应用启动时初始化ILiveSDK。 8 | 9 | |接口名|接口描述| 10 | |---|---| 11 | |initSdk: accountType:|ILiveSDK内部类初始化,告知AppId。内部包含了IMSDK的初始化| 12 | 13 | |参数类型|参数名|说明| 14 | |---|---|---| 15 | |int|appId|传入业务方appid| 16 | |int|accountType|传入业务方 accountType| 17 | 18 | *示例: 19 | ``` 20 | [[ILiveSDK getInstance] initSdk:[ShowAppId intValue] accountType:[ShowAccountType intValue]]; 21 | ``` 22 | 23 | # 2 帐号登录 24 | 25 | ## 2.1 托管模式 26 | 托管模式:用户帐号系统托管到腾讯云。[ 详情](https://www.qcloud.com/doc/product/269/1509) 27 | 28 | |接口名|接口描述| 29 | |---|---| 30 | |tlsLogin: pwd: succ: failed:|托管模式登录到腾讯云后台| 31 | 32 | |参数类型|参数名|说明| 33 | |---|---|---| 34 | |NSString|uid|用户在托管模式下注册的帐号| 35 | |NSString|pwd|用户在托管模式下注册帐号的密码| 36 | |TCIVoidBlock|succ|登录成功回调| 37 | |TCIErrorBlock|failed|登录失败回调| 38 | 39 | *示例: 40 | ``` 41 | [[ILiveLoginManager getInstance] tlsLogin:@"这里是帐号id" pwd:@"这里是登录密码" succ:^{ 42 | NSLog(@"登录成功"); 43 | } failed:^(NSString *moudle, int errId, NSString *errMsg) { 44 | NSLog(@"登录失败"); 45 | }]; 46 | ``` 47 | 48 | ## 2.2 独立模式 49 | 独立模式:用户帐号系统由用户自己的服务器维护。独立模式需要业务后台生成Sig,客户端拿到这个Sig再登录腾讯云后台。[详情](https://www.qcloud.com/doc/product/269/1508) 50 | 51 | |接口名|接口描述| 52 | |---|---| 53 | |iLiveLogin: sig: succ: failed:|独立模式登录到腾讯云后台| 54 | 55 | |参数类型|参数名|说明| 56 | |---|---|---| 57 | |NSString|uid|用户在独立模式下注册的帐号| 58 | |NSString|sig|用户在业务方后台获取到的签名| 59 | |TCIVoidBlock|succ|登录成功回调| 60 | |TCIErrorBlock|failed|登录失败回调| 61 | 62 | *示例: 63 | ``` 64 | [[ILiveLoginManager getInstance] iLiveLogin:@"这里是帐号id" sig:@"这里是签名字符串" succ:^{ 65 | NSLog(@"登录成功"); 66 | } failed:^(NSString *moudle, int errId, NSString *errMsg) { 67 | NSLog(@"登录失败"); 68 | }]; 69 | ``` 70 | 71 | # 3 创建房间(进入房间) 72 | 73 | ## 3.1 主播创建房间 74 | 75 | |接口名|接口描述| 76 | |---|---| 77 | |createRoom: option: succ: failed:|主播创建直播间,自动渲染本地画面,开始直播| 78 | 79 | |参数类型|参数名|说明| 80 | |---|---|---| 81 | |int|roomId|房间号。业务方后台生成的房间号,需保证唯一性| 82 | |ILiveRoomOption|option|主播创建房间时的配置项,使用defaultHostLiveOption接口获取主播默认配置即可| 83 | |TCIVoidBlock|succ|创建房间成功回调| 84 | |TCIErrorBlock|failed|创建房间失败回调| 85 | 86 | *示例: 87 | ``` 88 | ILiveRoomOption *option = [ILiveRoomOption defaultHostLiveOption]; //默认主播配置 89 | TILLiveManager *manager = [TILLiveManager getInstance]; 90 | [manager setAVRootView:self.view]; //设置渲染承载的视图 91 | [manager addAVRenderView:self.view.bounds forKey:self.host]; //添加渲染位置 92 | 93 | [manager createRoom:self.roomId option:option succ:^{ 94 | NSLog(@"创建房间成功"); 95 | } failed:^(NSString *moudle, int errId, NSString *errMsg) { 96 | NSLog(@"创建房间失败"); 97 | }]; 98 | ``` 99 | 100 | ## 3.2 观众进入房间 101 | 102 | |接口名|接口描述| 103 | |---|---| 104 | |joinRoom: option: succ: failed:|观众进入直播间,自动拉去远程画面并渲染,开始观看直播| 105 | 106 | |参数类型|参数名|说明| 107 | |---|---|---| 108 | |int|roomId|房间号。业务方后台生成的房间号,需保证唯一性| 109 | |ILiveRoomOption|option|观众进入房间时的配置项,使用defaultGuestLiveOption接口获取观众默认配置即可| 110 | |TCIVoidBlock|succ|进入房间成功回调| 111 | |TCIErrorBlock|failed|进入房间失败回调| 112 | 113 | *示例: 114 | ``` 115 | ILiveRoomOption *option = [ILiveRoomOption defaultGuestLiveOption]; //默认观众配置 116 | TILLiveManager *manager = [TILLiveManager getInstance]; 117 | [manager setAVRootView:self.view]; //设置渲染承载的视图 118 | [manager addAVRenderView:self.view.bounds forKey:self.host]; //添加渲染位置 119 | 120 | [manager joinRoom:self.roomId option:option succ:^{ 121 | NSLog(@"进入房间成功"); 122 | } failed:^(NSString *moudle, int errId, NSString *errMsg) { 123 | NSLog(@"进入房间失败"); 124 | }]; 125 | ``` 126 | 127 | 若以上步骤均无误,则主播开始直播,观众观看直播的整个流程就结束了。 128 | -------------------------------------------------------------------------------- /doc2/loguploader.md: -------------------------------------------------------------------------------- 1 | # 日志上报 2 | 3 | ## 功能描述 4 | 开发和用户使用过程中往往会遇到一些问题,为了尽快帮您定位问题,iLiveSDK提供了日志上报接口。主动调用日志上报接口,sdk会自动收集日志并压缩上报腾讯云。免去手动获取日志的麻烦。 5 | ## 使用场景 6 | - 开发过程中遇到腾讯云相关问题,调用接口上报日志,填写问题描述(如发生时间,现象等),然后反馈给腾讯云客服分析日志 7 | - 在产品上添加日志上报的交互,末端用户使用时出现问题,自动把日志上报到腾讯云 8 | 9 | ## 客户端SDK接口 10 | ### Android 11 | 12 | #### 接口定义 13 | 14 | ``` 15 | /** 16 | * 上报日志 17 | * 18 | * @param desc 描述 19 | * @param callBack 回调 20 | */ 21 | ILiveSDK.getInstance().uploadLog(String desc, ILiveCallBack callback); 22 | 23 | ``` 24 | 25 | ### IOS 26 | 27 | #### 接口定义 28 | 29 | ``` 30 | [[ILiveSDK getInstance] uploadLog:@"日志描述" uploadResult:^(int retCode, NSString *retMsg) { 31 |  if(retCode == ILLU_OK){ 32 |    NSLog("上报成功"); 33 | } 34 | else{ 35 |    NSLog("上报失败"); 36 | } 37 | }]; 38 | 39 | ``` 40 | 41 | #### 错误码定义 42 | 0    : 日志上报成功 43 | 44 | 8101 : 参数错误 45 | 46 | 8102 : 文件不存在 47 | 48 | 8103 : 压缩失败 49 | 50 | 8104 : 获取签名失败 51 | 52 | 8105 : 协议解析失败 53 | 54 | 8106 : 上传失败 55 | 56 | 8107 : 上报结果失败 57 | 58 | #### 注意 59 | 用户未登录也可调用上报日志接口,由于用户id有助于问题的定位,建议登录后上报 60 | -------------------------------------------------------------------------------- /doc2/multiStream.md: -------------------------------------------------------------------------------- 1 | # 一路RTMP+多路上麦混流方案文档 2 | 3 | ### 需求场景 4 | 5 | 主播游戏解说、赛事解说、频道分享等需多路混流场景 6 | 7 | |||| 8 | :-----:|:-----:|:-----: 9 | ![](https://mc.qcloudimg.com/static/img/81bbf05065bdbeac8dbbc48e17131e93/2.png)|![](https://mc.qcloudimg.com/static/img/ca04c477a4338b4752b1cf6ab44121cd/3.png)|![](https://mc.qcloudimg.com/static/img/feff9b2df5797d0a9fb82286e62304c0/1.png) 10 | 游戏解说|赛事解说|频道分享 11 | 12 | 13 | ### 方案设计 14 | 15 | || 16 | :-----:| 17 | ![](https://mc.qcloudimg.com/static/img/0e459b3bb1e12af56f7c65df97c4402a/4.png)| 18 | 19 | 20 |   21 | > 步骤解读 22 | 23 | (1) rtmp视频源以直播码的形式推送rtmp流到直播服务器。[直播码传送门](https://www.qcloud.com/document/product/267/5956)
24 | (2) 连麦者使用直播SDK拉取一路rtmp视频流,使用互动直播SDK上传自己视频流或请求其他上麦者视频流进行互动。[直播SDK传送门](https://www.qcloud.com/document/product/267)和[互动直播SDK传送门](https://github.com/zhaoyang21cn/ILiveSDK_iOS_Suixinbo)
25 | (3) 连麦者手动或自动将互动直播流旁路到直播服务器。[旁路直播传送门](https://www.qcloud.com/document/product/268/8560)
26 | (4) 业务服务器调用混流接口将一路rtmp流和多路互动直播流混成一路输出流。[混流传送门](https://www.qcloud.com/document/product/267/8832)
27 | (5) 观众使用直播SDK拉取一路混合流观看。 28 | 29 | 30 | > 注意事项 31 | 32 | (1)业务服务器需延迟调用混流接口:由于互动直播流旁路到直播服务器并生成一路新的rtmp流存在耗时,因此建议业务服务器延迟8秒或以上调用混流接口,否则直播服务器返回无法找到互动直播流的错误。
33 | (2)直播服务器支持推送混合流到第三方CDN,需要提单配置。 34 | -------------------------------------------------------------------------------- /doc2/musicinput.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 使用第三方App播放背景音乐 4 | 5 | 需求背景:主播使用第三方音乐App播放背景音乐,自己收听的同时也希望观众一起畅听。 6 | ## IOS 7 | 8 | 只需要**主播端**开启高音质即可,观众和上麦者的配置无需改变 9 | 10 | ``` 11 | //进入房间时开启高音质配置 12 | ILiveRoomOption *option = [ILiveRoomOption defaultHostLiveOption]; 13 | option.avOption.autoHdAudio = YES; 14 | ``` 15 | 16 | ## Android 17 | android无需配置即可支持 18 | 19 | **注意** 20 | > * 必须先进入房间然后才打开音乐App开启背景音乐,否则直播间会中断背景音乐 21 | > * 主播和上麦观众的后台spear配置需要开启aec(回声消除) 22 | 23 | 24 | -------------------------------------------------------------------------------- /doc2/ocdc.md: -------------------------------------------------------------------------------- 1 | ## 1、相关概念说明 2 | - DC(Data Center):核心机房,用于互动直播业务中需要上行音视频数据或实时交互的用户角色(如主播、讲师、参与实时互动的角色等)接入 3 | - OC(Outer Center):边缘节点,用于互动直播业务中不需要上行音视频数据、仅观看的用户角色(如普通观众、不需要与老师互动的学生等)接入 4 | 5 | 二者的计费价格是不同的的,详情请见[计费](https://www.qcloud.com/doc/product/268/5128#2..E5.9F.BA.E7.A1.80.E7.BD.91.E7.BB.9C.E8.B4.B9.E7.94.A8.E8.AE.A1.E7.AE.97.E5.85.AC.E5.BC.8F)。 6 | 7 | ## 2、关于DC和OC的分配原则 8 | 对于一个App的用户来说,什么情况下会接入DC、什么情况下会接入OC呢?
9 | 分配原则简单来说只有一句话:“有上行音视频数据权限的实例会分配DC、没有上行音视频数据权限的实例分配OC”。
10 | 具体地,在调用SDK进入房间接口ILiveRoomManager.getInstance().createRoom()的时候,其参数ILiveRoomOption.authBits()用于设置该实例在房间内的权限,具体权限字段如下图所示: 11 | 12 | ![用户权限位说明](https://mccdn.qcloud.com/img56cdd6a958dff.png) 13 | 14 | AVRoomMulti.auth_bits成员变量是权限位的明文形式。 15 | 16 | AVRoomMulti.auth_bits 将`AUTH_BITS_SEND_AUDIO`/ `AUTH_BITS_SEND_VEDIO`/ `AUTH_BITS_SEND_SUB` 中的任意一个置为1,则实例会被分配接入DC;反之则该实例被分配接入OC。 17 | 18 | PS:后台对单个房间接入DC的用户数量有一个上限保护。例如,如果某个业务设置每个用户都有上行权限,那么后台对于每一个房间前1000个用户分配DC,其他用户分配OC。该限制为后台保护策略,后面可以根据需要进行调整。 19 | 20 | ## 3、关于DC/OC之间的切换策略 21 | 当用户通过进入房间的ILiveRoomManager.getInstance().createRoom()流程被分配到DC/OC之后,有时也会有需要在DC/OC之间进行切换的需求。
22 | 例如,教育场景下,一个原本没有上行权限的学生(被分配接入OC)被老师点中回答问题时,需要从不能上行音视频数据OC切换到DC。
23 | DC/OC的切换依然是以权限变化为依据的,相对应的接口为ILiveRoomManager类中changeAuthAndRole接口。下面将分几种情况来分别讨论:
24 | 25 | - 用户位于DC,权限从有到无(将`AUTH_BITS_SEND_AUDIO` / `AUTH_BITS_SEND_VEDIO`/ `AUTH_BITS_SEND_SUB` 全设置为0) 26 | 在此情况下,音视频后台会下发重定向指令,将终端实例重定向到OC。
27 | 典型的场景是,老师叫一个学生回答问题,回答结束之后取消了该学生上行音视频的权限,学生此时会被重定向到OC(该重定向操作对App和用户是透明的,切换过程通常很快) 28 | 29 | ![权限从有到无的变更导致切换示意图](https://mccdn.qcloud.com/img56cdd763b0628.png) 30 | 31 | - 用户位于DC,权限从无到有:不存在这种情况 32 | - 用户位于OC,权限从有到无:在此情况下SDK不会有任何动作 33 | - 用户位于OC,权限从无到有(将`AUTH_BITS_SEND_AUDIO` / `AUTH_BITS_SEND_VEDIO`/ `AUTH_BITS_SEND_SUB`其中一个置为非0),在此情况下,音视频后台会下发重定向指令,将终端实例重定向到DC。 34 | 35 | ![权限从无到有的变更导致切换示意图](https://mccdn.qcloud.com/img56cdd789c7ee8.png) 36 | -------------------------------------------------------------------------------- /doc2/onlineMember.md: -------------------------------------------------------------------------------- 1 | #在线人数统计方案 2 | 3 | > * 方案一:业务服务器管理(推荐) 4 | > * 方案二:使用IMSDK接口 5 | 6 | ##方案一:业务服务器管理 7 | ###流程图 8 | 9 | ![](http://mc.qcloudimg.com/static/img/8da0f13a73d87e2970e5e4603d3ca61d/image.png) 10 | 11 | ###步骤描述 12 | 13 | 1. 观众2调用业务服务器进房接口生成进房记录 14 | 2. 观众2调用imsdk接口发送进群自定义消息,可与步骤1同步进行 15 | 3. 观众2生成进房记录同时,业务服务器返回当前房间人数 16 | 4. 观众1收到观众2进群自定义消息,在线人数+1 17 | 5. 观众2调用业务服务器退房接口生成退房记录 18 | 6. 观众2调用imsdk接口发送退群自定义消息,可与步骤5同步进行 19 | 7. 观众1收到观众2退群自定义消息,在线人数-1 20 | 21 | ##方案二:使用IMSDK接口 22 | 23 | 通过IMSDK接口获取直播间在线人数主要有两种方式: 24 | 25 | * AVChatRoom通过群组资料获取人数 26 | * 不是实时的,有1分钟左右的时延 27 | * 只返回人数 28 | * AVChatRoom注册TIMGroupEventListener接口收到进群、退群事件时获取人数 29 | * imsdk2.4支持 30 | * 统计结果存在时延 31 | * 只返回人数 32 | * 人数较少场景(比如只有几十人),统计结果偏差明显 33 | 34 | 点击[这里](https://www.qcloud.com/doc/product/269/4104#5.3-.E8.8E.B7.E5.8F.96.E8.A7.82.E7.9C.8B.E7.9B.B4.E6.92.AD.E7.9A.84.E4.BA.BA.E6.95.B0)查看详细。 35 | 36 | 37 | **注意事项:** 38 | 39 | * ILiveSDK暂未提供该方案,推荐使用方案一 40 | 41 | ###流程图 42 | 43 | ![](http://mc.qcloudimg.com/static/img/b16adf18652b99993810d07054ec7c9b/image.png) 44 | 45 | ###步骤描述 46 | 1. 观众2进入直播 47 | 2. 观众1和观众2收到观众2的进群事件通知,使用附带的人数字段memberNum更新在线人数 48 | 3. 观众2退出直播 49 | 4. 观众1收到观众2的退群事件通知,使用附带的人数字段memberNum更新在线人数 50 | -------------------------------------------------------------------------------- /doc2/record.md: -------------------------------------------------------------------------------- 1 | ## 互动直播录制开发 2 | 录制的文件将存储在腾讯云提供的点播服务上,用户可通过点播的管理控制台、API进行管理、转码、分发等操作。

3 | **使用录制功能前,请先在控制台开通腾讯云点播服务,否则将无法使用**。 4 | 5 | ### 1 客户端SDK接口 6 | #### Android 7 | ##### 开始录制 8 | ######1. 设置录制参数 9 | 10 | ``` 11 | ILiveRecordOption option = new ILiveRecordOption(); 12 | option.fileName(filename); 13 | option.addTag(tag); 14 | option.classId(Integer.parseInt(classId)); 15 | ``` 16 | 17 | * 录制参数:ILiveRecordOption 18 | 19 | 字段名|字段类型|默认值|说明 20 | :--:|:--:|:--:|:--: 21 | fileName|String|必填| 录制生成的文件名 22 | classId|int|必填(当前版本请填0)|视频分类ID 23 | transCode|boolean|(暂不支持,默认为NO)|是否转码 24 | screenShot|boolean|(暂不支持,默认为NO)|是否截图 25 | waterMark|boolean|(暂不支持,默认为NO)|是否打水印 26 | sdkType|TIMAvManager.SDKType|必填(当前版本请选Normal)|SDK对应的业务类型 27 | recordType|AVRecordType|AV_RECORD_TYPE_VIDEO|录制类型 28 | 29 | 方法名|参数|说明 30 | :--:|:--:|:--: 31 | addTag|String|添加视频标签 32 | 33 | ######2. 开始录制 34 | 35 | ``` 36 | ILiveRoomManager.getInstance().startRecordVideo(option, new ILiveCallBack() { 37 | @Override 38 | public void onSuccess(Object data) { 39 | //开始录制成功 40 | } 41 | 42 | @Override 43 | public void onError(String module, int errCode, String errMsg) { 44 | //开始录制失败 45 | } 46 | }); 47 | ``` 48 | 49 | ##### 结束录制 50 | 51 | ``` 52 | ILiveRoomManager.getInstance().stopRecordVideo(new ILiveCallBack>() { 53 | @Override 54 | public void onSuccess(List data) { 55 | //停止录制成功 56 | for (String url : data){ 57 | //文件id 58 | } 59 | } 60 | 61 | @Override 62 | public void onError(String module, int errCode, String errMsg) { 63 | //停止录制失败 64 | } 65 | }); 66 | ``` 67 | 68 | Android录制功能的详细实现见[新随心播](https://github.com/zhaoyang21cn/ILiveSDK_Android_Demos) 69 | 70 | #### ios 71 | ##### 开始录制 72 | ######1. 设置录制参数 73 | 74 | ``` 75 | ILiveRecordOption *option = [[ILiveRecordOption alloc] init]; 76 | option.fileName = @"新随心播录制文件"; 77 | ``` 78 | 79 | * 录制参数:ILiveRecordOption 80 | 81 | 字段名|字段类型|默认值|说明 82 | :--:|:--:|:--:|:--: 83 | fileName|NSString|必填| 录制生成的文件名 84 | recordType|AVRecordType|必填(默认值为AV_RECORD_TYPE_VIDEO)|录制类型 85 | sdkType|AVSDKType|必填(当前版本请选AVSDK_TYPE_NORMAL,默认值为AVSDK_TYPE_NORMAL)|SDK对应的业务类型 86 | classId|UInt32|必填(当前版本请填0,默认值为0)|视频分类ID 87 | tags|NSArray|选填(默认值为nil)|视频标签列表 88 | isTransCode|BOOL|(暂不支持,默认为NO)|是否转码 89 | isScreenShot|BOOL|(暂不支持,默认为NO)|是否截图 90 | isWaterMark|BOOL|(暂不支持,默认为NO)|是否打水印 91 | 92 | 93 | ######2. 开始录制 94 | 95 | ``` 96 | [[ILiveRoomManager getInstance] startRecordVideo:option succ:^{ 97 | NSLog(@"已开始录制"); 98 | } failed:^(NSString *module, int errId, NSString *errMsg) { 99 | NSLog(@"开始录制失败"); 100 | }]; 101 | ``` 102 | 103 | ##### 结束录制 104 | 105 | ``` 106 | [[ILiveRoomManager getInstance] stopRecordVideo:^(id selfPtr) { 107 | NSArray *fileIds = (NSArray *)selfPtr; 108 | NSLog(@"已停止录制"); 109 | } failed:^(NSString *module, int errId, NSString *errMsg) { 110 | NSLog(@"停止录制失败"); 111 | }]; 112 | ``` 113 | 114 | * 回调结果:NSArray(返回NSString类型的文件Id列表) 115 | 116 | IOS录制功能的详细实现见[新随心播](https://github.com/zhaoyang21cn/ILiveSDK_iOS_Demos) 117 | 118 | ### 2 视频管理 119 | 120 | 通过音视频通信SDK录制的视频将存储在点播服务中 121 | 122 | 1. 用户访问点播的[管理控制台](http://console.qcloud.com/video)可以对录制的文件进行相应的管理操作
123 | 2. 用户也可以通过点播提供的API进行管理操作,[API手册](https://www.qcloud.com/doc/api/257/API%E6%A6%82%E8%A7%88)
124 | 3. DescribeVodPlayInfo能根据文件名(开始录制Api中,录制参数所填文件名)获取到录制 125 | 文件下载地址。详见[参考文档](https://www.qcloud.com/doc/api/257/%E8%8E%B7%E5%8F%96%E8%A7%86%E9%A2%91%E6%92%AD%E6%94%BE%E4%BF%A1%E6%81%AF%E5%88%97%E8%A1%A8) 126 | 127 | ### 3 价格和计费说明 128 | 129 | 录制功能本身是不收费的,但由于使用的是点播服务的能力,在云点播中会产生存储、流量的费用。[计费规则](https://www.qcloud.com/doc/product/268/5129#2..E5.BD.95.E5.88.B6.E7.9B.B8.E5.85.B3.E8.AE.A1.E8.B4.B9): 130 | 131 | 132 | 需要说明的是,如果你已开通点播服务,并选定套餐或后付费中的一种计费模式,将沿用你已选定的计费模式,如果你未开通点播服务,将默认选择后付费按流量的计费模式。 133 | 134 | ### 4 注意事项 135 | 136 | 1. 双人音视频房间不支持录制功能 137 | 2. 录制文件格式默认为MP4 138 | 3. 录制每隔90分钟或录制结束时不足90分钟会生成一个MP4录制文件,超过90分钟则会生成多个文件 139 | 4. APP运行过程中crash或异常退出,1分钟没收到数据会自动关闭录制,后端会录制用户异常退出前音视频 140 | 5. 现版本不支持多路上行视频合并和混音处理 141 | 142 | ### 5 错误码 143 | 144 | 145 | | 错误码| 错误说明| 处理建议| 146 | |---------|---------|---------| 147 | |1|用户没有录制权限|| 148 | |2|用户点播余额不足|| 149 | |30000000|SDK请求解析失败|【录制请求字段填写是否完整】| 150 | |30000001|SDK请求解析失败-没有录制请求包体|【录制请求字段填写是否完整】 151 | |30000002|SDK请求解析失败-没有录制文件名字段|【录制请求字段填写是否完整】 152 | |30000003|SDK请求解析失败-没有录制请求操作字段|【录制请求字段填写是否完整】 153 | |30000004|SDK请求解析失败-视频源类型错误(摄像头/桌面等)|【录制请求字段填写是否完整】 154 | |30000201|请求服务器内部数据打包错误|【反馈腾讯客服】 155 | |30000202|请求服务器内部数据打包错误|【反馈腾讯客服】 156 | |30000203|请求服务器内部数据打包错误|【反馈腾讯客服】 157 | |30000207|请求录制服务器通讯错误-拉取录制服务器地址失败|【反馈腾讯客服】 158 | |30000208|请求录制服务器通讯错误-请求录制服务器超时|【可能是网络问题,重试处理,重试失败反馈腾讯客服】 159 | |30000301|解析录制服务器回包错误-数据包解析失败|【反馈腾讯客服】 160 | |30000302|解析录制服务器回包错误-数据包解析失败|【反馈腾讯客服】 161 | |30000303|解析录制服务器回包错误-没有返回IP|【反馈腾讯客服】 162 | |30000304|解析录制服务器回包错误-没有返回端口|【反馈腾讯客服】 163 | |30000305|解析录制服务器回包错误-没有返回结果|【反馈腾讯客服】 164 | |30000401|查询房间获取grocery服务IP错误|【可能是网络问题,重试处理,重试失败反馈腾讯客服】 165 | |30000402|查询房间拉取grocery数据错误|【可能是网络问题,重试处理,重试失败反馈腾讯客服】 166 | |30000403|查询房间拉取grocery不存在(房间不存在)|【检查是否成功开房,录制的用户ID,groupid是否填写正确】 167 | |30000404|查询房间流控服务器超时|【可能是网络问题,重试处理,重试失败反馈腾讯客服】 168 | |30000405|查询房间回包错误-数据包解析失败|【反馈腾讯客服】 169 | |30000406|查询房间回包错误-数据包解析失败|【反馈腾讯客服】 170 | |30000407|查询房间回包错误-数据包解析失败|【反馈腾讯客服】 171 | |30000408|查询房间回包错误-没有返回结果|【反馈腾讯客服】 172 | |30000409|查询房间回包错误-数据包解析失败|【反馈腾讯客服】 173 | |30000410|录制的房间不存在|【检查是否成功开房,录制的用户ID,groupid是否填写正确,或者用户是否已经退出房间】 174 | |30000411|录制的房间不存在,或发起录制的用户不存在|【检查是否成功开房,录制的用户ID,groupid是否填写正确,或者用户是否已经退出房间】 175 | |30000412|停止录制重复发送,用户已经停止录制 |【如果是录制停止操作说明已经停止,检查是否多次发送停止操作,无需处理】 176 | |30000413|停止录制重复发送,用户已经停止录制 |【如果是录制停止操作说明已经停止,检查是否多次发送停止操作,无需处理】 177 | |30000414|查询房间-服务器内部操作类型错误|【反馈腾讯客服】 178 | |30000415|启动录制重复发送,用户正在录制;或者发起录制的用户不存在|【检查是否成功开房,录制的用户ID,groupid是否填写正确】 179 | 180 | 181 | -------------------------------------------------------------------------------- /doc2/restCall.md: -------------------------------------------------------------------------------- 1 | # 后台接口 2 | 3 | 除了客户端sdk接口,互动直播后台也提供了一些接口,供开发者从自己的服务器发起调用。当前支持的接口有 4 | 5 | 1. 录制。 6 | 2. 旁路直播。 7 | 8 | ## 调用格式 9 | 10 | 请求数据为HTTPs Req+JSON格式的Content Body,应答数据为HTTPs Rsp+JSON格式的Content Body。 11 | 12 | ## 双向认证 13 | 为系统安全性考虑,第三方后台请求要求双向认证。双向认证证书申请请参考腾讯云官网相关文档:[产品文档-云通信-第三方回调回调-双向认证配置指南-Nginx双向认证配置指南](http://www.qcloud.com/doc/product/269/Nginx双向认证配置指南) 14 | 15 | 16 | ## HTTPs 请求的格式 17 | HTTP请求的格式为:`POST URL HTTP/1.1\r\n` 18 | 19 | ## 后台服务URL格式 20 | 21 | URL的格式为:`/ver/servicename/command?parameter/`,其中`ver`为版本号,目前为`v3`。servicenanme为`openim`。command根据请求的不同而设置。 22 | 23 | 例如,音频后台请求为:`v3/openim/videorelay` 24 | 25 | ### 域名: 26 | 27 | 测试环境为:
28 | 正式环境为: 29 | 30 | ### Comand: 31 | 32 | | Command | 说明 | 33 | |---------|---------| 34 | | videorelay | 视频聊天服务 | 35 | 36 | ### Parameter 37 | 38 | Parameter的格式为:`usersig=xxxx& identifier=xxxx&sdkappid=xxxx&random=xxxxx&apn=x/` 39 | 40 | | 参数名称 | 类型 | 说明 | 备注 | 41 | | --- | --- | --- | --- | 42 | | sdkappid | unsigned int | 使用open APP sdk时分配的appid | 在应用列表-应用配置-应用信息找到 | 43 | | usersig | String | open app sdk的token | 在应用列表-应用配置-帐号集成体系-下载用户凭证找到。 | 44 | | identifier | String | 管理员帐号 | 在应用列表-应用配置-帐号集成体系-帐号管理员由开发者创建 | 45 | | random | unsigned int | 标识当前请求的整数随机数参数 | 32位整数随机数 | 46 | | apn | unsigned int | 网络类型,0未知、1 wifi、2 2G、3 3G、4 4G | 后台操作填0 | 47 | 48 | ### 示例 49 | 完整的url如下:< 50 | https://openapi.tim.qq.com/v3/openim/videorelay?usersig=xxxx&apn=1&identifier=xxxx&sdkappid=xxxx&random=xxxx&contenttype=json> 51 | 52 | # 后台接口的内容定义 53 | 54 | ## 包体结构 55 | ### 请求内容由通用包头(GVCommOprHead)和具体包体两部分组成。如下所示: 56 | 57 | 【请求格式】 58 | 59 | { 60 | "reqhead":object of GVCommOprHead 61 | "reqbody":由GVCommOprHead中子命令决定 62 | } 63 | 64 | | 参数名称 | 类型 | 说明 | 备注 | 65 | | --- | --- | --- | --- | 66 | | reqhead | GVCommOprHead | 音视频服务通用包头 | | 67 | | reqbody | 由GVCommOprHead中子命令决定 | | | | 68 | ### 响应内容由通用包头(GVCommOprHead)和具体包体两部分组成。如下所示: 69 | 【响应格式】 70 | 71 | { 72 | "reqhead":object of GVCommOprHead 73 | "rspbody":由GVCommOprHead中子命令决定 74 | } 75 | 76 | | 参数名称 | 类型 | 说明 | 备注 | 77 | | --- | --- | --- | --- | 78 | | reqhead | GVCommOprHead | 音视频服务通用包头 | | 79 | | rspbody | 由GVCommOprHead中子命令决定 | | | | 80 | 81 | ## 通用包头(GVCommOprHead)定义 82 | 83 | { 84 | "uint32_sub_cmd":xxx, 85 | "uint32_seq":xxx, 86 | "uint32_auth_key":xxxx, 87 | "uint32_sdk_appid":xxx, 88 | "str_av_token":"xxx", 89 | "str_openid:"xxxx", 90 | "rpt_to_Account":["xxxx"], 91 | "bytes_cookie_buff":"xxxx", 92 | "uint32_result:"xxxx", 93 | "str_error_msg:"xxxx" 94 | } 95 | 96 | | 参数名称 | 类型 | 说明 | 备注 | 97 | | --- | --- | --- | --- | 98 | | uint32_sub_cmd | unsigned int/必填 | 子命令:0x5:请求录制和停止录制 0x6:请求推流和停止推流 | | 99 | | uint32_seq | unsigned int/必填 | 请求序号 | 需要第三方原样带回 | 100 | | uint32_auth_key | unsigned int/必填 | 群组号码 | 第三方定义的群组 | 101 | | uint32_sdk_appid | unsigned int/必填 | 开放sdk appid | | 102 | | str_av_token | String/可选 | 第三方调用QQ音视频服务鉴权标识(无需填写) | | 103 | | str_openid | String/可选 | 发起操作的openid后台操作时无需填写 | | 104 | | rpt_to_Account | String/可选 | 被操作的openid列表, **最多10个** ,具体含义参见业务包体 | **对于0x5、0x6请求只支持一个** | 105 | | uint32_result | int/可选 | 非业务结果(0:成功,非0:失败)-1:表示解包错误-2:包体错误-3:内部服务失败-4:包头校验失败-5 :av_token校验不通过 | 响应消息才用到 | 106 | | str_error_msg | String/可选 | 错误消息 | 响应消息才用到 | 107 | | bytes_cookie_buff | String | 业务cook,响应时原样带回 | | 108 | 109 | 【代码示例】 110 | 111 | "reqhead": 112 | { 113 | "uint32_sub_cmd":6, 114 | "uint32_seq":xxx, 115 | "uint32_auth_key":xxx, 116 | "uint32_sdk_appid":xxx, 117 | "rpt_to_Account":["xxx"], 118 | "bytes_cookie_buff":"xxxx" 119 | }, 120 | -------------------------------------------------------------------------------- /doc2/restCallRecord.md: -------------------------------------------------------------------------------- 1 | ### 录制请求 2 | 3 | - 子命令(uint32_sub_cmd):0x5 填写在GVCommOprHead中 4 | - 包体结构(reqbody):req_0x5 5 | 6 | req_0x5 7 | { 8 | "uint32_oper":xxx, 9 | "string_file_name":"xxx", 10 | "string_tags":["xxx"], 11 | "uint32_classid":xxx, 12 | "uint32_IsTransCode":xxx, 13 | "uint32_IsScreenShot":xxx, 14 | "uint32_IsWaterMark":xxx, 15 | "uint32_sdk_type":xxx, 16 | "uint32_record_data_type":xxx 17 | } 18 | 19 | ***注意:录制操作的对象为rpt_to_Account,必须填写,只支持一个*** 20 | 21 | | 参数名称 | 类型 | 说明 | 备注 | 22 | | --- | --- | --- | --- | 23 | | uint32_oper | unsigned int | 操作类型:1 启动录制;2 关闭录制; | 启动录制:必填 停止录制:必填 | 24 | | string_file_name | string | 录制的文件名称 | 启动录制:必填 停止录制:不填 | 25 | | string_tags | [string] | 视频标签列表,string数组 | 启动录制:可选 停止录制:不填 | 26 | | uint32_classid | unsigned int | 视频分类ID | 启动录制:可选 停止录制:不填 | 27 | | uint32_IsTransCode | unsigned int | 是否转码 | 启动录制:可选 停止录制:不填 | 28 | | uint32_IsScreenShot | unsigned int | 是否截图 | 启动录制:可选 停止录制:不填 | 29 | | uint32_IsWaterMark | unsigned int | 是否打水印 | 启动录制:可选 停止录制:不填 | 30 | | uint32_sdk_type | unsigned int | SDK类型:1 普通SDK; 2 物联摄像头; | 启动录制:必填 停止录制:必填 | 31 | | uint32_record_data_type | unsigned int | 录制的数据类型:0 录制摄像头; 1 录制屏幕分享数据; | 启动录制:必填 停止录制:必填 | 32 | 33 | "reqbody": 34 | { 35 | "req_0x5": 36 | { 37 | "uint32_oper":xxx, 38 | "string_file_name":xxx, 39 | "uint32_sdk_type":xxx, 40 | "uint32_record_data_type":xxx, 41 | } 42 | } 43 | 44 | 45 | - 响应包体结构(rspbody): rsp_0x5 46 | 47 | rsp_0x5定义: 48 | { 49 | "uint32_result":xxx, // 操作结果, 0成功, 非0失败 50 | "str_errorinfo":"xxx", 51 | "str_fileID":["xxx"] 52 | } 53 | 54 | | 参数名称 | 类型 | 说明 | 备注 | 55 | | --- | --- | --- | --- | 56 | | uint32_result | unsigned int | 操作结果0:成功;非0:失败; | 详细错误码见附录 | 57 | | str_errorinfo | string | 错误信息 | 错误字符串信息 | 58 | | str_fileID | [String] | 视频文件ID列表,string数组。 | 只有在录制结束的时候返回 | 59 | 60 | ***注意:启动录制需要用户进入音视频房间之后操作才能成功*** 61 | 62 | # 错误码说明 63 | 64 | ## 0x5录制错误码说明 65 | 66 | | 错误码 | 错误说明 | 处理建议 | 67 | | --- | --- | --- | 68 | | 30000000 | SDK请求解析失败 | 【录制请求字段填写是否完整】 | 69 | | 30000001 | SDK请求解析失败-没有录制请求包体 | 【录制请求字段填写是否完整】 | 70 | | 30000002 | SDK请求解析失败-没有录制文件名字段 | 【录制请求字段填写是否完整】 | 71 | | 30000003 | SDK请求解析失败-没有录制请求操作字段 | 【录制请求字段填写是否完整】 | 72 | | 30000004 | SDK请求解析失败-视频源类型错误(摄像头/桌面等) | 【录制请求字段填写是否完整】 | 73 | | 30000201 | 请求服务器内部数据打包错误 | 【反馈腾讯客服】 | 74 | | 30000202 | 请求服务器内部数据打包错误 | 【反馈腾讯客服】 | 75 | | 30000203 | 请求服务器内部数据打包错误 | 【反馈腾讯客服】 | 76 | | 30000207 | 请求录制服务器通讯错误-拉取录制服务器地址失败 | 【反馈腾讯客服】 | 77 | | 30000208 | 请求录制服务器通讯错误-请求录制服务器超时 | 【可能是网络问题,重试处理,重试失败反馈腾讯客服】 | 78 | | 30000301 | 解析录制服务器回包错误-数据包解析失败 | 【反馈腾讯客服】 | 79 | | 30000302 | 解析录制服务器回包错误-数据包解析失败 | 【反馈腾讯客服】 | 80 | | 30000303 | 解析录制服务器回包错误-没有返回IP | 【反馈腾讯客服】 | 81 | | 30000304 | 解析录制服务器回包错误-没有返回端口 | 【反馈腾讯客服】 | 82 | | 30000305 | 解析录制服务器回包错误-没有返回结果 | 【反馈腾讯客服】 | 83 | | 30000401 | 查询房间获取grocery服务IP错误 | 【可能是网络问题,重试处理,重试失败反馈腾讯客服】 | 84 | | 30000402 | 查询房间拉取grocery数据错误 | 【可能是网络问题,重试处理,重试失败反馈腾讯客服】 | 85 | | 30000403 | 查询房间拉取grocery不存在(房间不存在) | 【检查是否成功开房,录制的用户ID,groupid是否填写正确】 | 86 | | 30000404 | 查询房间流控服务器超时 | 【可能是网络问题,重试处理,重试失败反馈腾讯客服】 | 87 | | 30000405 | 查询房间回包错误-数据包解析失败 | 【反馈腾讯客服】 | 88 | | 30000406 | 查询房间回包错误-数据包解析失败 | 【反馈腾讯客服】 | 89 | | 30000407 | 查询房间回包错误-数据包解析失败 | 【反馈腾讯客服】 | 90 | | 30000408 | 查询房间回包错误-没有返回结果 | 【反馈腾讯客服】 | 91 | | 30000409 | 查询房间回包错误-数据包解析失败 | 【反馈腾讯客服】 | 92 | | 30000410 | 录制的房间不存在 | 【检查是否成功开房,录制的用户ID,groupid是否填写正确】 | 93 | | 30000411 | 录制的房间不存在,或发起录制的用户不存在 | 【检查是否成功开房,录制的用户ID,groupid是否填写正确】 | 94 | | 30000412 | 停止录制重复发送,用户已经停止录制 | 【如果是录制停止操作说明已经停止,检查是否多次发送停止操作,无需处理】 | 95 | | 30000413 | 停止录制重复发送,用户已经停止录制 | 【如果是录制停止操作说明已经停止,检查是否多次发送停止操作,无需处理】 | 96 | | 30000414 | 查询房间-服务器内部操作类型错误 | 【反馈腾讯客服】 | 97 | | 30000415 | 启动录制重复发送,用户正在录制;或者发起录制的用户不存在 | 【检查是否成功开房,录制的用户ID,groupid是否填写正确】 | 98 | 99 | -------------------------------------------------------------------------------- /doc2/rotate.md: -------------------------------------------------------------------------------- 1 | ## iLiveSDK视频旋转缩放解决方案 2 | 3 | ### 问题 4 | 5 | 由于观众和主播的屏幕方向和大小都可能不一致,所以需要在观众端,按照观众的屏幕大小和方向对主播的画面进行选择,缩放或裁剪。 6 | 7 | ### 方案选择 8 | 9 | 从1.2.0版本起,iLiveSDK支持自动旋转。 10 | 从1.5.1版本起,iLiveSDK支持手动旋转。 11 | 12 | 参数列表 13 | 14 | Android SDK 15 | 16 | 参数名/函数名 |说明 |默认值 17 | :-----: | :-----: | :-----: 18 | setRotate |主播画面是否旋转 |true(旋转) 19 | setSameDirectionRenderMode |方向一致渲染模式 |BaseVideoView.BaseRenderMode.SCALE_TO_FIT(全屏适应) 20 | setDiffDirectionRenderMode |方向不一致渲染模式 |BaseVideoView.BaseRenderMode.BLACK_TO_FILL(黑边) 21 | 22 | IOS SDK 23 | 24 | 参数名/函数名 |说明 |默认值 25 | :-----: | :-----: | :-----: 26 | autoRotate |是否启用自动旋转 |YES 27 | rotateAngle |顺时针旋转角度(手动旋转模式有效) |YES 28 | isRotate |主播画面是否旋转(自动旋转模式有效) |YES(旋转画面)NO(画面始终为正) 29 | sameDirectionRenderMode |方向一致渲染模式 |ILIVERENDERMODE_SCALEASPECTFILL(全屏适应) 30 | diffDirectionRenderMode |方向不一致渲染模式 |ILIVERENDERMODE_SCALEASPECTFIT(黑边) 31 | 32 | #### 自动旋转模式 33 | ##### 方案一 旋转主播画面 34 | 35 | 效果如下: 36 | 37 | 主播画面 |观众屏幕 |铺满屏幕,不留黑边 | 画面大小一致 | 尽量显示,可以留黑边 38 | :-----: | :-----: | :-----: | :-----: | :-----: 39 | ![](https://mc.qcloudimg.com/static/img/538ff9d974532d3cc13787f137dd0ea4/model8.png)|![](https://mc.qcloudimg.com/static/img/e9c1483107c3031dded8cbfc42821ef2/2.png)|![](https://mc.qcloudimg.com/static/img/152585d9f400feb2c35a899fd939737e/model1.png)|![](https://mc.qcloudimg.com/static/img/452c30d775789b72ecea8164ae084014/model2.png)|![](https://mc.qcloudimg.com/static/img/9193fc0d84c115de1bde449ffadc9635/model3.png) 40 | ![](https://mc.qcloudimg.com/static/img/538ff9d974532d3cc13787f137dd0ea4/model8.png)|![](https://mc.qcloudimg.com/static/img/5b5427bb528185e6fdb8e60784099f92/1.png)|![](https://mc.qcloudimg.com/static/img/31ebc8a5fa580e5678c8c6db38bdd858/model7.png)|![](https://mc.qcloudimg.com/static/img/538ff9d974532d3cc13787f137dd0ea4/model8.png)|![](https://mc.qcloudimg.com/static/img/e78daedf38d466b2ea66ad262580714f/model9.png) 41 | 42 | 配置如下: 43 | 44 | Android SDK 接口: 45 | 46 | ```java 47 | //设定需要旋转画面 48 | AVVideoView.setRotate(true); 49 | //设定是铺满屏幕还是留黑边 50 | AVVideoView.setSameDirectionRenderMode(BaseVideoView.BaseRenderMode.BLACK_TO_FILL); 51 | ``` 52 | 53 | IOS SDK接口: 54 | 55 | ```Object-C 56 | //设定需要旋转画面 57 | iLiveRenderView.isRotate = YES; 58 | //设定是铺满屏幕还是留黑边 59 | iLiveRenderView.sameDirectionRenderMode = ILiveRenderMode; 60 | ``` 61 | 62 | ##### 方案二 不旋转主播画面 63 | 64 | 效果如下: 65 | 66 | 主播画面 |观众屏幕 |铺满屏幕,不留黑边 | 画面大小一致 | 尽量显示,可以留黑边 67 | :-----: | :-----: | :-----: | :-----: | :-----: 68 | ![](https://mc.qcloudimg.com/static/img/538ff9d974532d3cc13787f137dd0ea4/model8.png)|![](https://mc.qcloudimg.com/static/img/e9c1483107c3031dded8cbfc42821ef2/2.png)|![](https://mc.qcloudimg.com/static/img/b442c7dffc76612d08bc0fcf8b220f61/model4.png)|![](https://mc.qcloudimg.com/static/img/e5f28f0210cfa878e8e4bbf41bb3ab72/model5.png)|![](https://mc.qcloudimg.com/static/img/7e75b7a6a227297207e4f955bec44ef8/model6.png) 69 | ![](https://mc.qcloudimg.com/static/img/538ff9d974532d3cc13787f137dd0ea4/model8.png)|![](https://mc.qcloudimg.com/static/img/5b5427bb528185e6fdb8e60784099f92/1.png)|![](https://mc.qcloudimg.com/static/img/31ebc8a5fa580e5678c8c6db38bdd858/model7.png)|![](https://mc.qcloudimg.com/static/img/538ff9d974532d3cc13787f137dd0ea4/model8.png)|![](https://mc.qcloudimg.com/static/img/e78daedf38d466b2ea66ad262580714f/model9.png) 70 | 71 | 配置如下: 72 | 73 | Android SDK 接口: 74 | 75 | ```java 76 | //设定不需要旋转画面 77 | AVVideoView.setRotate(false); 78 | //设定在方向不一致情况下,是铺满屏幕还是留黑边 79 | AVVideoView.setDiffDirectionRenderMode(BaseVideoView.BaseRenderMode.BLACK_TO_FILL); 80 | //设定在方向一致情况下,是铺满屏幕还是留黑边 81 | AVVideoView.setSameDirectionRenderMode(BaseVideoView.BaseRenderMode.SCALE_TO_FIT); 82 | ``` 83 | 84 | IOS SDK接口: 85 | 86 | ```Object-C 87 | //设定不需要旋转画面 88 | iLiveRenderView.isRotate = NO; 89 | //设定在方向不一致情况下,是铺满屏幕还是留黑边 90 | iLiveRenderView.diffDirectionRenderMode = ILiveRenderMode; 91 | //设定在方向一致情况下,是铺满屏幕还是留黑边 92 | iLiveRenderView.sameDirectionRenderMode = ILiveRenderMode; 93 | ``` 94 | 95 | #### 手动旋转模式 96 | 97 | 手动旋转模式下,画面方向为原始画面方向,只有在设置旋转角度后画面才会旋转。 98 | 99 | IOS SDK接口: 100 | 101 | ```Object-C 102 | //启用手动旋转模式 103 | iLiveRenderView.autoRotate = NO; 104 | //设置旋转角度 105 | iLiveRenderView.rotateAngle = ILIVEROTATION_0; 106 | //设定在方向不一致情况下,是铺满屏幕还是留黑边 107 | iLiveRenderView.diffDirectionRenderMode = ILiveRenderMode; 108 | //设定在方向一致情况下,是铺满屏幕还是留黑边 109 | iLiveRenderView.sameDirectionRenderMode = ILiveRenderMode; 110 | ``` 111 | 112 | Android SDK接口 113 | 114 | ``` 115 | // 启用手动旋转模式 116 | avRootView.setAutoOrientation(false); 117 | // 对每一路视频AVVideoView可以设置旋转角度 118 | avVideoView.setRotation(90); 119 | ``` 120 | -------------------------------------------------------------------------------- /doc2/serverInit.md: -------------------------------------------------------------------------------- 1 | ## 准备业务后台接口 2 | * 如果开发者采用托管账户模式,那在集成互动直播sdk的过程中基本不需要后台接口,可以跳过此文档; 3 | * 如果开发者采用独立账户模式,请参考下面的数据交互图。 4 | ![腾讯互动直播数据交互](https://mc.qcloudimg.com/static/img/4094feaf383cf1e3c5714bd3f9dbfc8e/hudongzhibo.png) 5 | 6 | #### 独立账号模式下开发者后台server必须实现的功能 7 | 8 | 1. 调用腾讯TLS后台API生成sig,派发给客户端; 9 | 2. 设计一个业务逻辑。以便在旧sig过期前生成新的sig,派发给客户端; 10 | 11 | #### 建议实现开发者后台server的功能 12 | 13 | 1. 上报创建房间信息; 14 | 2. 上报观众进入房间信息; 15 | 3. 提供正在进行的主播列表; 16 | 4. 统计观众人数; 17 | 5. 踢人和中断主播; 18 | 19 | ### 附录 20 | * [TLS账号登录集成说明](https://www.qcloud.com/doc/product/268/3328)。 21 | * 独立模式server demo下载地址(准备中......) 22 | -------------------------------------------------------------------------------- /doc2/spearConfig.md: -------------------------------------------------------------------------------- 1 | # SPEAR引擎流控配置简介 2 | ###**在进行实际开发前,首先要在腾讯云互动直播配置流控参数,才能获得更好的视频效果。** 3 | 4 | # 一、入口 5 | 登录腾讯云后,从 “云产品” -> “互动直播” 进入配置页面。 6 | ![](https://mc.qcloudimg.com/static/img/243044a017149d82e7cc10a1a81a7c80/image001.png) 7 | 8 | 进入“互动直播”配置页面后,可以看到自己创建的不同appid对应的配置。鼠标放在“更多”上,选择“SPEAR引擎配置”。 9 | 10 | ![](https://mc.qcloudimg.com/static/img/864d6de4bf6a052e3c3fb420be59713b/image002.png) 11 | 12 | 进入后就可以看到具体的参数配置。后面会详细说明配置的含义和如何设置参数。 13 | 14 | ![](https://mc.qcloudimg.com/static/img/24d35157346b545e20eab9718f2e4856/image004.png) 15 | 16 | # 二、配置说明 17 | ## 1. 场景 18 | 互动直播的配置首先分为不同的场景,每个场景保存自己的配置参数。一个appid可以设置一种对应的场景,当切换场景时,所有的音视频参数都会切换。 19 | 目前互动直播主要支持两种场景的业务:互动直播和实时通信。 20 | 21 | ![](https://mc.qcloudimg.com/static/img/f183e7a8c76ca9895318ae912c917523/image006.png) 22 | ![](https://mc.qcloudimg.com/static/img/7587343a15d6a8c31d7fcf13ddb52cff/image007.png) 23 | 24 | 互动直播主要针对一个或少量几个主播在直播,其他大多数的观众观看的场景。只有一个或几个用户有上行数据,其他大多数用户(几百、几千或更多)只有下行数据,没有上行数据。 25 | 实时通信主要针对多人聊天或多人会议的场景。参与的用户都有上下行数据的需要,同时需要较高的实时性,延时要小。 26 | 针对不同的场景,提供更适合业务需要的参数配置。 27 | 28 | ## 2. 平台 29 | 每个场景中包含不同平台的配置,支持根据不同的平台设置平台相关的不同参数。目前支持Windows、Web、iOS、Android四个平台,其中Windows和Web的参数配置是统一的。这样设置好后,Windows客户端会自动使用Windows页面的配置,iOS客户端会自动使用iOS页面的配置,以此类推。 30 | 31 | ![](https://mc.qcloudimg.com/static/img/c90c047e8f64b4085aa5a90eaa0a18a7/image008.png) 32 | 33 | ## 3. 角色 34 | 具体的某一平台的配置中,可以添加多个角色。角色实现了在单一平台上也可以配置不同的参数,即同一客户端可以通过切换角色来实现改变音视频配置的策略。 35 | user是默认角色,当客户端没有选择角色时,会使用默认角色的配置。 36 | 37 | ![](https://mc.qcloudimg.com/static/img/7da63a7a27f54b153c31d838263e3c2c/image010.png) 38 | 39 | 可以在页面的最底部添加角色,角色名称设置角色名。角色可以编辑,自己添加的角色可以删除。角色可以根据业务需要添加多个。 40 | 41 | ![](https://mc.qcloudimg.com/static/img/47ebdf9ebf1a765c0e3105c84fb59da8/image012.png) 42 | ![](https://mc.qcloudimg.com/static/img/69996113f9f8dcd94de3a6e6bf17c5d2/image014.png) 43 | 44 | 45 | ## 4. 场景、平台、角色的不同 46 | 场景、平台、角色都可以用来设置不同的配置方案,他们之间有什么区别? 47 | 场景是应用层面的不同,即一个app是主要用于直播还是实时通话。直播对清晰度流畅度要求高、延时要求低,实时通话对延时要求高;所以互动直播和实时通信的很多配置项都是不同的。一般一个app选择一个场景后,后续不会再改变。平台很容易理解,主要处理平台相关的不同配置,比如PC的性能一般比手机高,手机上的app会有权限的要求的等等。 48 | 49 | 角色上的区分,主要是为了业务层面的支持。不同角色可设置的配置项和取值范围都是一样的,配置的不同完全由业务决定。比如,作为主播时使用可以上行数据的配置,作为观众时使用只有下行数据的配置;性能高的机器上使用分辨率更高的配置等等。 50 | 51 | 52 | ## 5. 参数配置 53 | 参数配置分为视频参数、音频参数、网络参数三部分。在互动直播场景下,视频参数和大部分音频参数(下图红框中的参数)主要应用于上行数据,即只对主播起作用,对观众不起作用;网络参数应用于上下行数据,对主播、观众都起作用。实时通信场景,所有用户都有上下行数据,所以三部分参数对所有用户都起作用。 54 | 55 | ![](https://mc.qcloudimg.com/static/img/6dd38ad1b956cd1c885bfdbf1b2ca4ce/image016.png) 56 | 57 | 下面具体看下每部分参数的设置。 58 | ### 5.1 视频参数 59 | 60 | ![](https://mc.qcloudimg.com/static/img/263dff18fdaa2e01e1ff9f94bab43632/image018.png) 61 | 62 | 63 | * 配置模式:提供预设的“标清”、“高清”、“超清”打包模式,选择后不需要再配置其他参数。建议选择“高清”。选择“自定义”模式,可以自己配置其他参数 64 | * 编码格式:“自适应”由SDK根据设备性能和网络情况自行调整分辨率;“固定图像格式”选择一个固定的分辨率,提供4:3和16:9两种类型的分辨率。 65 | * 编码码率:“自适应”由SDK根据设备性能和网络情况自行调整码率;“自定义”指定SDK可以调整的范围,如果需要固定码率可以把最大最小值设置成一样的 66 | * 编码帧率:“自适应”由SDK根据设备性能和网络情况自行调整帧率;“自定义”指定一个期望的帧率。帧率和码率、清晰度相关,如果MinQP、MaxQP设置的不当,可能达不到期望的帧率。 67 | * 冗余抗丢包:通过FEC等方式增加冗余度来抵消网络丢包,冗余度一般为丢包率的两倍。一般情况下建议关闭。 68 | 69 | 帧率、码率、分辨率有一定的相关性,QP设置的不合理也有可能会降低帧率。简单的用法可以直接选择预设的“标清”、“高清”、“超清”打包模式;自定义情况下,帧率、码率、分辨率的对应建议如下: 70 | 71 | 分辨率 | 码率 | 帧率 72 | ---- |---- |---- 73 | 640 x 368 | 800Kbps | 25fps 74 | 960 x 540 | 1200Kbps | 15fps 75 | 76 | ### 5.2 音频参数 77 | 78 | ![](https://mc.qcloudimg.com/static/img/28a7f98d8d139042e5c9372e998333d3/image020.png) 79 | 80 | * 配置模式:“默认”模式不需要再设置其他参数,“自定义”模式可设置更多参数。 81 | * 音频场景:“开播”模式可以采集、编码、发送音频,适用于主播;“观看”模式不会打开音频设备也不会发送音频数据,适用于观众。 82 | * 编码码率:设置音频码率,范围0~64 83 | * 冗余抗丢包:通过FEC等方式增加冗余度来抵消网络丢包。互动直播场景建议关闭,实时通信场景建议打开。 84 | * aec:回声消除。互动直播不连麦的场景建议关闭,互动直播可能连麦场景和实时通信场景建议打开。 85 | * agc:自动增益。互动直播不连麦的场景建议关闭,互动直播可能连麦场景和实时通信场景建议打开。 86 | * ans:噪声抑制。互动直播不连麦的场景建议关闭,互动直播可能连麦场景和实时通信场景建议打开。 87 | 88 | ### 5.3 参数差异 89 | 90 | ![](https://mc.qcloudimg.com/static/img/b38439c90daed4aaba9e8ae4a3b93367/image024.png) 91 | 92 | 不同平台、不同场景下的参数配置略有不同,根据页面显示的可配置选项配置即可。 93 | 94 | 如实时通信场景,音频参数和网络参数是不能配置的。 95 | 96 | 可配置参数可能会随着版本升级发生变化,以配置网页上显示的配置项为准。 97 | 98 | # 三、客户端逻辑 99 | ## 1. 配置生效时机 100 | 在腾讯云上配置好后,客户端不会立即生效。客户端要在调用xxx api时,去后台拉取最新配置。拉取成功后会在本地保存。 101 | 102 | ## 2. 默认配置 103 | SDK自带一套保底默认配置,用户可以调用的API修改保底默认配置,设置的参数可以从云端配置网站获得 ,参数值为明文json字符串。SDK使用配置时,如果云端配置第一次无法获取, 则使用保底默认配置。其他情况仍走之前云端配置逻辑。 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /doc2/webPlayer.md: -------------------------------------------------------------------------------- 1 | ## web端观看 2 | 3 | 由于互动直播是私有协议,需要用旁路推流的方式转成标准的直播协议,这样就可以在web上观看了。
4 | web播放器相关的开发可以参考[web直播播放器](https://www.qcloud.com/document/product/267/5704) 5 | 6 | ## web端消息互动 7 | 8 | 参考[云通信 web sdk](https://www.qcloud.com/document/product/269/1594) 9 | -------------------------------------------------------------------------------- /doc2/互动直播下载页面.md: -------------------------------------------------------------------------------- 1 | 2 | ## 互动直播 3 | 4 | ### 特别提醒 5 | 1. 本页面为下载SDK与示例的统一入口,点击链接会跳转到实际下载页面; 6 | 2. 各平台集成或下载方式各异(如iOS,MAC使用脚本进行下载,Android只需要在Android Stdio中gradle中引入),**跳转到实际下载页面后,请仔细阅读相关的说明**; 7 | 8 | ### SDK+示例下载 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |     17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
平台下载示例源码AVSDK下载可运行示例下载
iOSiLiveSDK V1.8.4随心播源码 QAVSDK_1.9.8App Store
AndroidiLiveSDK V1.8.5随心播源码 QAVSDK_1.9.8应用宝
WindowsiLiveSDK V1.8.5随心播源码 QAVSDK_1.9.8随心播运行程序
Web(IE)iLiveSDK V1.6.0随心播源码/WebDemo(IE浏览器)
MACiLiveSDK V1.8.5随心播源码 QAVSDK_1.9.8随心播运行程序
Demo配套后台随心播后台部署说明随心播后台源码//
61 | -------------------------------------------------------------------------------- /doc2/截图和鉴黄.md: -------------------------------------------------------------------------------- 1 | ## 一 功能说明 * 互动直播后台提供截图和鉴黄两种服务,可以根据需要选择开通。
2 | 截图功能:
3 | 会对用户的上行数据(包括摄像头和屏幕分享)进行截图并存储,支持通过截图回调的方式把截图下载链接发送给用户。
4 | 鉴黄功能:
5 | 会对存储的截图调用腾讯云优图服务来智能鉴黄并给出鉴黄评分,对于涉黄的图片支持通过鉴黄回调的方式通知用户。 6 | * 开通鉴黄服务后,默认开启了大屏监控展示功能,登录[监控后台](http://jh.live.qcloud.com/)后可以看到展示的图片和鉴黄相关信息。 7 | ## 二 控制台设置 #### 1. 开通方法 8 | 9 | ![](https://mc.qcloudimg.com/static/img/5f583de77788f98af47b60a9553c14b5/1.png) 10 | 11 | 在互动直播控制台对需要开通截图鉴黄功能的sdkappid,点击【应用配置】,切换到【鉴黄设置】页面。
默认是关闭状态,点击【编辑】后可以看到启动开关,开启后系统会自动生成一对密钥(secretId和secretKey)供签名使用。 12 | ##### 1.1 开通截图功能 13 | 14 | ![](https://mc.qcloudimg.com/static/img/b70f58eba309927a1c27e823f53e8bcc/2.png) 15 | 用户只开通截图功能默认是必须提供截图回调地址的,截图回调使用方法请参考2.1节。截图频率默认10s,后面会支持4种选择(5s/10s/30s/60s)。填写完成后勾选下面的“同意 《腾讯云服务协议》”并点击【确认】,即开通了截图功能。 16 | ##### 1.2 开通截图+鉴黄功能 用户开通鉴黄功能默认是必须提供鉴黄回调地址的,通过回调来获取图片鉴黄结果,鉴黄回调使用方法请参考3.1节。
17 | 用户可选择是否需要截图回调和操作回调(封停房间用),不需要的话对应的回调地址可以不填。
18 | 填写完成后勾选下面的“同意 《腾讯云服务协议》”并点击【确认】,即开通了截图+鉴黄功能。 #### 2. 获取截图 目前只支持截图回调的方式来获取截图。 ##### 2.1 截图回调服务 ##### 2.1.1 说明 截图回调服务会根据用户提供的截图回调地址,把存储的截图相关信息(用户名,房间号,下载链接等),主动回调给用户。 19 | ##### 2.1.2 接口描述 协议:HTTP
域名:(用户提供回调的域名)
请求类型:POST
数据格式:JSON
20 | * 请求参数说明 21 | 22 | 参数名称 | 是否必选 | 类型 | 描述 23 | :-----: | :-----: | :-----: |:-----: 24 | userid|必选|string|用户名`(经过base64转码,转码后特殊符号‘$’替换成‘$1’,‘\’替换成‘$2’)` groupnum|必选|UInt|房间号 25 | sdkappid|必选|UInt|sdkappid filename|必选|string|文件名 url|必选|string|图片下载链接 timestamp|必选|string|时间戳 sign|必选|string|请求签名,计算方法参加附录 * 返回参数 26 | 参数名称 | 类型 | 描述 27 | :-----: | :-----: |:-----: code|UInt|0:接收成功 1:处理失败 * 示例 请求 28 | ``` { "userid": "dXNlcjE", "groupnum": 123456, "sdkappid": 1400000000 "filename": "dXNlcjE_123456_1400000000_1481701566.jpg", "url": "http://xxx.com/ab_140000000/20161214/dXNlcjE/15/dXNlcjE_123456_1400000000_1481701566.jpg", "timestamp": "1481701566", "sign": "e22fd6bcb979d78933acdc5863f0334a" } ``` 29 | 返回 30 | 31 | ``` { "code": 0 } 32 | ``` 33 | #### 3. 获取自动鉴黄结果 ##### 3.1 鉴黄回调服务 ##### 3.1.1说明 鉴黄回调服务会根据用户提供的鉴黄回调地址,把优图智能鉴黄发现疑似涉黄图片信息(用户名,房间号,下载链接等),主动回调给用户。 34 | ##### 3.1.2接口描述 35 | 协议:HTTP
域名:(用户提供回调的域名)
请求类型:POST
数据格式:JSON
* 请求参数说明
http head部分
鉴黄回调会在http请求头中携带HMAC-SHA1签名,来传递身份验证信息,客户可以通过验证签名进行鉴权。http请求头包含下面3个参数: 36 | 37 | 参数名称 | 是否必选 | 类型 | 描述 38 | :-----: | :-----: |:-----: | :-----: TPD-SecretID |必选|string|生成签名所用的secretId TPD-CallBack-Auth|必选|string|使用 HMAC-SHA1算法计算的签名,计算方法参加附录 TPD-CallBack-Version|必选|string|回调协议的版本号,当前协议的版本为v2 39 | http body部分
40 | 参数名称 | 是否必选 | 类型 | 描述 41 | :-----: | :-----: |:-----: | :-----: userid|必选|string|用户名`(经过base64转码,转码后特殊符号‘$’替换成‘$1’,‘\’替换成‘$2’)` roomId|必选|UInt|房间号 img|必选|string|图片下载链接 type|必选|Array|图片类型。 鉴黄服务判定的鉴黄结果。 0 : 正常图片1 : 色情图片2 : 性感 图片4 : OCR识别恶意 confidence|必选|Number|识别为黄图的置信度,范围0-100;normalScore, hotScore, pornScore的综合评分。confidence大于83定为疑似图片 normalScore|必选|Number|图片为正常图片的评分 hotScore|必选|Number|图片为性感图片的评分 pornScore|必选|Number|图片为色情图片的评分 level|必选|Number|图片的级别 ocrMsg|必选||图片的ocr识别信息(如果有) screenshotTime|必选|Number|截图时间(UNIX时间戳,单位秒) sendTime|必选|Number|请求发送时间,(Unix时间戳,单位秒) abductionRisk|必选|Array|一个包含AbductionRisk结构的数组 * 返回参数 参数名称 | 类型 | 描述 42 | :-----: | :-----: |:-----: code|UInt|0:接收成功 1:处理失败, 2:签名错误 * 示例 43 | HTTP Header部分格式:
44 | 45 | ``` "TPD-SecretID": AYID5JH4f1rYNT1XzIjTMCQCg9QZ "TPD-CallBack-Auth": sSOna1XcIDwgNRSm1b3D6scfFJk= "TPD-CallBack-Version": v2 ``` 输入的数据格式: ``` 46 | { "id": 20001, "roomId" : 234, "userid": "VXNlcg==", "img" : "http://dasdas.***.888", "type" : [1], "confidence" : 10, "normalScore": 0, "pornScore": 100, "hotScore": 0, "level" : 0, "screenshotTime" : 1477366280, "ocrMsg":"" "sign" : "XXXXX" "sendTime":1481010889, "abductionRisk":[ { "level":4, /*风险等级*/ "type":2001 /*风险类型*/ }, { "level":3, "type":2002 } ] } ``` 47 | 返回 48 | 49 | ``` { "code": 0 } ``` 50 | #### 4.使用大屏监控功能 用户开通鉴黄后则默认开启了大屏监控功能,登录[监控后台](http://jh.live.qcloud.com/)可以在大屏监控上看到直播用户的截图和直播旁路推流画面(必须发起旁路推流),可以选择按照鉴黄可疑度进行排序查看。 51 | ##### 4.1 查看图片 52 | 查看方式选择“图片查看”。 ##### 4.2 查看视频 53 | 查看方式选择“视频查看”。 #### 5.费用 54 | 55 | 截图与鉴黄为收费功能,启用后,截图功能按每千张¥0.1元 收费;鉴黄功能按每千张¥1.3元收费。 [查看收费详细说明](https://www.qcloud.com/document/product/268/5129#3..E6.88.AA.E5.9B.BE.E9.89.B4.E9.BB.84.E5.8A.9F.E8.83.BD.E8.AE.A1.E8.B4.B9) 56 | ### 附录 57 | #### 回调签名计算方法 58 | 1. 取http请求body部分的原始字符串 2. 从控制台获取回调秘钥secretKey 3. 使用从控制台获取的secretKey,通过HMACSHA1算法对上面步骤中获得的签名原文字符串计算签名 4. 将生成的签名串二进制内容使用Base64进行编码,获得最终的签名 例如: 假设从http请求获取的body部分如下: 59 | 60 | ```json {"sendTime":1481010889,"tid":20001,"roomId":234,"userId":"TestUser","img":"http://dasdas.***.888","type":[1],"confidence":10,"normalScore":0,"pornScore":100,"hotScore":0,"level":0,"screenshotTime":1477366280,"ocrMsg":"","abductionRisk":[{"level":4,"type":2001},{"level":3,"type":2002}]} ``` 61 | 下面以PHP为例讲解签名的计算过程。 62 | 63 | ```php $secret_key=’6zkty7DvD8vfG3XEkV21VKV8Qpqh6SZK’ $jsonBody=‘{"sendTime":1481010889,"tid":20001,"roomId":234,"userId":"TestUser","img":"http://dasdas.***.888","type":[1],"confidence":10,"normalScore":0,"pornScore":100,"hotScore":0,"level":0,"screenshotTime":1477366280,"ocrMsg":"","abductionRisk":[{"level":4,"type":2001},{"level":3,"type":2002}]}’ $signature = base64_encode(hash_hmac('SHA1',$jsonBody,$secret_key, true)); 64 | ``` 65 | 得到最终的签名。 66 | #### 优图智能鉴黄评分说明 67 | 正常图片评分: 范围0-100。优图对图片判定为正常概率评分,越高说明越符合正常图片;
性感图片评分: 范围0-100。 优图对图片判定为性感概率评分,越高说明图片性感等级越高;
色情图片评分: 范围0-100。 优图对图片判定为性感概率评分,越高说明图片色情等级越高;
黄图置信度: 范围0-100。 综合前面三种评分综合评分大于83定为疑似图片;
建议是使用黄图置信度对黄图进行评判。 -------------------------------------------------------------------------------- /doc2/新老随心播信令兼容文档.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | # 新老随心播信令兼容文档 4 | 5 | 如果您的App已经按老随心播的方式开发完毕并已经上线,如今想切换到iLiveSDK。您需要参考以下方式完成新老信令的兼容(以下以IOS平台为例)。 6 | 7 | ## 1. 迁移老信令到新App 8 | 9 | ``` 10 | //如以下是老随心播的部分信令(以您App的信令为准) 11 | typedef NS_ENUM(NSInteger, AVIMCommand) { 12 | AVIMCMD_Text = -1, // 普通的聊天消息 13 | AVIMCMD_None, // 无事件:0 14 | ...... 15 | AVIMCMD_Multi = 0x800, // 多人互动消息类型 16 | AVIMCMD_Multi_Host_Invite, // 多人主播发送邀请消息 17 | AVIMCMD_Multi_CancelInteract, // 已进入互动时,断开互动 18 | AVIMCMD_Multi_Interact_Join, //同意,C2C消息 19 | AVIMCMD_Multi_Interact_Refuse, //拒绝,C2C消息 20 | ...... 21 | }; 22 | ``` 23 | 24 | ## 2. 进入房间配置为自定义协议并设置消息监听 25 | 26 | ``` 27 | //设置自定义协议为YES 28 | TILLiveRoomOption *option = [TILLiveRoomOption defaultGuestLiveOption]; 29 | option.isCustomProtocol = YES; 30 | 31 | //设置消息监听 32 | TILLiveManager *manager = [TILLiveManager getInstance]; 33 | [manager setAVListener:self]; 34 | }; 35 | ``` 36 | 37 | ## 3. 发送消息或信令 38 | 39 | ``` 40 | - (void)sendText 41 | { 42 | //发送文本消息到老随心播 43 | ILVLiveTextMessage *msg = [[ILVLiveTextMessage alloc] init]; 44 | msg.text = @"text"; 45 | msg.type = ILVLIVE_IMTYPE_GROUP; 46 | [[TILLiveManager getInstance] sendTextMessage:msg succ:nil failed:nil]; 47 | } 48 | 49 | - (void)sendOther 50 | { 51 | //发送其他消息到老随心播,如自定义消息、表情消息等 52 | TIMCustomElem *imCustomElem = [[TIMCustomElem alloc] init]; 53 | [imCustomElem setData:[@"data" dataUsingEncoding:NSUTF8StringEncoding]]; 54 | TIMMessage *imMessage = [[TIMMessage alloc] init]; 55 | [imMessage addElem:imCustomElem]; 56 | [[TILLiveManager getInstance] sendOtherMessage:imMessage toUser:nil succ:nil failed:nil]; 57 | } 58 | ``` 59 | 60 | ## 4. 接受消息或信令 61 | 62 | ``` 63 | - (void)onTextMessage:(ILVLiveTextMessage *)msg 64 | { 65 | //收到老随心波发送的文本消息 66 | } 67 | - (void)onOtherMessage:(TIMMessage *)msg 68 | { 69 | int cnt = [msg elemCount]; 70 | for(int i = 0; i < cnt; i++){ 71 | TIMElem *elem = [msg getElem:i]; 72 | if([elem isKindOfClass:[TIMCustomElem class]]){ 73 | //收到老随心波发送的自定义消息 74 | } 75 | else{ 76 | //其他消息:比如表情、声音等 77 | } 78 | } 79 | } 80 | ``` 81 | 82 | **注意** 83 | > * sendTextMessage和onTextMessage回调对应,sendOtherMessage和onOtherMessage回调对应 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /doc2/直播码升级指南.md: -------------------------------------------------------------------------------- 1 | ## 直播码模式升级指南 2 | 3 | ### 直播码模式的新功能 4 | 5 | 1. 支持自动旁路直播和自动录制,**极大降低了因接口调用时机不对导致旁路直播和录制失败的风险** 6 | 2. 地址生成和直播流有很强的自由度和定制度。 7 | 2. 录制支持多种录制格式、录制完成后事件回调。 8 | 3. 混流的必要条件。 9 | 10 | ## 如何升级直播码模式 11 | 12 | ![](https://mc.qcloudimg.com/static/img/2bcf5926caa034e205b96ad0b85bc24d/C9F9849C-7E9C-4BFA-85EB-CCC266F8B15F.png)
13 | 14 | ## 如何判断当前是频道模式还是直播码模式 15 | 16 | 在腾讯云控制台,选择`直播->直播码接入(推荐)`,如果展现为类似下图,如果展现为类似下图,说明当前还是处于**频道模式**,否则就是**直播码模式**。 17 | 18 | ![](https://mc.qcloudimg.com/static/img/488c132a42470912ec4c49091a041cb9/4.png)
19 | 20 | ### 如果还是频道模式,一定要按照流程图提交工单,不要自己直接在控制台修改成直播码,也不要新建SDKAppID进行测试。 21 | 22 | ## 如何提交直播码兼容模式申请工单 23 | 24 | 1. 在控制台选择发起工单,创建互动直播工单。 25 | 2. 问题类型选择其他问题,问题描述写以下内容: 26 | 27 | * 标题:申请开通直播码兼容模式 28 | * 内容1:公司的appid(注意不是SDKAppID,开发者可在直播控制台或者互动直播控制台上部找到) 29 | * 内容2:是否要在互动直播创建房间的时候自动开始旁路直播 30 | 31 | ## 如何在直播控制台切直播码模式 32 | 33 | 1. 检查直播服务是否开通
34 | 35 | 在[腾讯云控制台上选择`直播`tab](https://console.qcloud.com/live),如果服务还没有开通,则会有如下提示:
36 | ![](https://mc.qcloudimg.com/static/img/c40ff3b85b3ad9c0cb03170948d93555/image.png)
37 | 点击申请开通,之后会进入腾讯云人工审核阶段,审核通过后即可开通。 38 | 39 | 2. 直播服务开通后,在控制台`直播`tab的`接入管理`中选择`直播码接入`。右边的页面中会出现以下几个选项:
40 | 41 | ![](https://mc.qcloudimg.com/static/img/973b21b88bf24bf02eb276c8e0e9efb3/1.png)
42 | 43 | 选项解释如下:
44 | 45 | 配置项 | 取值范围 | 解释| 详细文档 46 | :-----: | :-----: | :-----:|:-----: 47 | 直播录制 | 开启 OR 关闭 | 开启后,只要是旁路直播的视频,都会被录制下来。|[补充文档地址](https://www.qcloud.com/document/product/454/7917) 48 | 推流防盗链key | 32位小写字符串 | 用于计算推流防盗链地址的key|[DOC](https://www.qcloud.com/document/product/454/7917) 49 | API鉴权key | 32位小写字符串 | 业务服务器和腾讯云后台接口互调时,鉴权信息所需的参数|[DOC](https://www.qcloud.com/document/product/454/7920#.E5.AE.89.E5.85.A8.E6.A3.80.E6.9F.A5) 50 | 回调URL | HTTP的URL地址 | 业务服务器回调地址。推流和录制的事件通过此地址通知,不支持HTTPS|[DOC](https://www.qcloud.com/document/product/267/5957) 51 | 52 | 3. 在根据自己的业务配置后,点`确认接入`。即完成了直播码的开通。 53 | 54 | ## 关于直播码模式下的旁路直播自动混流 55 | 56 | 直播码模式下,支持将主播和上麦者的音视频数据混在一路音视频流里播出。
57 | 用户可以在互动直播控制台的`旁路直播配置中选择开启`。 58 | 59 | ### 旁落直播自动混流要注意的点 60 | 61 | 1. 开启自动混流后15分钟后生效 62 | 2. 在app代码中要正确配置主播和上麦观众角色 63 | 3. 目前只支持两路,上麦者固定在右下角 64 | 4. 旁路直播的音视频流混流成功后,对应的录制文件也会混流。 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /doc2/角度方案.md: -------------------------------------------------------------------------------- 1 | 在手机视频的场景中,因为手机可以竖着、横着,四个方向随意旋转,为了保证各种设备互通时观看正常,我们提供了一套角度方案。 # 一、采集角度 2 | 3 | ## 角度定义 4 | 不同平台、不同系统、不同设备定义采集方向的方法不一致,这里统一为采集角度。iOS和Android的后置摄像头角度一致,所以这里以手机后置摄像头为基准;考虑到和PC互通,PC摄像头采集的图像都是横向的,所以把PC摄像头采集的横向角度定义为0。具体定义如下: 5 | 6 | 手机采集 | 视频数据 | 角度值 7 | :--------------------: | :---------------------: | :-------------: 8 | ![h](https://mc.qcloudimg.com/static/img/df42bc04e5362a94d43b1cd57c08a9a2/phone_0.png) | ![f](https://mc.qcloudimg.com/static/img/b9ef73b8bf2dfc8e0b489a6e4f955ea3/frame_0.png) | 0 9 | ![v](https://mc.qcloudimg.com/static/img/a3c5ef84b6cf98930087dcbc172d4289/phone_1.png) | ![f](https://mc.qcloudimg.com/static/img/454e6d4d0c0ed7b11d766d5fa050f4c6/frame_1.png) | 1 10 | ![h](https://mc.qcloudimg.com/static/img/888e0b6d55e5198cd1328eb76307433b/phone_2.png) | ![f](https://mc.qcloudimg.com/static/img/ad426d61381ccafc3b4aa4972adee5ad/frame_2.png) | 2 11 | ![v](https://mc.qcloudimg.com/static/img/263a82b3c74d785159ef5aac0d493396/phone_3.png) | ![f](https://mc.qcloudimg.com/static/img/d5c770e75b9f47cd8440e0a10df396d4/frame_3.png) | 3 12 | 13 | 其中,手机采集的画面为在手机上preview看到的画面,视频数据为传给SDK的数据。因为无论手机怎么旋转,从摄像头得到的数据其实都是横向的数据,只是其中的内容会由于旋转变得不同,所以视频数据中的图都是横向的。 14 | ## 前置摄像头 15 | iOS和Android在前置摄像头上的定义不一致,具体定义如下: 16 | 17 | iOS前置采集 | Android前置采集 | 视频数据 | 角度值 18 | :--------------------: | :--------------------: | :---------------------: | :-------------: 19 | ![h](https://mc.qcloudimg.com/static/img/888e0b6d55e5198cd1328eb76307433b/phone_2.png) | ![h](https://mc.qcloudimg.com/static/img/df42bc04e5362a94d43b1cd57c08a9a2/phone_0.png) | ![f](https://mc.qcloudimg.com/static/img/b9ef73b8bf2dfc8e0b489a6e4f955ea3/frame_0.png) | 0 20 | ![v](https://mc.qcloudimg.com/static/img/a3c5ef84b6cf98930087dcbc172d4289/phone_1.png) | ![v](https://mc.qcloudimg.com/static/img/263a82b3c74d785159ef5aac0d493396/phone_3.png) | ![f](https://mc.qcloudimg.com/static/img/454e6d4d0c0ed7b11d766d5fa050f4c6/frame_1.png) | 1 21 | ![h](https://mc.qcloudimg.com/static/img/df42bc04e5362a94d43b1cd57c08a9a2/phone_0.png) | ![h](https://mc.qcloudimg.com/static/img/888e0b6d55e5198cd1328eb76307433b/phone_2.png) | ![f](https://mc.qcloudimg.com/static/img/ad426d61381ccafc3b4aa4972adee5ad/frame_2.png) | 2 22 | ![v](https://mc.qcloudimg.com/static/img/263a82b3c74d785159ef5aac0d493396/phone_3.png) | ![v](https://mc.qcloudimg.com/static/img/a3c5ef84b6cf98930087dcbc172d4289/phone_1.png) | ![f](https://mc.qcloudimg.com/static/img/d5c770e75b9f47cd8440e0a10df396d4/frame_3.png) | 3 23 | 24 | 25 | ## 锁定旋转 26 | iOS和Android手机都有锁定自动旋转的功能。 27 | 28 | 目前的实现是,当锁定旋转时,Android的角度表现不会发生变化,还是有旋转的效果;iOS的角度会固定为1,无论是竖屏锁定还是横屏锁定,角度都会重置为竖屏状态的1。 29 | 30 | > 锁定的实现,后续会做下优化,争取iOS和Android的表现能统一,并且支持横屏的锁定。 31 | ## API设置 32 | 33 | ### iOS Capture 34 | iOS的采集角度不用设置,SDK内部实现。 35 | 36 | ### Android Capture 37 | Android需要通过重力感应事件把当前的手机旋转角度传给SDK。 38 | 39 | ```java 40 | AVVideoCtrl avVideoCtrl = AVContextModel.getInstance().getAVContext().getVideoCtrl(); 41 | avVideoCtrl.setRotation(rotation); 42 | ``` 43 | # 二、视频绘制 44 | 视频数据在编码传输、接收解码的整个过程中,不会做旋转处理,一直保持为横向数据。采集端的角度信息,一直透传到接受端的渲染模块。渲染模块在绘制远端视频时,会根据采集角度和当前设备的旋转角度,先对视频画面进行旋转,再绘制出来,保证观看到的是角度正常的视频画面。 45 | 46 | 视频数据 | 正常观看 | 左旋观看 | 右旋观看 | 倒置观看 | :------------------------------------------: | :--------------------: | :---------------------: | :---------------------: | :--------------------: | 47 | ![sf](https://mc.qcloudimg.com/static/img/b9ef73b8bf2dfc8e0b489a6e4f955ea3/frame_0.png) ![sf](https://mc.qcloudimg.com/static/img/ad426d61381ccafc3b4aa4972adee5ad/frame_2.png)| ![v](https://mc.qcloudimg.com/static/img/cdb2f8ec5e6708ea2fd3d950048bbacc/watch_up.png)| ![h](https://mc.qcloudimg.com/static/img/df42bc04e5362a94d43b1cd57c08a9a2/phone_0.png) | ![h](https://mc.qcloudimg.com/static/img/888e0b6d55e5198cd1328eb76307433b/phone_2.png) | ![v](https://mc.qcloudimg.com/static/img/44e9bfbc3f196916de78fb256127ea65/watch_down.png)| 48 | ![sf](https://mc.qcloudimg.com/static/img/454e6d4d0c0ed7b11d766d5fa050f4c6/frame_1.png) ![sf](https://mc.qcloudimg.com/static/img/d5c770e75b9f47cd8440e0a10df396d4/frame_3.png)| ![v](https://mc.qcloudimg.com/static/img/a3c5ef84b6cf98930087dcbc172d4289/phone_1.png) |![h](https://mc.qcloudimg.com/static/img/3bb4183b2412532910d08f97b3771c36/watch_left.png)|![h](https://mc.qcloudimg.com/static/img/96aae9236078f9b0ef043cf201a68508/watch_right.png)|![v](https://mc.qcloudimg.com/static/img/263a82b3c74d785159ef5aac0d493396/phone_3.png) | 49 | 50 | ## 锁定旋转 51 | iOS和Android手机都有锁定自动旋转的功能。当锁定旋转时,也会影响视频绘制的角度。 52 | 53 | 目前的实现是,当锁定旋转时,Android的视频绘制表现不会发生变化,还是有旋转的效果;iOS的绘制表现会固定为正常观看,无论是竖屏锁定还是横屏锁定,都会重置为正常观看的竖屏观看状态。 54 | 55 | > 锁定的实现,后续会做下优化,争取iOS和Android的表现能统一,并且支持锁定下的横屏观看。 56 | 57 | ## API设置 58 | 59 | ### iOS Render 60 | iOS的渲染需要业务层做好角度的处理,示例代码如下: 61 | 62 | ```Obj-C 63 | #pragma mark remoteVideoDelegate 64 | -(void)OnVideoPreview:(QAVVideoFrame*)frameData{ 65 | int peerRotate = frameData.frameDesc.rotate; 66 | int selfRotate = 0; 67 | UIInterfaceOrientation currentOri=(UIInterfaceOrientation)[[UIDevice currentDevice] orientation]; 68 | switch (currentOri) { 69 | case UIDeviceOrientationPortrait: 70 | selfRotate = 0; 71 | break; 72 | case UIDeviceOrientationLandscapeLeft: 73 | selfRotate = 1; 74 | break; 75 | case UIDeviceOrientationLandscapeRight: 76 | selfRotate = 3; 77 | break; 78 | case UIDeviceOrientationPortraitUpsideDown: 79 | selfRotate = 2; 80 | break; 81 | default: 82 | 83 | break; 84 | } 85 | frameData.frameDesc.rotate = (selfRotate + peerRotate ) % 4; 86 | ... ... 87 | } 88 | ``` 89 | ### Android Render 90 | Android需要通过重力感应事件把当前的手机旋转角度传给SDK,SDK内部处理采集角度的调整逻辑。 91 | 92 | ```java 93 | AVVideoCtrl avVideoCtrl = AVContextModel.getInstance().getAVContext().getVideoCtrl(); 94 | avVideoCtrl.setRotation(rotation); 95 | ``` 96 | -------------------------------------------------------------------------------- /doc2/随心播后台.markdown: -------------------------------------------------------------------------------- 1 | # 随心播 Server QuickStart 2 | 3 | ## 1. 代码部署 4 | 5 | ### 1.1 搭建PHP和数据库环境 6 | 7 | #### 服务器环境要求 8 | 9 | * PHP >= 5.4 10 | * MySQL >= 5.5.3 11 | 12 | ### 1.2 修改配置 13 | 14 | * 下载代码,部署到php目录中 15 | * 在lib/db/DBConfig.php填写mysql的数据库url、用户名和密码 16 | * 调整server/account/AccountLoginCmd.php为自己互动直播的SDKAPPID: 17 | 18 | ```php 19 | const SDKAPPID = '1400019352'; 20 | ``` 21 | * 修改deps/bin/tls_licence_tools具有可执行权限,用于生产userSig 22 | * 修改deps/sig目录权限,使得其他用户有可读写执行权限(chmod 757 deps/sig),用于生成sig临时文件的目录,将用于生成和校验sig的公私钥放置于此目录。
23 | 如果用户自定义置于其他目录,则需要修改server/account/AccountLoginCmd.php为自定义路径,保证这些文件至少具有可读权限。 24 | 25 | ```php 26 | $private_key = DEPS_PATH . '/sig/private_key'; 27 | $public_key = DEPS_PATH . '/sig/public_key'; 28 | ``` 29 | 30 | * 如果您在使用直播码进行旁路推流,调整server/live/ReportLiveRoomInfoCmd.php代码的BIZID。 31 | 32 | ```php 33 | const BIZID = '123456'; 34 | ``` 35 | 36 | * 如果想使用图片上传功能,需要开通腾讯云COS服务,并在deps/cos-php-sdk/Conf.php填写对应APPID、SecretKey和SecretID。 37 | 38 | ### 1.3 数据库建表建库 39 | 40 | 执行sxb_db.sql文件中的sql。 41 | 42 | ## 2. 代码目录结构 43 | 44 | ![](https://mc.qcloudimg.com/static/img/0413205b36b65645ef4a5ddd8135198c/2.png) 45 | 46 | ### 2.1 service 47 | 48 | 服务层,也就是接口层,主要包括:账号管理,直播服务、AV房间服务、COS服务。每个服务(亦即模块)下是各个子接口。详细可参看协议文档。 49 | 50 | #### 2.1.1 直播服务 51 | 52 | - 开始直播:数据库Replace一条记录,注意一个用户同一时间最多只能有一场直播; 53 | - 直播结束:从数据库中删除记录; 54 | - 直播列表:从数据库分页获取直播列表; 55 | - 直播心跳包:客户端10秒发一次心跳包更新数据。 56 | 57 | #### 2.1.2 Cos服务 58 | 59 | 获取Cos签名。 60 | 61 | #### 2.1.3 AvRoom服务 62 | 63 | 获取AV房间号。 64 | 65 | 66 | ### 2.2 model 67 | 68 | 数据层。 69 | 70 | ### 2.3 client-data 71 | 72 | 客户端数据对象层,主要用于接收和返回给客户端的数据对象。 73 | 74 | ### 2.4 lib 75 | 76 | 包括数据库和日志等库。 77 | 78 | ### 2.5 deps 79 | 80 | 依赖库和依赖程序和文件,主要是其他项目或者SDK,比如腾讯云COS SDK。 81 | 82 | ### 2.6 cron 83 | 后台定时任务。清理90秒没有发心跳包的直播记录。可以crontab定时执行。 84 | 85 | ## 3. 再次强调 86 | 87 | * sig目录其他用户一定要有读写可执行权限 88 | * deps/bin/tls_licence_tools签名程序一定可执行权限 89 | * 调整为自己的SDKAPPID和私钥公钥路径 -------------------------------------------------------------------------------- /ios自定义画面采集流程文档.md: -------------------------------------------------------------------------------- 1 | ## 简介 ## 2 | 本文档主要针对[AVSDK](https://www.qcloud.com/product/ilvb.html)自定义采集画面流程做详细讲解,自定义采集画面的用途主要用于预处理原始数据,比如用户需要人脸识别,画面美化,动效处理等,如下是通过自定义采集画面后,增加动效效果图: 3 | ![](http://img.blog.csdn.net/20160914113734996) 4 | **注:动效效果是用户自己增加的,和本文档无关,用户可以对原始数据做任何预处理(不仅是动效)** 5 | 6 | 7 | ## 流程说明 ## 8 | 首先请记住,若要使用自定义采集画面,则采集画面的过程与AVSDK没有任何关系,完全不依赖AVSDK,自定义采集画面的流程中,AVSDK的作用是透传数据以及渲染远程数据。而本文介绍的流程是:***自定义采集画面->画面传入AVSDK->远程端收到画面帧渲染*** 的整个过程,流程图如下: 9 | ![](http://img.blog.csdn.net/20160914112952279) 10 | 11 | 12 | ## 采集前准备 ## 13 | ***进入房间之后,采集画面之前***, 14 | 调用 `[videoCtrl enableExternalCapture:YES];` 15 | `videoCtrl`是`QAVVideoCtrl`对象的实例,在此方法返回`QAV_OK`之后才能进行下一步,此方法告诉AVSDK,你需要自定义采集画面,且你将会把采集到的画面传给AVSDK,以AVSDK做画面数据传输通道,用了此方法之后,***不能***再调用AVSDK的打开摄像头接口,且AVSDK的美白,美颜将不再生效。 16 | 17 | ## 自定义采集 ## 18 | 通过`AVCaptureSession`采集画面,实现`AVCaptureVideoDataOutputSampleBufferDelegate`代理,采集到的画面会在 19 | `- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection` 20 | 回调中吐出,吐出的是原始画面,用户可以在这里对原始画面做任何预处理,当然,渲染也和AVSDK没有任何关系,本地画面只需要设置`AVCaptureVideoPreviewLayer`即可显示,采集画面和渲染是iOS基础API的调用,不做过多描述。 21 | 22 | ## 采集后处理 ## 23 | 接收到系统回吐出的原始数据(`CMSampleBufferRef`类型数据),用户就可以对其做预处理,比如美白,美颜,人脸识别等,预处理之后的画面需要用户自己完成渲染,与AVSDK无任何关系。 24 | 25 | ## AVSDK透传 ## 26 | 通过上面步骤,得到采集后处理的数据,传入AVSDK需调用接口 27 | ` QAVResult result = [videoCtrl fillExternalCaptureFrame:frame];` 28 | `videoCtrl`是`QAVVideoCtrl`对象的实例,`frame`是采集后处理过的数据转换成的`QAVVideoFrame`对象,`result`为`QAV_OK`,说明成功传入AVSDK,否则失败,需要检查前面的流程是否都正确了。 29 | 30 | ## 远端渲染 ## 31 | AVSDK的回调接口 32 | `-(void)OnVideoPreview:(QAVVideoFrame*)frameData` 33 | 接收远程帧数据,再使用AVSDK的开放类`AVGLBaseView`渲染画面,这里的渲染用户只需要设置一个渲染视图,不需要做额外的操作,详情可参考[随心播](https://github.com/zhaoyang21cn/iOS_Suixinbo)的渲染逻辑。 34 | 35 | ## 注意事项 ## 36 | 1、如果渲染自定义采集的画面使用了OpenGL,则不能使用AVSDK中开放的`AVGLBaseView`作为渲染视图,否则会Crash。也就是说,此时界面上应该有两个view,一个渲染自定义采集的画面,另一个渲染`QAVVideoFrame`对象。 37 | 2、转换成`QAVVideoFrame`时,属性`color_format`必需填写`AVCOLOR_FORMAT_NV12` 38 | `srcType`属性必须填写`QAVVIDEO_SRC_TYPE_CAMERA` -------------------------------------------------------------------------------- /大咖模式.md: -------------------------------------------------------------------------------- 1 | # 大咖模式 2 | ![](http://mc.qcloudimg.com/static/img/5c61520f52804727dc7c06d9a1818c2f/image.png) 3 | --- 4 | ### 1、主播端 5 | #### 1.1 创建IM聊天室 6 | 使用ImSDK的接口创建聊天室,观众可进入聊天室中聊天,但此时主播端无音视频数据 7 | ``` 8 | [[TIMGroupManager sharedInstance] CreateGroup:@"AVChatRoom" members:nil groupName:@"groupName" groupId:groupId succ:^(NSString *groupId) { 9 | NSLog(@"保存成功回调的groupId,在1.3步骤中需要用到"); 10 | } fail:^(int code, NSString *msg) { 11 | NSLog(@"创建群组失败,打印code和msg分析原因"); 12 | }]; 13 | ``` 14 | #### 1.2 创建音视频房间 15 | 使用TILILiveSDK的接口创建音视频房间,主播开始音视频数据上行 16 | ``` 17 | TILLiveRoomOption *option = [TILLiveRoomOption defaultHostLiveOption]; 18 | option.imOption.imSupport = NO;//创建音视频房间是必须把imSupport配置项设置为NO 19 | 20 | [[TILLiveManager getInstance] createRoom:roomId option:option succ:^{ 21 | NSLog(@"创建音视频房间成功,在这里开始1.3步骤"); 22 | } failed:^(NSString *module, int errId, NSString *errMsg) { 23 | NSLog(@"创建音视频房间失败,打印errId和errMsg分析错误原因"); 24 | }]; 25 | ``` 26 | #### 1.3 绑定IM聊天室和音视频房间 27 | 使用ILiveSDK的接口绑定IM聊天室和音视频房间,绑定之后,聊天室和音视频房间则合成为一个房间 28 | ``` 29 | int result = [[ILiveRoomManager getInstance] bindIMGroupId:groupid]; 30 | if (result == 0) 31 | { 32 | NSLog(@"绑定成功,在这里开始1.4步骤"); 33 | } 34 | ``` 35 | #### 1.4 发送大咖进房群组消息 36 | 使用TILLiveSDK的接口发送自定义消息,通知观众,主播进入直播间开始直播了(大咖来了,观众接收到这个消息的时候会进入音视频房间,参考2.2) 37 | ``` 38 | //发送群消息,通知观众进入音视频房间 39 | ILVLiveCustomMessage *inAvRoomMsg = [[ILVLiveCustomMessage alloc] init]; 40 | inAvRoomMsg.type = ILVLIVE_IMTYPE_GROUP; 41 | inAvRoomMsg.cmd = ILVLIVE_IMCMD_BigCast_ENTER;//自定义的消息命令字 42 | NSString *roomStr = [@(roomId) stringValue]; 43 | inAvRoomMsg.data = [roomStr dataUsingEncoding:NSUTF8StringEncoding]; 44 | [[TILLiveManager getInstance] sendCustomMessage:inAvRoomMsg succ:^{ 45 | NSLog(@"发送成功,观众端接收到此消息,做进入音视频房间的操作"); 46 | } failed:^(NSString *module, int errId, NSString *errMsg) { 47 | NSLog(@"发送消息失败,打印errId和errMsg分析原因"); 48 | }]; 49 | ``` 50 | #### 1.5 主播退出 51 | ##### 1.5.1 退出IM聊天室 52 | 主播端退出IM聊天室之前,先发送一个退群消息,让其他观众感知到主播已经离开,观众也退群,再使用ImSDK的接口删除IM聊天室。 53 | ``` 54 | ILVLiveCustomMessage *customMsg = [[ILVLiveCustomMessage alloc] init]; 55 | customMsg.type = ILVLIVE_IMTYPE_GROUP; 56 | customMsg.recvId = [[ILiveRoomManager getInstance] getIMGroupId]; 57 | customMsg.cmd = (ILVLiveIMCmd)AVIMCMD_ExitLive; 58 | [[TILLiveManager getInstance] sendCustomMessage:customMsg succ:^{ 59 | NSLog(@"发送退群消息成功,在这里开始退出聊天室"); 60 | int result = [[TIMGroupManager sharedInstance] DeleteGroup:groupId succ:^{ 61 | NSLog(@"主播退出IM聊天室成功"); 62 | } fail:^(int code, NSString *msg) { 63 | NSLog(@"主播退出IM聊天室失败,打印code和msg分析原因"); 64 | }]; 65 | if(result != 0) 66 | { 67 | NSLog(@"主播退出IM聊天室失败,打印result分析原因"); 68 | } 69 | } failed:^(NSString *module, int errId, NSString *errMsg) { 70 | NSLog(@"发送退群消息失败,打印errId和errMsg分析原因"); 71 | }]; 72 | ``` 73 | ##### 1.5.2 退出音视频房间 74 | 使用TILLiveSDK的接口退出音视频房间 75 | ``` 76 | [[TILLiveManager getInstance] quitRoom:^{ 77 | NSLog(@"退出直播间成功"); 78 | } failed:^(NSString *module, int errId, NSString *errMsg) { 79 | NSLog(@"退出直播间失败,打印eerrId和errMsg分析原因"); 80 | }] 81 | ``` 82 | ---- 83 | ### 2、观众端 84 | #### 2.1 加入IM聊天室 85 | 使用ImSDK的接口加入聊天室,此时观众是看不到主播画面的,因为主播还没有创建音视频房间,观众只能在聊天室里面聊天。 86 | ``` 87 | int result = [[TIMGroupManager sharedInstance] JoinGroup:groupId msg:nil succ:^{ 88 | NSLog(@"加入聊天室成功"); 89 | } fail:^(int code, NSString *msg) { 90 | if (code == ILIVE_IM_ALREADYINGROUP)//已经是群成员 91 | { 92 | NSLog(@"加入聊天室成功"); 93 | } 94 | else 95 | { 96 | NSLog(@"加入聊天室失败,打印code和msg分析原因"); 97 | } 98 | }]; 99 | if (result != 0) 100 | { 101 | NSLog(@"加入聊天室失败,打印result分析原因"); 102 | } 103 | ``` 104 | #### 2.2 加入音视频房间 105 | 当观众收到主播加入音视频房间的的消息时(本文档中1.4的ILVLIVE_IMCMD_BigCast_ENTER),使用TILLiveSDK的接口加入音视频房间。 106 | ``` 107 | TILLiveRoomOption *option = [TILLiveRoomOption defaultGuestLiveOption]; 108 | option.imOption.imSupport = NO;//加入音视频房间是必须把imSupport配置项设置为NO 109 | 110 | [[TILLiveManager getInstance] joinRoom:roomId option:option succ:^{ 111 | NSLog(@"加入音视频房间成功,在这里开始执行2.3"); 112 | } failed:^(NSString *module, int errId, NSString *errMsg) { 113 | NSLog(@"加入音视频房间失败,打印errId和errMsg分析原因"); 114 | }]; 115 | ``` 116 | #### 2.3 绑定IM聊天室和音视频房间 117 | 使用ILiveSDK的接口绑定IM聊天室和音视频房间,绑定之后,聊天室和音视频房间则合成为一个房间 118 | ``` 119 | int result = [[ILiveRoomManager getInstance] bindIMGroupId:groupid]; 120 | if (result == 0) 121 | { 122 | NSLog(@"绑定成功。到此为止,从主播创建大咖模式房间到观众最终看到大咖视频画面的流程已经结束"); 123 | } 124 | ``` 125 | #### 2.4 观众退出 126 | ##### 2.4.1 退出IM聊天室 127 | 用TILLiveSDK的代理接口`- (void)onCustomMessage:(ILVLiveCustomMessage *)msg`收消息,收到主播退出IM聊天室的消息后(本文当中1.5.1的AVIMCMD_ExitLive),用IM接口退出聊天室 128 | ``` 129 | int result = [[TIMGroupManager sharedInstance] DeleteGroup:groupId succ:^{ 130 | NSLog(@"观众退出IM聊天室成功"); 131 | } fail:^(int code, NSString *msg) { 132 | if (code == 10015)//群组id无效 133 | { 134 | NSLog(@"观众端返回这个错误码,可以认为是退出聊天室成功,因为观众端退聊天室时,极有可能主播已经解散了这个聊天室,导致观众这边的聊天室id已经无效"); 135 | } 136 | else 137 | { 138 | NSLog(@"观众退出IM聊天室失败,打印code和msg分析原因"); 139 | } 140 | }]; 141 | if(result != 0) 142 | { 143 | NSLog(@"主播退出IM聊天室失败,打印result分析原因"); 144 | } 145 | ``` 146 | ##### 2.4.2 退出音视频房间 147 | 使用TILLiveSDK的接口退出音视频房间 148 | ``` 149 | [[TILLiveManager getInstance] quitRoom:^{ 150 | NSLog(@"退出直播间成功"); 151 | } failed:^(NSString *module, int errId, NSString *errMsg) { 152 | NSLog(@"退出直播间失败,打印eerrId和errMsg分析原因"); 153 | }] 154 | ``` 155 | --- 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /屏幕旋转方案.md: -------------------------------------------------------------------------------- 1 | #腾讯互动直播视频旋转方案 2 | ##前言 3 | 本文用于介绍开发[腾讯互动直播](https://www.qcloud.com/product/ilvb.html)时可选用的三种视频旋转模式。开发前请参考[ILiveSDKAndroidDemos](https://github.com/zhaoyang21cn/ILiveSDK\_Android\_Demos)或者[ILiveSDKiosDemos](https://github.com/zhaoyang21cn/ILiveSDK\_ios\_Demos),导入ILiveSDK。 4 | ##方案详细介绍 5 | ###方案一:智能旋转模式 6 | ####简述 7 | 智能旋转方案保证显示的视频(包括观众端和主播端等任意角色)始终是正向画面(以主播眼睛看到的上下顺序为准)。视频会自适应到界面View中。 8 | ####效果 9 | 主播(镜像) | 观众横屏 | 观众竖屏 10 | ------------- | ------------- | ------------- 11 |
![](http://i.imgur.com/joPDT4x.jpg)
| ![](http://i.imgur.com/Sl46TRR.jpg) | ![](http://i.imgur.com/Fparsn8.jpg)| 12 |
![](http://i.imgur.com/VQARU6x.jpg)
| ![](http://i.imgur.com/ecKNaF0.jpg) | ![](http://i.imgur.com/iVhHNJn.jpg)| 13 | 14 | ####Android实现方式 15 | 1.在工程中导入iLiveSDK 16 | 2.获取布局中的AVRootView 17 | 18 | avRootView = (AVRootView) findViewById(R.id.av_root_view); 19 | 3.把AVRootView中指定的AVVideoView的旋转方案设置为ILiveConstants.ROTATION_AUTO,该设置可以随时修改,立即生效 20 | 21 | avRootView.getViewByIndex(i).setRotationMode(ILiveConstants.ROTATION_AUTO); 22 | ####iOS实现方式: 23 | 24 | glView.iLiveRotationType = ILiveRotation_Auto; 25 | 默认是ILiveRotation_Auto,可在任何时候设置,设置即生效,glView是AVGLCustomRenderView对象,即渲染视图 26 | ###方案二:全屏模式 27 | ####简述 28 | 全屏模式保证观众端始终看到全屏画面,并尽量保证观众看到更多的图像。 29 | ####效果 30 | 主播(镜像) | 观众横屏 | 观众竖屏 31 | ------------- | ------------- | ------------- 32 | ![](http://i.imgur.com/joPDT4x.jpg)| ![](http://i.imgur.com/Sl46TRR.jpg) | ![](http://i.imgur.com/TFptGcz.jpg)| 33 |
![](http://i.imgur.com/VQARU6x.jpg)
| ![](http://i.imgur.com/BeUSd3g.jpg) | ![](http://i.imgur.com/iVhHNJn.jpg)| 34 | ####Android实现方式 35 | 1.在工程中导入iLiveSDK 36 | 2.获取布局中的AVRootView 37 | 38 | avRootView = (AVRootView) findViewById(R.id.av_root_view); 39 | 3.把AVRootView中指定的AVVideoView的旋转方案设置为ILiveConstants.ROTATION_FULL_SCREEN,该设置可以随时修改,立即生效 40 | 41 | avRootView.getViewByIndex(i).setRotationMode(ILiveConstants.ROTATION_FULL_SCREEN); 42 | ####iOS实现方式 43 | 44 | glView.iLiveRotationType = ILiveRotation_FullScreen; 45 | 可在任何时候设置,设置即生效,glView是AVGLCustomRenderView对象,即渲染视图 46 | 47 | ###方案三:裁剪模式 48 | 裁剪模式1:(Android和iOS都有) 49 | 画面源端的设备**关闭**系统的“竖排方向锁定”开关,即**支持横竖屏自由旋转**时,保证观众端始终看到全屏画面,并保证始终是正向画面(以主播眼睛看到的上下顺序为准),超出显示范围的图像会被裁剪。: 50 | ####效果 51 | 主播(镜像) | 观众横屏 | 观众竖屏 52 | :-------------: | :-------------: | :-------------: 53 | ![](http://i.imgur.com/joPDT4x.jpg)| ![](http://i.imgur.com/Sl46TRR.jpg) | ![](http://i.imgur.com/WP4tvCY.png)| 54 | ![](http://i.imgur.com/VQARU6x.jpg)| ![](http://i.imgur.com/DdNC21E.png) | ![](http://i.imgur.com/iVhHNJn.jpg)| 55 | 56 | 裁剪模式2:(iOS独有) 57 | 画面源端的设备**打开**系统的:“竖排方向锁定”开关,即**不支持横竖屏的自由旋转**时,保证观众端始终看到全屏画面,但**不保证**看到的始终是正向画面,超出显示范围的图像会被裁剪: 58 | ####效果 59 | 主播(镜像) | 观众横屏 | 观众竖屏 60 | :-------------: | :-------------: | :-------------: 61 | ![](http://i.imgur.com/joPDT4x.jpg)| ![](http://i.imgur.com/Sl46TRR.jpg) |![](http://img.blog.csdn.net/20160901173326383) | 62 | ![](http://i.imgur.com/VQARU6x.jpg)| ![](http://img.blog.csdn.net/20160901174427957) |![](http://i.imgur.com/iVhHNJn.jpg)| 63 | ####Android实现方式 64 | 1.在工程中导入iLiveSDK 65 | 2.获取布局中的AVRootView 66 | 67 | avRootView = (AVRootView) findViewById(R.id.av_root_view); 68 | 3.把AVRootView中指定的AVVideoView的旋转方案设置为ILiveConstants.ROTATION_CROP,该设置可以随时修改,立即生效 69 | 70 | avRootView.getViewByIndex(i).setRotationMode(ILiveConstants.ROTATION_CROP); 71 | 72 | ####iOS实现方式 73 | 74 | glView.iLiveRotationType = ILiveRotation_Crop; 75 | 可在任何时候设置,设置即生效,glView是AVGLCustomRenderView对象,即渲染视图 -------------------------------------------------------------------------------- /随心播/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/.DS_Store -------------------------------------------------------------------------------- /随心播/Android随心播集成/ILVCallManager.md: -------------------------------------------------------------------------------- 1 | # 视频聊天快速接入 2 | ------ 3 | 该业务旨在为开发者提供双人视频,乃至多人视频会议的服务 4 | 5 | ##初始化 6 | 在初始化时可以配置呼叫超时时间、忙时(通话过程中)自动拒接。 7 | 为保证收到来电消息,需要配置来电回调 8 | ```java 9 | ILVCallManager.getInstance().init(new ILVCallConfig() 10 | .setTimeOut(30) // 超时时间为30秒 11 | .setAutoBusy(true)); // 忙时自动拒接模式 12 | ILVCallManager.getInstance().addIncomingListener(this); 13 | ``` 14 | 15 | ##发起呼叫 16 | 发起通话时,直接调用makeCall,填入对方的id即可发起呼叫 17 | 可以通过setCallType设置通话类型(*纯语音呼叫也是可以的哦*) 18 | ```java 19 | ILVCallOption option = new ILVCallOption(ILiveLoginManager.getInstance().getMyUserId()) 20 | .callTips("重要电话") // 电话描述 21 | .setCallType(ILVCallConstants.CALL_TYPE_VIDEO); // 视频电话 22 | int callId = ILVCallManager.getInstance().makeCall(remoteId, option); 23 | if (ILiveConstants.INVALID_INTETER_VALUE != callId) { 24 | // 呼叫成功 25 | ... 26 | } 27 | ``` 28 | 29 | ##接听来电 30 | 在收到来电时,会进入onNewIncomingCall或onNewMutiIncomingCall(多人) 31 | 此时可以调用acceptCall或rejectCall进行接听或拒接 32 | ```java 33 | @Override 34 | public void onNewIncomingCall(int callId, final int callType, final String fromUserId, String strTips, String strCustom, long timeStamp){ 35 | if (0 == ILVCallManager.getInstance().acceptCall(mCurIncomingId, new ILVCallOption(fromUserId).setCallType(callType))) { 36 | // 接听成功 37 | } 38 | } 39 | ``` 40 | 41 | ##通话回调 42 | 对于通话可以设置回调来获取通话状态 43 | ```java 44 | ILVCallManager.getInstance().addCallListener(new ILVCallListener() { 45 | @Override 46 | public void onCallEstablish(int callId) { 47 | // 通话建立成功 48 | } 49 | 50 | @Override 51 | public void onCallEnd(int callId, int endResult, String endInfo) { 52 | // 通话结束 53 | } 54 | 55 | @Override 56 | public void onException(int iExceptionId, int errCode, String errMsg) { 57 | // 通话异常情况捕获 58 | } 59 | }); 60 | ``` 61 | 更多接口参考[API文档](https://zhaoyang21cn.github.io/ilivesdk_help/android_help/) 62 | -------------------------------------------------------------------------------- /随心播/Android随心播集成/ILVLiveManager.md: -------------------------------------------------------------------------------- 1 | #iLiveSDK直播基础接口简介 2 | ##简单直播流程示例 3 | 4 | ![](http://mc.qcloudimg.com/static/img/e6632b362fbc90745505823b1dc295bd/image.png) 5 | 6 | 7 | ###1 ILiveSDK初始化 8 | 9 | | 接口名| 接口描述 | 10 | |---------|---------| 11 | | **initSDK** | iLiveSDK的部分类的预初始化,是所有行为的第一步,告知身份appId| 12 | 13 | 14 | | 参数类型| 说明 | 15 | |---------|---------| 16 | | Conext | 建议用AppcalicationContext | 17 | | int | 传入业务方appid | 18 | | int | 传入业务方 accounttype | 19 | 20 | *示例 21 | 22 | ```java 23 | ILiveSDK.getInstance().initSdk(getApplicationContext(), appid, accoutype); 24 | ``` 25 | 26 | 27 | ###2 账号登录 28 | | 接口名| 接口描述 | 29 | |---------|---------| 30 | | **iLiveLogin** | 使用托管方式或独立模式,在获取到用户的sig后,使用登录接口,告知后台音视频模块上线了(包括avsdk)| 31 | 32 | | 参数类型| 说明 | 33 | |---------|---------| 34 | | String | 用户id,在直播过程中的唯一标识 | 35 | | String | 鉴权的密钥Sig 如果是独立登录方式,是业务方后台计算生成后下发的| 36 | | ILiveCallBack | 帐号登录回调接口。通知上线是否成功 | 37 |
38 | *示例 39 | 40 | ```java 41 | ILiveLoginManager.getInstance().iLiveLogin(ILiveSDK.getInstance().getMyUserId(), "123456", new ILiveCallBack() { 42 | @Override 43 | public void onSuccess(Object data) { 44 | bLogin = true; 45 | Toast.makeText(ContactActivity.this, "login success !", Toast.LENGTH_SHORT).show(); 46 | } 47 | 48 | @Override 49 | public void onError(String module, int errCode, String errMsg) { 50 | Toast.makeText(ContactActivity.this, module + "|login fail " + errCode + " " + errMsg, Toast.LENGTH_SHORT).show(); 51 | } 52 | }); 53 | ``` 54 | ###3 创建房间 55 | 56 | | 接口名| 接口描述 | 57 | |---------|---------| 58 | | **createRoom** | 创建一个直播,只有在初始化和登录成功之后才能创建直播| 59 | 60 | | 参数类型| 说明 | 61 | |---------|---------| 62 | | int | 房间id 房间唯一标识 建议由业务方后台统一分配 | 63 | | ILiveRoomOption | 房间配置项 可以设置角色 权限 主播ID 摄像头参数等 具体参考类ILiveRoomOption | 64 | | ILiveCallBack | 创建房间回调接口。通知创建房间是否成功 | 65 | 66 | ```java 67 | //创建房间配置项 68 | ILiveRoomOption hostOption = new ILiveRoomOption(null). 69 | controlRole("Host")//角色设置 70 | .authBits(AVRoomMulti.AUTH_BITS_DEFAULT)//权限设置 71 | .cameraId(ILiveConstants.FRONT_CAMERA)//摄像头前置后置 72 | .videoRecvMode(AVRoomMulti.VIDEO_RECV_MODE_SEMI_AUTO_RECV_CAMERA_VIDEO);//是否开始半自动接收 73 | //创建房间 74 | ILiveRoomManager.getInstance().createRoom(room, hostOption, new ILiveCallBack() { 75 | @Override 76 | public void onSuccess(Object data) { 77 | Toast.makeText(LiveActivity.this, "create room ok", Toast.LENGTH_SHORT).show(); 78 | } 79 | 80 | @Override 81 | public void onError(String module, int errCode, String errMsg) { 82 | Toast.makeText(LiveActivity.this, module + "|create fail " + errMsg + " " + errMsg, Toast.LENGTH_SHORT).show(); 83 | } 84 | }); 85 | ``` 86 | ###4 加入房间 87 | | 接口名| 接口描述 | 88 | |---------|---------| 89 | | **joinRoom** | 观众角色调用加入房间接口| 90 | 91 | 92 | | 参数类型| 说明 | 93 | |---------|---------| 94 | | int | 房间id 房间唯一标识 建议由业务方后台统一分配 | 95 | | ILiveRoomOption | 房间配置项 可以设置角色 权限 主播ID 摄像头参数等 具体参考类ILiveRoomOption | 96 | | ILiveCallBack | 加入房间回调接口。通知加入房间是否成功 | 97 |
98 | 99 | ```java 100 | 101 | 102 | 103 | //加入房间配置项 104 | ILiveRoomOption memberOption = new ILiveRoomOption(hostId) 105 | .autoCamera(false) //是否自动打开摄像头 106 | .controlRole("NormalMember") //角色设置 107 | .authBits(AVRoomMulti.AUTH_BITS_JOIN_ROOM | AVRoomMulti.AUTH_BITS_RECV_AUDIO | AVRoomMulti.AUTH_BITS_RECV_CAMERA_VIDEO | AVRoomMulti.AUTH_BITS_RECV_SCREEN_VIDEO) //权限设置 108 | .videoRecvMode(AVRoomMulti.VIDEO_RECV_MODE_SEMI_AUTO_RECV_CAMERA_VIDEO) //是否开始半自动接收 109 | .autoMic(false);//是否自动打开mic 110 | //加入房间 111 | ILVLiveManager.getInstance().joinRoom(room, memberOption, new ILiveCallBack() { 112 | @Override 113 | public void onSuccess(Object data) { 114 | bEnterRoom = true; 115 | Toast.makeText(LiveActivity.this, "join room ok ", Toast.LENGTH_SHORT).show(); 116 | logoutBtn.setVisibility(View.INVISIBLE); 117 | backBtn.setVisibility(View.VISIBLE); 118 | } 119 | 120 | @Override 121 | public void onError(String module, int errCode, String errMsg) { 122 | Toast.makeText(LiveActivity.this, module + "|join fail " + errMsg + " " + errMsg, Toast.LENGTH_SHORT).show(); 123 | } 124 | }); 125 | ``` 126 | 127 | 128 | ###设置渲染层 129 | > 渲染层级示例图 在界面层xml插入一个AVRootView,音视频数据最终是通过AVRootView渲染出来。考虑多屏互动情况,AVRootView实际上不是一层View而是多层AVVideoView的叠加。直播业务默认主播在第0层默认最大,其他互动观众分别在1,2,3层。每层大小都可以动态调节。 130 | > 131 | 132 | ![](http://mc.qcloudimg.com/static/img/d063a1980cc046cafa0444df0b609d02/image.png) 133 | * 示例 134 | 135 | ```java 136 | 141 | 142 | 143 | avRootView = (AVRootView) findViewById(R.id.av_root_view); 144 | ILVLiveManager.getInstance().setAvVideoView(avRootView); 145 | ``` 146 | 147 | [信令及上麦参见](./ILVLiveSenior.md) 148 | -------------------------------------------------------------------------------- /随心播/Android随心播集成/ILVLiveRecordAPush.md: -------------------------------------------------------------------------------- 1 | ##发消息 2 | 3 | ###发文本消息 4 | //发送消息 5 | ILVText iliveText = new ILVText("ss", "", ILVLiveConstants.GROUP_TYPE); 6 | iliveText.setText("" + textInput.getText()); 7 | //发送消息 8 | ILVLiveManager.getInstance().sendText(iliveText, new ILiveCallBack() { 9 | @Override 10 | public void onSuccess(Object data) { 11 | Toast.makeText(LiveActivity.this, "send succ!", Toast.LENGTH_SHORT).show(); 12 | } 13 | 14 | @Override 15 | public void onError(String module, int errCode, String errMsg) { 16 | 17 | } 18 | 19 | }); 20 | 21 | ###上麦邀请 22 | 23 | 24 | 25 | //邀请上麦 26 | ILVCustomCmd cmd = new ILVCustomCmd(); 27 | cmd.setCmd(ILVLiveConstants.ILVLIVE_CMD_INVITE); 28 | cmd.setType(ILVLiveConstants.C2C_TYPE); 29 | cmd.setDestid("" + memId.getText()); 30 | cmd.setParam(""); 31 | ILVLiveManager.getInstance().sendCustomCmd(cmd, new ILiveCallBack() { 32 | @Override 33 | public void onSuccess(TIMMessage data) { 34 | Toast.makeText(LiveActivity.this, "invite send succ!", Toast.LENGTH_SHORT).show(); 35 | } 36 | 37 | @Override 38 | public void onError(String module, int errCode, String errMsg) { 39 | 40 | } 41 | 42 | }); 43 | 44 | 45 | ###下麦命令 46 | //关闭上麦 47 | ILVCustomCmd cmd = new ILVCustomCmd(); 48 | cmd.setCmd(ILVLiveConstants.ILVLIVE_CMD_INVITE_CLOSE); 49 | cmd.setType(ILVLiveConstants.C2C_TYPE); 50 | cmd.setDestid("" + memId.getText()); 51 | cmd.setParam(""); 52 | ILVLiveManager.getInstance().sendCustomCmd(cmd, new ILiveCallBack() { 53 | @Override 54 | public void onSuccess(TIMMessage data) { 55 | Toast.makeText(LiveActivity.this, "invite send succ!", Toast.LENGTH_SHORT).show(); 56 | } 57 | 58 | @Override 59 | public void onError(String module, int errCode, String errMsg) { 60 | 61 | } 62 | 63 | }); 64 | 65 | ###解析信令上麦 66 | ILVLiveConfig liveConfig = new ILVLiveConfig(); 67 | 68 | liveConfig.setLiveMsgListener(new ILVLiveConfig.ILVLiveMsgListener() { 69 | @Override 70 | public void onNewTextMsg(String text, String id) { 71 | Toast.makeText(LiveActivity.this, "onNewTextMsg : " + text, Toast.LENGTH_SHORT).show(); 72 | } 73 | 74 | @Override 75 | public void onNewCmdMsg(int cmd, String param, String id) { 76 | switch (cmd) { 77 | case ILVLiveConstants.ILVLIVE_CMD_INVITE: 78 | Toast.makeText(LiveActivity.this, "onNewCmdMsg : received a invitation! ", Toast.LENGTH_SHORT).show(); 79 | ILiveLog.d(TAG, "ILVB-LiveApp|received "); 80 | ILVLiveManager.getInstance().upToVideoMember(ILVLiveConstants.VIDEO_MEMBER_AUTH, ILVLiveConstants.VIDEO_MEMBER_ROLE, new ILiveCallBack() { 81 | @Override 82 | public void onSuccess(Object data) { 83 | 84 | } 85 | 86 | @Override 87 | public void onError(String module, int errCode, String errMsg) { 88 | 89 | } 90 | }); 91 | break; 92 | case ILVLiveConstants.ILVLIVE_CMD_INVITE_CANCEL: 93 | 94 | break; 95 | case ILVLiveConstants.ILVLIVE_CMD_INVITE_CLOSE: 96 | ILVLiveManager.getInstance().downToNorMember(ILVLiveConstants.NORMAL_MEMBER_AUTH, ILVLiveConstants.NORMAL_MEMBER_ROLE, new ILiveCallBack() { 97 | @Override 98 | public void onSuccess(Object data) { 99 | 100 | } 101 | 102 | @Override 103 | public void onError(String module, int errCode, String errMsg) { 104 | 105 | } 106 | }); 107 | break; 108 | case ILVLiveConstants.ILVLIVE_CMD_INTERACT_AGREE: 109 | break; 110 | case ILVLiveConstants.ILVLIVE_CMD_INTERACT_REJECT: 111 | break; 112 | } 113 | 114 | } 115 | 116 | @Override 117 | public void onNewCustomMsg(int cmd, String param, String id) { 118 | Toast.makeText(LiveActivity.this, "cmd "+ cmd, Toast.LENGTH_SHORT).show(); 119 | 120 | } 121 | }); 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /随心播/Android随心播集成/Names.md: -------------------------------------------------------------------------------- 1 | ## 直播中一些专有名词解释 2 | 3 | ### 直播房间 4 | 在随心播中,直播房间是指的音视频AVRoom和聊天室AVChatRoom的整合。 5 | **音视频AVROOM** 主要负责音视频流的拉取,房间ID是32位整型。 6 | **聊天室AVChatRoom** 是消息和信令通道,包括文本,礼物,赞等,房间ID是String 7 | 8 | 随心播创建房间过程是先创建一个音视频AVROOM (例如房间ID是int1235),在成功的回调里面再创建直播聊天室(ID是String类型1235),最后把回调抛回给用户。 9 | 10 | 11 | 12 | ```java 13 | //创建房间配置项 14 | ILVLiveRoomOption hostOption = new ILVLiveRoomOption(null) 15 | .controlRole(Constants.HOST_ROLE)//角色设置 16 | .authBits(AVRoomMulti.AUTH_BITS_DEFAULT)//权限设置 17 | .cameraId(ILiveConstants.FRONT_CAMERA)//摄像头前置后置 18 | .videoRecvMode(AVRoomMulti.VIDEO_RECV_MODE_SEMI_AUTO_RECV_CAMERA_VIDEO);//是否开始半自动接收 19 | //创建房间 20 | ILVLiveManager.getInstance().createRoom(room, hostOption, new ILiveCallBack() { 21 | @Override 22 | public void onSuccess(Object data) { 23 | Toast.makeText(LiveActivity.this, "create room ok", Toast.LENGTH_SHORT).show(); 24 | logoutBtn.setVisibility(View.INVISIBLE); 25 | backBtn.setVisibility(View.VISIBLE); 26 | } 27 | 28 | @Override 29 | public void onError(String module, int errCode, String errMsg) { 30 | Toast.makeText(LiveActivity.this, module + "|create fail " + errMsg + " " + errMsg, Toast.LENGTH_SHORT).show(); 31 | } 32 | }); 33 | ``` 34 | 35 | 如果在Option里面配置imsupport(false)则仅仅单独创建AV音视频房间,业务方可以根据业务需求灵活配置。 36 | 37 | 38 | ### 直播房间生命周期 39 | 正常情况下,退出房间主动退出音视频AVROOM,会主动结束掉聊天室AVChatRoom。 40 | 异常情况下,例如主播Crash 音视频AVROOM房间内无上下行流量超过30S AVROOM会被系统回收。聊天室AVChatRoom主播Crash不会主动回收房间。(如果需要配置回收需要找腾讯后台申请配置,一般不推荐) 41 | -------------------------------------------------------------------------------- /随心播/Android随心播集成/beforeHand.md: -------------------------------------------------------------------------------- 1 | #准备 2 | 3 | 鉴于Google已经官方声明不再支持eclipse开发,强烈建议你用Android Studio开发。
4 | 5 | 6 | #1.下载SDK 7 | ### 方法1 aar方式集成(强烈推荐)
8 | 如果你使用的Android Studio开发,那么导入iliveSDK非常简单。只需一行代码就可以搞定了 9 | 10 | compile 'com.tencent.ilivesdk:ilivesdk:X.X.X' 11 | 12 | (X.X.X 替换成对应版本号 比如0.3.7) 13 | 14 | 15 | ### 方法2 传统库类方式集成 16 | * 在腾讯云官网[下载音视频库类](http://www.oracle.com/index.html) 17 | 18 | 19 | #2 导入项目 20 | * **aar方式集成**,同步完成之后可以在build文件夹中找到ilivesdk文件夹。 21 |
22 | ![](http://mc.qcloudimg.com/static/img/ecd51eab082087cd2049a6a06a84ea76/image.png) 23 | 24 | 25 | * **传统库类方式集成**,则需要把so文件和jar包文件分别放到对应jnilibs和libs里面。 26 |
27 | helloAndroid.png 28 |
29 | **特别注意:**目前音视频相关库类只支持armeabi架构。[关于多架构的问题总结](https://github.com/zhaoyang21cn/Android_Suixinbo/issues/6) 30 | 31 | 32 | ## 库类介绍 33 | 从官网上下载的SDK主要包含以下文件夹: 34 | 35 | | 文件夹 | 说明 | 36 | |---------|---------| 37 | | docs | 里面放了一些开发文档 包括API更新列表 | 38 | | libs | SDK是以jar和so文件的形式提供给APP使用的,方便普通方式集成和eclipse方式开发 | 39 | | asserts | 音视频核心库类,目前只支持armeabi架构 | 40 | 41 | 42 | ####库类清单 43 | | 序号 | 名称 | 所在文件夹 | 说明 | 44 | |---------|---------|---------|---------| 45 | | 1 | qavsdk.jar | libs\jar | 音视频SDK。| 46 | | 2 | libhwcodec.so | libs\armeabi | 编解码。 | 47 | | 3 | libqav_graphics.so | libs\armeabi | 音视频图形界面。| 48 | | 4 | libqavsdk.so | libs\armeabi | 音视频SDK。| 49 | | 5 | libstlport_shared.so | libs\armeabi | 音视频基础库。 | 50 | | 6 | libTcVpxDec.so | libs\armeabi | 视频组件。| 51 | | 7 | libTcVpxEnc.so | libs\armeabi | 视频组件。 | 52 | | 8 | libtraeimp-armeabi-v7a.so | libs\armeabi | 音频组件。| 53 | | 9 | libxplatform.so | libs\armeabi | 音视频基础库。| 54 | | 10 | beacon_1.5.3_imsdk_release.jar | libs\jar | 音视频SDK。| 55 | | 11| bugly_1.2.8_imsdk_release.jar | libs\jar | 即时聊天crash上报。 56 | | 12 | imsdk.jar | libs\jar | 即时聊天的SDK。| 57 | | 13 | mobilepb.jar | libs\jar | protouf编解码相关。| 58 | | 14| qalsdk.jar | libs\jar | imsdk网络层。| 59 | | 15 | tls_sdk.jar | libs\jar | 登录相关。| 60 | | 16 | wup-1.0.0-SNAPSHOT.jar | libs\jar | imSdk相关依赖包。| 61 | | 17 | lib_imcore_jni_gyp.so | libs\armeabi | 即时聊天。| 62 | | 18 | libBugly.so | libs\armeabi | crash上报。| 63 | | 19 | libqalcodecwrapper.so | libs\armeabi | qalsdk相关。| 64 | | 20 | libqalmsfboot.so | libs\armeabi | qalsdk相关。| 65 | | 21 | libwtcrypto.so | libs\armeabi | 登录依赖。| 66 | **特别注意:**APP开发者在更新替换SDK的时候,务必要保证以上所有文件的完整性。如果仅局部地替换个别文件,很可能会引入异常。 67 | 68 | ### 附录 69 | #### [了解更多IMSDK的信息](http://www.qcloud.com/product/im.html) 70 | #### [eclipse开发集成文档](https://github.com/zhaoyang21cn/ILiveSDK_Android_Demos/blob/master/doc/ILiveSDK/eclipse_readme.md) (不推荐) 71 | 72 | 73 | ## 示例参考 74 | 为了方便客户快速集成直播业务,我们在github提供一个[简单直播的示例](https://github.com/zhaoyang21cn/ILiveSDK_Android_Demos)和一个业务级的[应用随心播](https://github.com/zhaoyang21cn/Android_Suixinbo) 75 | 76 |
77 | ![](http://mc.qcloudimg.com/static/img/9c869853602951b70bf14d29775047b8/image.png) 78 | 79 |
80 |
81 | 82 | 83 |
84 | 85 | #3修改Appid和AccountType 86 | Appid应用唯一腾讯云服务的标示。[如何申请Appid](https://www.qcloud.com/doc/product/268/4899) 87 | 88 | 随心播修改位置 89 | ![](http://mc.qcloudimg.com/static/img/62890dee5794a2ce94404ba762624b94/image.png) 90 | 91 | 简单直播修改位置 92 | ![](http://mc.qcloudimg.com/static/img/f1c38008d48d9a33f28a089f57cdb0a5/image.png) 93 | 94 | #4修改后台地址 95 | 目前随心播后台主要用来维护直播房间列表。如果复用随心播客户端代码,需要修改随心播后台地址为业务方自己部署的服务器地址。
96 | 97 | | 接口| 说明 | 98 | |---------|---------| 99 | | GET_MYROOMID | 获取自己分配的房间号 | 100 | | NEW_ROOM_INFO | 创建新房间 | 101 | | STOP_ROOM | 退出房间 | 102 | | GET_LIVELIST | 获取房间列表 | 103 | | SEND_HEARTBEAT | 房间心跳 | 104 | | GET_COS_SIG | 图片上传相关 | 105 | ![](http://mc.qcloudimg.com/static/img/06919328fe28d9088170fc2a6b0f7ee9/image.png) 106 | 107 | 108 | 109 | 110 | #5编译运行 111 | ###简单直播配置参考 112 | * 由于目前只支持armeabi架构,如果工程(或依赖库)中有多架构,需要在build.gradle中添加以下配置
(如果包含子工程子工程也要加) 113 |
114 | android{
115 |     defaultConfig{
116 |         ndk{
117 |             abiFilter 'armeabi'
118 |         }
119 |     }
120 | }
121 | 
播配置参考 122 | 123 | 124 | 125 | 126 | ###随心播配置参考 127 | * 请注意配置jcenter库 腾讯内部是自己的maven
128 | ![](http://mc.qcloudimg.com/static/img/8c4c9bf238499dec32aca993d9ff7ad4/image.png) 129 | * 配置自己的版本号
130 | ![](http://mc.qcloudimg.com/static/img/88beeec46c0fab88f9cf977f6af7f14c/image.png) 131 | * 混淆相关
132 | 133 | -keep class com.tencent.**{*;} 134 | -dontwarn com.tencent.** 135 | 136 | -keep class tencent.**{*;} 137 | -dontwarn tencent.** 138 | 139 | -keep class qalsdk.**{*;} 140 | -dontwarn qalsdk.** 141 | * 配置信令服务
142 | ![](http://mc.qcloudimg.com/static/img/afa18e51202e3e80232841d215d90f7b/image.png) 143 | * 申请权限
144 | ![](http://mc.qcloudimg.com/static/img/55db2326bef2d0270ab17e81d945da22/image.png)) 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/OpenVideo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/OpenVideo.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/UiLayers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/UiLayers.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/customcmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/customcmd.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/demos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/demos.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/helloAndroid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/helloAndroid.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/idntype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/idntype.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/iliveappid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/iliveappid.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/ilivelocation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/ilivelocation.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/jarnso.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/jarnso.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/jdk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/jdk.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/livedemo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/livedemo.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/nolongsupport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/nolongsupport.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic1.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic10.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic11.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic12.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic13.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic14.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic15.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic16.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic17.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic18.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic19.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic2.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic20.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic21.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic3.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic4.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic5.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic6.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic7.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic8.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/pic9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/pic9.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/process.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/qalservice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/qalservice.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/respositories.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/respositories.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/rights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/rights.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/sdkversion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/sdkversion.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/server.png -------------------------------------------------------------------------------- /随心播/Android随心播集成/image/suixinbo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/Android随心播集成/image/suixinbo.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/0.随心播功能列表.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # TCShow功能列表 5 | 6 | 7 | TCAVIMDemo:是集成演示Demo,其内部主要展示如何自定义扩展TCAdapter中核心模块,并提供一部分可用TCAdapter进行二次开发的简单场景。 8 | 9 | LiveIMTool:是一个用于与随心播联调的工具,具体使用时,用户可参考里面的代码进行不同消息量发送,对直播间进行压测,以检测直播性能; 10 | 11 | TCSoLive:主要展示一些外部用户经常反馈的功能(在随心播中没有的); 12 | 13 | TCShow 14 | 15 | -------------------------------------------------------------------------------- /随心播/iOS随心播集成/1.随心播运行指南.md: -------------------------------------------------------------------------------- 1 | 2 | # 随心播运行指南 3 | 4 | ## 随心播功能说明 5 | 随心播是基于腾讯云[**云通信(IMSDK)**](https://www.qcloud.com/product/im.html)与[**互动直播(AVSDK)**](https://www.qcloud.com/product/ilvb.html),用于对外部用户演示与集成的产品,并上传至[**AppStore**](https://itunes.apple.com/cn/app/sui-xin-bo/id1037944078?mt=8)(用户亦可在AppStore搜索随心播进行下载)。其包含常用直播/互动直播两个场景(AppStore版本对外只显示了互动直播场景)。其演示了IMSDK与AVSDK结合进行直播、互动直播时如何进行画面请求与渲染,聊天消息,信令控制,推流录制等。 6 | 7 | ## 随心播下载与运行 8 | 因业务需要,将随心播的代码上传至[**GitHub**](https://github.com/zhaoyang21cn/iOS_Suixinbo),GitHub定期会有更新与维护,其使用的SDK版本较腾讯云上的版本会较新(原[**腾讯云互动直播**](https://www.qcloud.com/product/ilvb.html)上只存放正式版本,GitHub使用的IMSDK与AVSDK可能会是最新的稳定版本)。 9 | 10 | 用户打开[**GitHub**](https://github.com/zhaoyang21cn/iOS_Suixinbo)后,可以**Star**随心播,这样腾讯更新代码时,GitHub会通知到。同时注意阅读ReadMe。用户也可以在GitHub上给随心播提issue,我们会定期查看并回复。 11 | 12 | 13 | 用户点击右上角Clone or 14 | download下载代码到本地后,注意阅读ReadMe,因GitHub有文件大小限制,我们将AVSDK+IMSDK存储在腾讯云COS服务上,用户还需要去对应下载SDK文件,并按照说明解压到对应的目录。 15 | 16 | 17 | 18 | 下载并解压代码与并下载配置好SDK后,如下图: 19 | 20 | 21 | 22 | | 文件名 | 说明 | 23 | | ------ | ------ | 24 | | 10000以上被转换的错误码 | 出现10000以上错误时,先将日志开启,再重现,然后搜索日志中ERROR. SERVER\_ERROR. server ret\_code 再对比码表找到对应的错误码 | 25 | | 随心播iOS重构说明 | 随心播代码导读 | 26 | | ReadMe + 4张JPEG | ReadMe说明,以及Spear推荐配置说明 | 27 | | TCShow | 源代码目录 | 28 | | TCShow/CommonLibrary | 代码中的工具包,以及UI框架 | 29 | | TCShow/TCAdapter | 重构以及复用的核心部分 | 30 | | TCShow/LiveIMTool | IM工具,用于直播间内消息压测 | 31 | | TCShow/TCAVIMDemo | 集成演示Demo,以及一些不常用的,不同场景,不便于在随心播中演示的功能,会在此处进行演示 | 32 | | TCShow/TCShow | 随心播工程目录 | 33 | 34 | 35 | 打开iOS\_Suixinbo/TCShow目录下的TCShowWorkSpace.xcworkspace,打开后选择好对应的TCShow 36 | 37 | 38 | ## 随心播运行注意事项 39 | 户在真机上运行时,在进入到直播发布页可以看到的开始直播与开始互动直播两个按钮(见下图一),分别点击进入后对应直播界面(图二)与互动直播界面(图三),虽然在随心播里面直播与互动直播可以互看,而且界面也非常类似,但是互动直播内部逻辑较直播要复杂很多,如果用户只是做直播,为方便用户进行代码阅读,可将代码的宏kSupportMultiLive改为0,以便理解代码逻辑。 40 | 41 | 42 | 直播发布页 43 | 直播页 44 | 互动直播页 45 | -------------------------------------------------------------------------------- /随心播/iOS随心播集成/2.架构集成.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 导入框架 4 | 5 | ## 架构设计及说明 6 | 7 | 通用的App框架是基于系统(OS System Service),自底向上分作三层: 8 | 9 | | 模块层 | 作用 | 10 | | -------------- | ------ | 11 | | **App Core Service** | App核心服务层,对外提供核心功能(如IMSDK,AVSDK)等 | 12 | | **App Adapter** | 业务逻辑适配层,App根据自身的业务不同,将App Core Service提供的核心功能进行封装,以方便外部使用 | 13 | | **App UI** | 各功能模块对就看整屏界面,主要负责界面内部Custom UI的布局与调度 | 14 | | **Custom UI** | 自定义UI层,主要作用是把界面上的大模块拆分到小的自定义的小模块(Custom View)中进行实现,实际开发中隶属于AppUI,可在各App UI模块中进行复用的部分 | 15 | | **Common Library** | 公用代码库,主要基础工具类,第三方代码等,用作代码搜集以及后期复用 | 16 | 17 | 18 | 通用App框架各分层通信模型如下: 19 | 20 | 21 | 22 | 各箭头含义:
23 | | 箭头 | 含义 | 24 | | ------ | ------ | 25 | | Call | 调用 | 26 | | CallBack | 回调 | 27 | | Broadcast | 广播 | 28 | | Support | 支撑/支持 | 29 | 30 | ## TCAdapter如何复用框架 31 | 32 | 33 | 为了方便用户进行集成,我们设计TCAdapter,将AVSDK与IMSDK进行再封装,降低用户使用AVSDK+IMSDK来开发直播场景等业务类App门槛: 34 | 35 | 36 | - **用户可以通过集成TCAdapter来扩展自身业务逻辑,集成者更多地关注自身的业务逻辑上的处理**; 37 | 38 | - **TCAdapter中处理了大量直播中常见的问题,这些问题处理让用户自行实现的话可能会比较麻烦**; 39 | 40 | - **TCAdapter经过测试,稳定性上有一定的保证**; 41 | 42 | 43 | TCAdapter对应通用框架即为下图 44 | 45 | 46 | 47 | 熟悉过TCAdapter中的代码后,你会发现其对应基本模型如下图,其每个模块都有默认的内容,并且也都支持定制扩展。TCAdapter内部负责管理各模块之间的协作,实际开发中,用户只要逐一完成一个个模块即可。 48 | 49 | 51 | 52 | ## 随心播如何扩展框架 53 | 随心播集成TCAdapter之后对应层次即为下图,其他业务集成后对应的层次图也如下 54 | 55 | 56 | 57 | 其他第三方在集成TCAdapter时,同样也需要可以复用的TCAdapter(里面已将App 58 | Core Service的SDK添加到其中),CommonLibrary,然后再实现其App 59 | UI部分(主要指跟直播、互动直播相关的模块)。 60 | 61 | # 框架集成 62 | 开始集成前,请务必下载*GitHub*上最新的代码,以创建**TCAVIMDemo**为例,过程中会介绍已有项目如何集成,每进行一步结束时,都**Build**一下,以确保每步都正常。 63 | 64 | ## 配置新的工程 65 | 若当前为新工程TCAVIMDemo,并删除默认生成的内容,设置**Enable BitCode** 66 | 为**NO**,设置**Other Linker Flags** 为 **-ObjC(注意大小写)**,增加PCH文件
67 | 68 | 69 | 70 | 71 |
72 | 73 | 74 | 同是配置C++相关的配置如下:**如果不配置,会导致调试时在Console下po时,拿不到正确的值**
75 | 76 | 77 | 78 | 79 | ## 导入CommonLibrary 80 | 导入CommonLibrary,添加到PCH,并添加Compiler Flags 81 | 82 | 83 | 此时用户若只想用CommonLibrary进行App开发,还需要配置AppDelegate。 84 | 85 | 修改前
86 | 87 | 88 | 修改后
89 | 90 | 91 | ## 导入TCAdapter 92 | 导入TCAdapter,添加到PCH,添加依赖库(**因可能文档没有及时更新,请以TCShow中SystemLibrary为准**):
93 | 94 | 95 | 添加CompilerFlags,请注意阅读红字部分
96 | 97 | 98 | 若用户参考的是Demo中目录结构(CommonLibrary与TCAdapter不在当前工程目录下),注意配置以下Search 99 | Path,以确保能访问到正确的目录(下图实际配置与App相关只作参考)
100 | 101 | 102 | 完成以上步骤,即可编译成功,用户在保证编译成功的前提下,再继续后面的步骤。 103 | 104 | **1.8.1之后的版本请注意添加 libresolv.tbd 105 | (用于支持ipv6),另外XCode7.3(在写该文档时,已升级到7.3,低版本未试过) 106 | 的用户编译后可能会报下面的问题,不要惊慌,其不影响在真机上调试,至于为什么报错(网上了解到的是跟C++有关),暂未找到具体解决办法,后续如有找到,再更新该处** 107 |
108 | 109 | 110 | 111 | 在完成以上步骤时,再进行*配置AppID*即已完成TCAdapter框架的集成了,后续的第四步第五步只是介绍如何配置与简单的使用。 112 | 113 | ## 配置托管模式登录功能 114 | 配置AppDelegate ,使用支持登录功能
115 | 116 | 117 | 若不是新建的工程,而是在现有代码上集成,此处注意: 118 | 119 | - 用户根据情况而定,看是否需要继承IMAAppDelegate; 120 | 121 | - 若不能直接继承IMAAppDelegate,用户需要参考IMAAppDelegate,以及BaseAppDelegate代码,将相关逻辑移植到现有的代码中。 122 | 123 | ## 添加主界面后的效果 124 | 125 | 126 | 127 | 128 | 界面中一些基本的样式,可能通通修改BaseAppDelegate中的CommonLibraryConfig.h中的配置进行修改,如果不符合要求,可修改原代码(后期合并时注意) 129 | 130 | 另外用户如果想重写登录界面,可重写enterLoginUI方法即跳转到自己的登录界面,注意自已界面内与IMALoginViewController内部登录逻辑一致,确保IMSDK能正确登录。 131 | 132 | **另外请注意**:若用户app使用了国际化,请将TCAdapter/TIMAdapter/Localizable.strings文件与自己app的国际化字符串文件进行合并 133 | 134 | 135 | ## 配置App参数 136 | 修改自己App申请的AppID以及AccountType 137 | 138 | 139 | 配置完以上步骤即可使用TCAdapter进行开发了,集成示例TCAVIMDemo中,使用其编写了几个简单的场景,详见代码。 140 | -------------------------------------------------------------------------------- /随心播/iOS随心播集成/4.直播中的功能点讲解.md: -------------------------------------------------------------------------------- 1 | # 直播中的功能点讲解 2 | 3 | 4 | **该部份主要讲解实际操作中,用户需要关注或可能需要重写的逻辑,这一节内容也是用户比较容易出错的地方。用户在重写以下这些方法时,注意保证逻辑的完整性。另外此章节会根据技术支持群反馈的问题持续更新。** 5 | 6 | ## 硬件权限以及网络检查 7 | 8 | 9 | ### 进入前检查 10 | 11 | 1. 进入前网络检查:TCAdapter中的网络通知回调是IMSDK返回的,IMAPlatform对其作如下封装:
12 | 13 | 14 | 15 | 外部用户如果也想用这一通知,其前提是要执行*这一步*中的configIMSDK,然后在其代码中KVO网络变化。
16 | 17 | TCAdapter内部直播前网络检查接口如下: 18 | 19 | 2. 进入前手机权限检查:权限检查主要相机与麦克风的权限检查,检查的时候会区分不前用户是主播还是观众,同时也跟Spear配置有关。 20 | 21 | TCAdapter中主要是对直播场进行了封装,默认的逻辑是:主播进入时(还未到调用AVSDK相关代码)要检查相机与麦克风权限(**但对静音,以及勿扰模式不作检查,这一块会影响音频上行,请开发者注意**),观众进入时不检查这些权限。 22 | 23 | 但是如果进入时Spear配置音频场景为开播模式时,使用AVSDK,进入房间后,其底层会检查麦克风权限(比如:随心播中互动直播,观众进入时配置的是开播模式,首次使用时使用提麦克风权限检查)。
24 | 25 | 实际使用时,用户根据自已业务场景与TCAdapter中的一不致,可重写上图中的方 26 | 法即可。 27 | 28 | ### 使用中检查 29 | 30 | 1. 使用过程中,如果用户手动去手机设置项是修改了权限,这样会导致使用到对应权限的App重启,这是系统机制。所以TCAdapter使用过程中不再对相机与麦克风权限作检查。 31 | 32 | 2. 使用过程网络变化监听:TCAdapter中监听了网络断开/连接变化通知(onNetworkConnected),以及网络类型(wifi/移动网络/无网)变化通知(onNetworkChanged),并提供较简单的处理,用户重写这两处以满足自定义效果。 33 | 34 | # 进房间流程定制 35 | 36 | 前面介绍过用户集成时,*用户进直播间*时,需要关注的主线流程,下面的几点可能也是用户会关注的,用户根据实际需要进行重写。 37 | 38 | - 能否不立即进入直播间:TCAdapter默认直接进入到直播间,如果用户需要在进入直播界面,需要做一些自定义的操作之后再进行,可以重写下在的接口:
39 | 40 | 41 | - 直播聊天室是否必须创建:TCAdapter中默认enableIM为YES,用户进入时会根据传入的直播间参数信息中的liveIMChatRoomId去作创建/加入直播聊天室的操作,对于一些业务场景下,用户不需要聊天室操作,或外部已经有聊天室的情况时,可以通过下图红框中的参数进行设置,注意阅读注释。

同时如果自定设置时,注意根据具体情况设置消息的回调处理,此处可能有调试工作,用户谨慎处理。 42 | 43 | - 美颜、美白默认参数自定义:TCAdapter中如果在*进入房间后配置*中配置了自动开启美颜或美白(前提是必开相机才有效),进入房间成功后,在打开相机后,会默认对应打开美颜或美白,此时二者对应的默认值均为5,用户可在其*自定义引擎*中可重写该值:
44 | 45 | 46 | - 退出时能否不解散/退出聊天室:TCAdapter中的直播场景在退出直播间后,会默认退出群,但对于一些非直播业务场景下,用户并不想这么做,这时用户可在其*自定义直播界面控制器*重写以下方法:
47 | 48 | 49 | # 推流/录制 50 | 51 | TCAdapter中推流相关的代码在TCAVLiveRoomEngine+PushStream中,录制相关的代码在TCAVLiveRoomEngine+Record。TCAdapter中默认会管理推流操、录制操作:正常退出时,会自动结束推流、录制,使用过程中也可以手动停止。但异常退出时,业务端需要到后台手动关闭相关的操作;当然用户也可能参考此部分的代码,进行重写,或**自行实现,自行实现时注意退出直播时,一定要关掉对应开启的推流与录制。** 52 | 53 | ## 推流设置 54 | 55 | 目前代码中支持两种方式让主播开启推流 56 | 57 | 1. 启动过程中配置:在进房间后,像其他开Mic,Camera一样配置即可,退出时,TCAdapter自动检查是否有:
58 | 59 |
60 | 代码中进行监听推流回调(详见TCAVRoomEngineDelegate); 61 | 62 | 63 | 2. 用户手动调用开始与结束推流代码;
64 | 65 | 66 | **注意启动时配置时,推使用观察者回调,直播中使用block回调;** 67 | 68 | ## 录制设置 69 | 70 | 录制相关的代码在TCAVLiveRoomEngine+Record中,目前代码中支持两种方式让主播开启录制: 71 | 72 | 1. 启动过程中配置:在进房间后,像其他开Mic,Camera一样配置即可(同上推流处中使用EAVCtrlState\_Record)代码中进行监听录制回调(详见TCAVRoomEngineDelegate);
73 | 74 | 75 | 2. 用户手动调用录制代码;
76 | 77 | 78 | **注意启动时配置时,推使用观察者回调,直播中使用block回调;** 79 | 80 | # 中断处理 81 | 82 | 83 | ## 电话中断 84 | 85 | TCAdapter中进入直播间成功后会添加电话监听(addPhoneListener),App在前台直播中如果有电话中断,其会自动进行处理(handlePhoneEvent):被电话中断时,会切换到电话界面,相当于App会进行退后台处理,电话结束时,App自动切换到至前台,进行前台处理。
86 | 87 | 88 | ## 前后台切换 89 | 90 | 直播过程中,前后台切换事件处理(此处说明一下子类有对此事件进行重写)
91 | 92 | 93 | 用户在开发自己的App过程中,经常反馈会退后有声音无画面问题,而随心播没有,原因随心播没有配置后台模式,而用户的App配置了后台模式导致。当用户App有后台模式的时候,TCAdapter中默认会在前后台切换时,会执行开关mic操作,来处理这样的逻辑。用户若想让其退后台仍可声音可重写该方法(有后台模式的前提下),可让自己的app在退后台仍可继续进行录音。
94 | 95 | ## 音频中断 96 | 97 | 直播过程中有可能会有输入法,闹铃,或其他音频相关的中断,TCAdapter中,会添加相关的中断监听,并统一在下图的代码中进行处理了。
98 | 99 | 100 | 另外需要注意的是:在进入房间前的会记发当前的AVAudioSession中相关的参数,以便离开房间时,可以恢复到进入前的配置。 101 | 102 | ## IM互踢 103 | 104 | 使用过程中,如果用户帐号在其他手机上登录了并开启直播的话,会导致直播时画面出错。所以在TCAdapter里面,当我们进入到TCAVBaseViewController中是,重新要设置IMSDK的TIMUserStatusListener监听者为自己(之前是IMAPlatform)。
105 | 106 | 107 | 直播结束时,再设置回IMAPlatform
108 | 109 | 110 | 直播中处理互踢以及sig过期等操作
111 | 112 | 113 | 114 | # 上麦/下麦流程 115 | 116 | 117 | 上麦/下麦是互动直播才用到,用户上麦流程: 118 | 119 | 1. 本地检查手机是否有使用Camera/Mic权限,如果没有权限不能进行后续操作; 120 | 121 | 2. 修改权限; 122 | 123 | 3. 修改Role(NormalGuest-->InteractUser); 124 | 125 | 4. 前两步操作完后,再打开camera/mic; 126 | 127 | 用户下麦流程: 128 | 129 | 1. 关camera/mic 130 | 131 | 2. 修改权限 132 | 133 | 3. 修改Role(InteractUser-->NormalGuest) 134 | 135 | TCAdapter中对此流程进行了封装,用户可根据自己的业务逻辑,要上麦的用户,在合适的时机调用以下接口进行上麦。 136 | 137 | 138 | 139 | 140 | 具体流程请搜索代码中上图中的函数。 141 | 142 | 143 | # 性能优化 144 | 145 | 146 | 当主播端短时间内收发大量消息时,如果采用即时显示,那么消息的显示会抢占CPU,无法保证AVSDK采集以上行数据 147 | ,这样观众端看到的画面会有卡顿, 148 | 149 | 关于大量收到IM消息时性能调优原则: 150 | 151 | 1. 减少IM消息显示频率:将IM消息进行缓存(或IM消息合并),以固定频率进行刷新; 152 | 153 | 2. 减少界面上的动画,增加动画缓存: 154 | 155 | 3. 在AVSDK回调中进行刷新: 156 | 157 | 4. IM消息在显示前,先在子线程中将要显示的内容先计算出来,不要等到主线程中计算; 158 | 159 | 5. 界面上使用性能更好的代码; 160 | 161 | 如何验证:使用WorkSpace中的LiveIMTool,配置成与App相同的Appid,然后用LiveIMTool加入到相同直播聊天室,输入参数控制发消息间隔,然后查看大消息下的效果,并进行性能调化。
162 | 163 | 164 | 用户也可参考该LiveIMTool的代码,自己写测试代码进行验证。 165 | 166 | 另外请注意目前直播中使用的是AVChatRoom是有频率控制,具体参数设置请咨询IMSDK技术支持。 167 | 168 | Demo中支持立即显示与缓存后显示,详见编译宏kSupportIMMsgCache,用户可通过修改此值,并与LiveIMTool结合进行,可检查大消息量下自己App是否有卡顿效果。 169 | -------------------------------------------------------------------------------- /随心播/iOS随心播集成/OpenGL Crash问题定位方法.md: -------------------------------------------------------------------------------- 1 | # 原因分析 2 | 当使用AVSDK中默认的AVGLBaseView作为直播渲染时,从之前调试以及用户反馈的情况来看,通常导致crash的地方是:**OpenGL在上一次没有正确得到释放,下一次使用过程中crash了;**
,其表象是crash到AVGLRenderView中的drawTexture下图中标线处,报野指针错误:
3 | 4 | 5 | ## 为什么是在下一次使用中出问题 6 | 7 | 通常的原因有如下几点:
8 | 1. 代码中有循环引用:**通常表现在block使用不当,或计时器处理不当,以及其他常见的内存引用问题,导致没有释放或延迟释放;**
9 | 2. 切换前后台处理不当:直播过程中的前后台切换(尤其是频繁切换时),以及对电话的处理不当,导致AVGLBaseView startDisplay或stopDisplay的时机不对,其本质上还是第一条,下面会解释;
10 | 3. 调试过程中AVSDK太久没上传心跳(>30s),直播过程中被动退出了,然后下次再进的时候也有会导致crash,本质上也属于第一条。通常这种情况下,建议检查AVSDK相关的回调中是否处理得当,此处不多介绍;
11 | 12 | 真实原因是: 13 | AVGLBaseView底层渲染是通过CADisplayLink(相当于计时器,计时器本身对使用target造成一次循环引用),当我们开始startDisplay时,实际上是循环进行绘制AVSDK返回的QAVFrameData到display屏幕上,display中会间接调用上面说的AVGLRenderView的drawTexture方法
14 | 15 |
所以在不需要渲染的时候,需要停止该计时器
16 | 17 | 18 | **因为其底层使用的AVGLShareInstance是一个单例,如果在下一次initOpenGL后,这时上一次的延迟释放了,其会调用destoryOpenGL,导致在display的时候crash。** 19 | 20 | 以TCAdapter为例说明以上的问题(其他方式接入的可参考):
21 | 代码中显示对AVGLBaseView**直接强引用**的有: 22 | 1. QAVSDK返回的视频帧(QAVFrameData)分发器,如TCAdapter中使用的TCAVFrameDispatcher,目前TCAdapter是是将其封装到TCAVLivePreview中,即如果TCAVLivePreview; 23 | 2. 将AVGLBaseView添加到直播界面的self.view,即当前直播界面,如TCAdapter中的TCAVLiveViewController及其子类:如果外部对直播界面强引用了,同样会造成AVGLBaseView释放不成功(即OpenGL得不到正确的释放); 24 | 25 | 同样如果业务侧代码对直播界面强引用了,也会间接导致AVGLBaseView无法正常释放 26 | 27 | 28 | # 如何排查crash 29 | 30 | ## 接入前验证 31 | 32 | 1. 如果是刚接入:在查内存泄露问题上,接入时建议步步为营,确保每一步都没有问题,ARC不是万能的,这块出了问题,确实不好查,到后期代码量大,相关的逻辑就多了,就更不好查。接入前最好先验证一下TCAVIMDemo里面的简单直播例子; 33 | 34 | 2. 提前了解下Objective-C通常哪些地方会导致循环引用:建议先谷哥度娘一下,避免真正开发的时候踩坑:最为常见的例子有:NSTimer没有invalidate,以及下面的方法使用不当,导致延迟释放:;
35 | 36 | 37 | 3. 对Block使用注意事项要了解:堆类型、栈类型、全局类型这三种Block使用注意事项要有清楚(这里不注意,经常会导致延迟释放或不释放OpenGL): 直播界面内的block最保险的方式如下:block内涉及直播界面,以及内部的变量全部用__weak, 38 |
39 | > ``` 40 | > // 以下为伪代码,用户可参考仿照此伪代码写真实代码进行验证 41 | > class A 42 | > { 43 | > int _mA; 44 | > id *_md; 45 | > } 46 | > 47 | > @property (nonatomic, strong) id mc; 48 | > 49 | > // block调用处 50 | > 51 | > - (void)print 52 | > { 53 | > // XXXTool 如果对传入succ中代码块作copy操作(即XXXTool内部将其转成堆类型变量),下面的写法都是不安全的,容易导致内存泄漏,self释放前,必须要把XXXTool内部的保存的堆类型block变量释放 54 | > // 如果没有copy,即为栈类型变量,如果内部是同步回调succ块还好,如果是异步回调,在异回调过程中,self想释放,其需要等该回调返回之后才可以释放 55 | > [[XXXTool sharedInstance] sendmsg:xxxx succ:^(BOOL succ) { 56 | > // 下面的代码都有问题 57 | > _mA = 10; 58 | > _md = [[NSObject alloc] init] 59 | > self.mc = [[NSObject alloc] init]; 60 | > [self methodB]; 61 | > }]; 62 | > } 63 | > 64 | > - (void)methodB 65 | > { 66 | > .... 67 | > } 68 | > 69 | > 推荐的print写法: 70 | > - (void)print 71 | > { 72 | > 73 | > // 无论在哪种情况下,都使用weak。block块内部不直接使用用当前类self, 或其成员变量(示例中的_mA, md) 74 | > __weak typeof(self) ws = self; 75 | > [[XXXTool sharedInstance] sendmsg:xxxx succ:^(BOOL succ) { 76 | > [ws onSendMessageSucc:succ] 77 | > // 此种情况下,这样写是没有关系的 78 | > //ws.mc = [[NSObject alloc] init]; 79 | > }]; 80 | > } 81 | > 82 | > - (void)onSendMessageSucc:(BOOL)succ 83 | > { 84 | > _mA = 10; 85 | > _md = [[NSObject alloc] init] 86 | > self.mc = [[NSObject alloc] init]; 87 | > [self methodB]; 88 | > } 89 | > 90 | > 91 | > ``` 92 | 93 | ## 有必现的crash重现步骤 94 | 1. 先验证是否是在第二次时才出现的问题:可在当前直播界面的dealloc方法里面打日志或断点,按重现步骤,第一次退出直播界面的时候,是否立即进入到dealloc里面,由此可判断代码里面是否有循环引用;(如果使用TCAdapter进行集成的,可使用TCAVIMDemo下UserAppBaseUIViewController,然后重写addLiveView方法,然后再用同样的重现步骤检查是否有crash,这样基本可定位是否是业务侧代码出问题,还是TCAdapter中出问题,用随心播作对比验证也可以
95 | 96 | ) 97 | 2. 按上面所说的检查方法,排查重现步骤上的相关内存相关代码(根据前面反馈的记录来看,大部份是因为业务中的计时器,block使用不当。排查NSTimer在退出直播界面时是否invalidate,block使用不当,可在直播相关的代码中搜索 **^**,即可将当前代码中的所有block全部搜索出来); 98 | 3. 整个代码都进行检查,是否存在其他的crash可能; 99 | 4. 如果是当次出现的crash问题,建议对比随心播,用同样的操作检查对比一下,查看两边的使用流程是否一致:(之前遇到过退后台不stopDisplay,然后再进入时crash的); 100 | 101 | 102 | ## 无必现的crash步骤 103 | 1. 找到重现步骤,首先在代码里面各关键节点处(进出房间,前后台切换,以及业务核心逻辑处)加上相关的日志,并保存到文件,在重现过程中,确保日志能正确保存到文件,以便查阅;如果是使用TCAdapter进行集成的,可将下关的开关,改成3, 104 | 105 | 因此块与业务方逻辑接触比较多 106 | 107 | 2. 当复现出crash之后,再按照有必现的crash重现步骤进行排查; 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /随心播/iOS随心播集成/beforeHand.md: -------------------------------------------------------------------------------- 1 | # 准备 2 | 3 | # 1.下载SDK 4 | 5 | 因GitHub有文件大小限制,现将ILiveSDK、IMSDK、AVSDK以及相关Framework上传到腾讯云COS上。 更新时,请到对应的地址进行更新,并添加到工程下面对应的目录下. 6 | 7 | Frameworks : http://dldir1.qq.com/hudongzhibo/ILiveSDK/Frameworks.zip 下载后解压,然后再放至对应放到[工程](https://github.com/zhaoyang21cn/ILiveSDK_iOS_Demos)目录 TILLiveSDKShow/ 8 | 9 | 10 | # 2.导入项目 11 | 参照 https://github.com/zhaoyang21cn/ILiveSDK_iOS_Demos/blob/master/ILiveSDK-README.md 12 | 13 | 14 | # 3.修改Appid和AccountType 15 | Appid应用唯一腾讯云服务的标示。[如何申请Appid](https://www.qcloud.com/doc/product/268/4899) 16 | 17 | 随心播修改位置 18 | TILLiveSDKShow/TILLiveSDKShow/ConstHeader.h 19 | ![](http://img.blog.csdn.net/20161116193820944) 20 | 21 | 简单直播修改位置 22 | TCILiveSDKDemo/TCILiveSDKDemo/AppDelegate.m 23 | 24 | ![](http://img.blog.csdn.net/20161116194345186) 25 | 26 | #4修改后台地址 27 | 目前随心播后台主要用来维护直播房间列表。如果复用随心播客户端代码,需要修改随心播后台地址为业务方自己部署的服务器地址。
28 | 29 | | 接口| 说明 | 30 | |---------|---------| 31 | | GET_MYROOMID | 获取自己分配的房间号 | 32 | | NEW_ROOM_INFO | 创建新房间 | 33 | | STOP_ROOM | 退出房间 | 34 | | GET_LIVELIST | 获取房间列表 | 35 | | SEND_HEARTBEAT | 房间心跳 | 36 | | GET_COS_SIG | 图片上传相关 | 37 | 38 | 39 | #5编译运行 40 | 请参考 https://github.com/zhaoyang21cn/ILiveSDK_iOS_Demos/blob/master/ILiveSDK-README.md 41 | -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image1.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image10.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image100.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image101.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image101.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image102.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image102.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image103.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image103.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image104.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image104.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image105.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image105.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image106.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image106.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image107.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image107.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image108.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image108.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image109.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image109.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image11.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image11.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image110.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image110.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image111.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image111.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image112.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image112.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image113.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image113.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image114.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image12.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image12.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image13.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image13.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image14.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image14.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image15.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image15.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image16.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image16.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image17.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image17.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image18.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image18.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image19.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image19.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image2.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image20.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image20.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image21.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image21.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image22.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image22.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image23.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image23.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image24.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image25.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image26.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image27.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image28.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image29.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image3.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image30.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image30.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image31.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image32.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image32.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image33.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image34.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image35.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image36.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image37.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image38.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image39.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image4.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image40.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image41.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image42.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image42.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image43.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image44.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image45.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image45.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image46.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image47.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image48.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image49.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image5.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image50.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image51.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image52.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image53.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image54.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image55.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image56.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image57.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image58.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image59.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image6.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image6.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image60.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image61.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image61.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image62.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image62.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image63.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image63.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image64.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image65.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image65.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image66.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image66.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image67.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image67.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image68.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image68.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image69.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image69.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image7.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image7.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image70.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image71.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image71.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image72.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image73.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image73.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image74.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image74.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image75.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image76.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image77.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image77.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image78.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image78.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image79.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image79.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image8.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image8.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image80.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image81.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image81.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image82.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image82.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image83.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image83.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image84.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image84.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image85.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image85.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image86.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image86.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image87.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image88.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image89.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image89.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image9.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image9.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image90.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image91.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image91.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image92.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image92.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image93.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image93.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image94.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image94.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image95.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image95.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image96.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image97.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image97.png -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image98.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image98.jpeg -------------------------------------------------------------------------------- /随心播/iOS随心播集成/media/image99.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoyang21cn/suixinbo_doc/3271716e8b069efe250a652a9468ce962678f0c2/随心播/iOS随心播集成/media/image99.png --------------------------------------------------------------------------------