room.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. import { genTestUserSig } from './GenerateTestUserSig.js'
  2. const app = getApp()
  3. Page({
  4. /**
  5. * 页面的初始数据
  6. */
  7. data: {
  8. roomID: 1, // 房间号
  9. role: '',
  10. userList: [], // 主播list
  11. userID: '',
  12. debugMode: false,
  13. initialRole: '',
  14. showRolePanel: false,
  15. presenterConfig: {
  16. enableMic: true,
  17. muteAllAudio: false,
  18. },
  19. headerHeight: app.globalData.headerHeight,
  20. statusBarHeight: app.globalData.statusBarHeight,
  21. rtcConfig: {
  22. sdkAppID: '1400537003', // 必要参数 开通实时音视频服务创建应用后分配的 sdkAppID
  23. userID: '', // 必要参数 用户 ID 可以由您的帐号系统指定
  24. userSig: '', // 必要参数 身份签名,相当于登录密码的作用
  25. template: '', // 必要参数 组件模版,支持的值 1v1 grid custom ,注意:不支持动态修改, iOS 不支持 pusher 动态渲染
  26. },
  27. },
  28. enterRoom: function({ sdkAppID, userSig }) {
  29. const template = 'custom'
  30. const roomID = this.data.roomID
  31. console.log('* room enterRoom', roomID, template)
  32. this.data.rtcConfig = {
  33. sdkAppID: sdkAppID, // 您的实时音视频服务创建应用后分配的 sdkAppID
  34. userID: '2',
  35. userSig: userSig,
  36. template: template, // 1v1 grid custom
  37. debugMode: this.data.debugMode, // 非必要参数,打开组件的调试模式,开发调试时建议设置为 true
  38. audioVolumeType: this.data.audioVolumeType,
  39. }
  40. this.setData({
  41. rtcConfig: this.data.rtcConfig,
  42. }, () => {
  43. // 进房前决定是否推送视频或音频
  44. if (this.data.role === 'presenter') {
  45. this.trtcComponent.publishLocalAudio()
  46. }
  47. // roomID 取值范围 1 ~ 4294967295
  48. this.trtcComponent.enterRoom({ roomID: roomID })
  49. })
  50. },
  51. getSignature: function(userID) {
  52. console.log('* room getSignature', userID)
  53. const Signature = genTestUserSig(userID)
  54. this.enterRoom({
  55. sdkAppID: Signature.sdkAppID,
  56. userSig: Signature.userSig,
  57. })
  58. },
  59. bindTRTCRoomEvent: function() {
  60. const TRTC_EVENT = this.trtcComponent.EVENT
  61. // 初始化事件订阅
  62. this.trtcComponent.on(TRTC_EVENT.LOCAL_JOIN, (event)=>{
  63. console.log('* room LOCAL_JOIN', event)
  64. // 进房成功,触发该事件后可以对本地视频和音频进行设置
  65. // if (this.data.role === 'presenter') {
  66. // this.trtcComponent.publishLocalAudio()
  67. // }
  68. })
  69. this.trtcComponent.on(TRTC_EVENT.LOCAL_LEAVE, (event)=>{
  70. console.log('* room LOCAL_LEAVE', event)
  71. })
  72. this.trtcComponent.on(TRTC_EVENT.ERROR, (event)=>{
  73. console.log('* room ERROR', event)
  74. })
  75. // 远端用户进房
  76. this.trtcComponent.on(TRTC_EVENT.REMOTE_USER_JOIN, (event)=>{
  77. console.log('* room REMOTE_USER_JOIN', event, this.trtcComponent.getRemoteUserList())
  78. const userList = this.trtcComponent.getRemoteUserList()
  79. this.handleOnUserList(userList).then(() => {
  80. console.log(this.data.userList)
  81. })
  82. })
  83. // 远端用户退出
  84. this.trtcComponent.on(TRTC_EVENT.REMOTE_USER_LEAVE, (event)=>{
  85. console.log('* room REMOTE_USER_LEAVE', event, this.trtcComponent.getRemoteUserList())
  86. const userList = this.trtcComponent.getRemoteUserList()
  87. this.handleOnUserList(userList).then(() => {
  88. console.log(this.data.userList)
  89. })
  90. })
  91. // 远端用户推送音频
  92. this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_ADD, (event)=>{
  93. if (this.data.userList.length < 6) {
  94. // 订阅音频
  95. const data = event.data
  96. // 如果不订阅就不会自动播放音频
  97. const userList = this.trtcComponent.getRemoteUserList()
  98. this.handleOnUserList(userList).then(() => {
  99. console.log(this.data.userList)
  100. })
  101. console.log('* room REMOTE_AUDIO_ADD', event, this.trtcComponent.getRemoteUserList())
  102. this.trtcComponent.subscribeRemoteAudio({ userID: data.userID })
  103. }
  104. })
  105. // 远端用户取消推送音频
  106. this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_REMOVE, (event)=>{
  107. console.log('* room REMOTE_AUDIO_REMOVE', event, this.trtcComponent.getRemoteUserList())
  108. const userList = this.trtcComponent.getRemoteUserList()
  109. this.handleOnUserList(userList).then(() => {
  110. console.log(this.data.userList)
  111. })
  112. })
  113. this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_VOLUME_UPDATE, (event)=>{
  114. const userID = event.data.target.dataset.userid
  115. const volume = event.data.detail.volume
  116. this.data.userList.forEach((item) =>{
  117. if (item.userID === userID) {
  118. item.volume = volume
  119. }
  120. })
  121. this.setData({
  122. userList: this.data.userList,
  123. })
  124. })
  125. },
  126. handleOnUserList: function(userList) {
  127. return new Promise((resolve, reject) => {
  128. const newUserList = []
  129. let index = 0
  130. const oldUserList = this.data.userList
  131. userList.forEach((item) => {
  132. if (item.hasMainAudio) {
  133. const user = this.judgeWhetherExist({ userID: item.userID, streamType: 'main' }, oldUserList)
  134. index += 1
  135. if (user) {
  136. // 已存在
  137. newUserList.push(Object.assign(user, { index: index }))
  138. } else {
  139. newUserList.push({
  140. userID: item.userID,
  141. streamType: 'main',
  142. index: index,
  143. hasMainAudio: item.hasMainAudio,
  144. volume: 0,
  145. })
  146. }
  147. }
  148. })
  149. this.setData({
  150. userList: newUserList,
  151. }, () => {
  152. console.log('handleOnUserList newUserList', newUserList)
  153. resolve()
  154. })
  155. })
  156. },
  157. judgeWhetherExist: function(target, userList) {
  158. userList.forEach( (item) => {
  159. if (target.userID === item.userID && target.streamType === item.streamType) {
  160. return item
  161. }
  162. })
  163. return false
  164. },
  165. handlePublishAudio() {
  166. if (this.data.presenterConfig.enableMic) {
  167. this.trtcComponent.unpublishLocalAudio()
  168. const config = this.data.presenterConfig
  169. config.enableMic = false
  170. this.setData({
  171. presenterConfig: config,
  172. }, () => {
  173. wx.showToast({
  174. title: '您已关闭麦克风',
  175. icon: 'none',
  176. duration: 500,
  177. })
  178. })
  179. } else {
  180. this.trtcComponent.publishLocalAudio()
  181. const config = this.data.presenterConfig
  182. config.enableMic = true
  183. this.setData({
  184. presenterConfig: config,
  185. }, () => {
  186. wx.showToast({
  187. title: '您已开启麦克风',
  188. icon: 'none',
  189. duration: 500,
  190. })
  191. })
  192. }
  193. },
  194. handleMuteAllAudio() {
  195. if (this.data.presenterConfig.muteAllAudio) {
  196. this.data.userList.forEach((item) => {
  197. this.trtcComponent.subscribeRemoteAudio({ userID: item.userID })
  198. })
  199. const config = this.data.presenterConfig
  200. config.muteAllAudio = false
  201. this.setData({
  202. presenterConfig: config,
  203. }, () => {
  204. wx.showToast({
  205. title: '取消禁音成功',
  206. icon: 'none',
  207. duration: 500,
  208. })
  209. })
  210. } else {
  211. this.data.userList.forEach((item) => {
  212. this.trtcComponent.unsubscribeRemoteAudio({ userID: item.userID })
  213. })
  214. const config = this.data.presenterConfig
  215. config.muteAllAudio = true
  216. this.setData({
  217. presenterConfig: config,
  218. }, () => {
  219. wx.showToast({
  220. title: '禁音成功',
  221. icon: 'none',
  222. duration: 500,
  223. })
  224. })
  225. }
  226. },
  227. /**
  228. * 返回上一页
  229. */
  230. onBack: function() {
  231. wx.navigateBack({
  232. delta: 1,
  233. })
  234. },
  235. handleRoleChange() {
  236. if (this.data.initialRole !== 'presenter' ) {
  237. this.setData({
  238. showRolePanel: !this.data.showRolePanel,
  239. })
  240. }
  241. },
  242. confirmRoleChange() {
  243. if (this.data.role === 'audience') {
  244. this.trtcComponent.publishLocalAudio().then(() => {
  245. this.setData({
  246. role: 'presenter',
  247. showRolePanel: false,
  248. })
  249. }).catch(() => {
  250. wx.showToast({
  251. icon: 'none',
  252. title: '上麦失败',
  253. })
  254. })
  255. } else {
  256. this.trtcComponent.unpublishLocalAudio().then(() => {
  257. this.setData({
  258. role: 'audience',
  259. showRolePanel: false,
  260. })
  261. }).catch(() => {
  262. wx.showToast({
  263. icon: 'none',
  264. title: '下麦失败',
  265. })
  266. })
  267. }
  268. },
  269. /**
  270. * 生命周期函数--监听页面加载
  271. * @param {*} options 配置项
  272. */
  273. onLoad: function(options) {
  274. console.log('room onload', options)
  275. wx.setKeepScreenOn({
  276. keepScreenOn: true,
  277. })
  278. // 获取 rtcroom 实例
  279. this.trtcComponent = this.selectComponent('#trtc-component')
  280. Object.getOwnPropertyNames(options).forEach((key) => {
  281. if (options[key] === 'true') {
  282. options[key] = true
  283. }
  284. if (options[key] === 'false') {
  285. options[key] = false
  286. }
  287. })
  288. // 监听TRTC Room 关键事件
  289. this.bindTRTCRoomEvent()
  290. this.setData({
  291. roomID: 1,
  292. // role: 1,
  293. // initialRole: 1,
  294. userID: '2',
  295. debugMode:true,
  296. // audioVolumeType: options.audioVolumeType,
  297. }, () => {
  298. this.getSignature('2')
  299. })
  300. },
  301. /**
  302. * 生命周期函数--监听页面初次渲染完成
  303. */
  304. onReady: function() {
  305. console.log('room ready')
  306. wx.setKeepScreenOn({
  307. keepScreenOn: true,
  308. })
  309. },
  310. /**
  311. * 生命周期函数--监听页面显示
  312. */
  313. onShow: function() {
  314. console.log('room show')
  315. wx.setKeepScreenOn({
  316. keepScreenOn: true,
  317. })
  318. },
  319. /**
  320. * 生命周期函数--监听页面隐藏
  321. */
  322. onHide: function() {
  323. console.log('room hide')
  324. },
  325. /**
  326. * 生命周期函数--监听页面卸载
  327. */
  328. onUnload: function() {
  329. console.log('room unload')
  330. wx.setKeepScreenOn({
  331. keepScreenOn: false,
  332. })
  333. },
  334. })