live.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. import {getDataSet, getEventParam, toast} from "../../utils/utils";
  2. import {liveSources, LOG_TAGS} from "../../model/enum";
  3. import {timStore} from "../../store/tim";
  4. import {createStoreBindings} from "mobx-miniprogram-bindings";
  5. import Tim from "../../model/tim";
  6. import User from "../../model/user";
  7. import EduTRTC from "../../model/edu-trct";
  8. import Route from "../../model/route";
  9. // var log = require('../../utils/log.js') // 引用上面的 log.js 文件
  10. import MyLogManager from "../../utils/log";
  11. var log = new MyLogManager(LOG_TAGS.LIVE);
  12. // var testLog = new MyLogManager('test');
  13. Page({
  14. data: {
  15. liveSourcesEnum: liveSources,
  16. user: {},
  17. groupId: '',
  18. pic: '',
  19. userSig: '',
  20. scheduleId: '',
  21. isFull: false,
  22. isRotate:false,
  23. bigIndex: 0,
  24. isLive: false,
  25. hasRotate:false,
  26. // pageOptions: {}
  27. },
  28. async onLoad(options) {
  29. // wx.setKeepScreenOn({
  30. // keepScreenOn: true,
  31. // })
  32. // 退出时 退房处理 使用 ↓
  33. // this.storeBindings = createStoreBindings(this, {
  34. // store: timStore,
  35. // fields: ['isCanShare', 'isAudVideo', 'isAudText', 'isStuVideo', 'pusher', 'playerList', 'handReply'],
  36. // actions: ['setScroll', 'setHandReply', 'pushMessage', 'resetMessage', 'logout', 'initLive', "exitRoom",
  37. // "setPusherAttributesHandler",
  38. // "setPlayerAttributesHandler"]
  39. // })
  40. // this.setData({
  41. // pageOptions: options
  42. // });
  43. // const title = options.title;
  44. // wx.setNavigationBarTitle({title})
  45. //原来的 ↓
  46. wx.setKeepScreenOn({
  47. keepScreenOn: true,
  48. })
  49. this.storeBindings = createStoreBindings(this, {
  50. store: timStore,
  51. fields: ['isCanShare', 'isAudVideo', 'isAudText', 'isStuVideo', 'pusher', 'playerList', 'handReply'],
  52. actions: ['setScroll', 'setHandReply', 'pushMessage', 'resetMessage', 'logout', 'initLive', "exitRoom",
  53. "setPusherAttributesHandler",
  54. "setPlayerAttributesHandler"]
  55. })
  56. const {title, type, eId, scheduleId, eduStuName,pic} = options;
  57. let userID = "";
  58. let groupId = "";
  59. if (type == liveSources.DEFAULT) {
  60. userID = "student_" + eId;
  61. } else if (type == liveSources.GUEST) {
  62. userID = "guest_" + eId;
  63. }
  64. groupId = "schedule_" + scheduleId;
  65. const res = await User.getUserSign(userID);
  66. const userSig = res.userSig
  67. Tim.SDKAppID = res.appID;
  68. this.setData({
  69. type,
  70. user: {nickname: eduStuName, avatar: '', gender: 1, userID},
  71. groupId,
  72. scheduleId,
  73. userSig,
  74. pic
  75. }, () => {
  76. console.log('群组ID: ', groupId);
  77. log.info('onload 设置的群组ID: ', groupId);
  78. this.initLive(this);
  79. wx.nextTick(() => {
  80. // 为了防止直播画面不显示 ↓
  81. setTimeout(() => EduTRTC.getInstance().getSDK().getPusherInstance().start(), 800)
  82. });
  83. });
  84. wx.setNavigationBarTitle({title})
  85. },
  86. // async onShow(){
  87. // console.log('onShow -> live');
  88. // wx.setKeepScreenOn({
  89. // keepScreenOn: true,
  90. // });
  91. // const {type, eId, scheduleId, eduStuName,pic} = this.data.pageOptions;
  92. // let userID = "";
  93. // let groupId = "";
  94. // if (type == liveSources.DEFAULT) {
  95. // userID = "student_" + eId;
  96. // } else if (type == liveSources.GUEST) {
  97. // userID = "guest_" + eId;
  98. // }
  99. // groupId = "schedule_" + scheduleId;
  100. // const res = await User.getUserSign(userID);
  101. // const userSig = res.userSig
  102. // Tim.SDKAppID = res.appID;
  103. // this.setData({
  104. // type,
  105. // user: {nickname: eduStuName, avatar: '', gender: 1, userID},
  106. // groupId,
  107. // scheduleId,
  108. // userSig,
  109. // pic
  110. // }, () => {
  111. // console.log('群组ID: ', groupId);
  112. // log.info('onload 设置的群组ID: ', groupId);
  113. // this.initLive(this);
  114. // // 为了防止直播画面不显示 ↓
  115. // setTimeout(() => EduTRTC.getInstance().getSDK().getPusherInstance().start(), 800)
  116. // });
  117. // },
  118. async reply(e) {
  119. let msg = getEventParam(e, "msg")
  120. if (!msg.trim()) {
  121. toast('请输入内容')
  122. return;
  123. }
  124. const message = Tim.getInstance().createGroupTextMsg(msg, this.data.groupId);
  125. this.setScroll(true)
  126. try {
  127. await Tim.getInstance().sendMessage(message);
  128. this.pushMessage(message)
  129. this.selectComponent('.bottom-reply').clear();
  130. } catch (e) {
  131. toast(e.message)
  132. }
  133. },
  134. async hand(e) {
  135. const message = Tim.getInstance().createHandMsg(this.data.groupId);
  136. const res = await Tim.getInstance().sendCMD(message, ({code}) => {
  137. if (code == 10017) {
  138. toast('举手失败:禁言情况不能举手');
  139. this.setHandReply(!this.data.handReply);
  140. }
  141. });
  142. },
  143. // async handleLeaveRoom(){
  144. // wx.setKeepScreenOn({
  145. // keepScreenOn: false,
  146. // })
  147. // this.exitRoom()
  148. // await this.logout()
  149. // // this.storeBindings.destroyStoreBindings()
  150. // },
  151. // onSaveExitState(){
  152. // testLog.info('exit room');
  153. // this.handleLeaveRoom();
  154. // console.log('exitRoom -> live');
  155. // },
  156. // onHide(){
  157. // console.log('exit');
  158. // testLog.info('exit room');
  159. // this.handleLeaveRoom();
  160. // },
  161. async onUnload() {
  162. wx.setKeepScreenOn({
  163. keepScreenOn: false,
  164. })
  165. this.exitRoom()
  166. await this.logout()
  167. this.storeBindings.destroyStoreBindings()
  168. // this.handleLeaveRoom();
  169. // this.storeBindings.destroyStoreBindings();
  170. },
  171. changeFull(e) {
  172. let verticalFullScreen = this.data.bigIndex === -1;
  173. if(!verticalFullScreen) {
  174. let currentBigerPlayer = this.data.playerList[this.data.bigIndex];
  175. // let livePlayerContext = EduTRTC.getInstance().getPlayerInstance(playerList.id);
  176. const {videoWidth, videoHeight} = currentBigerPlayer.netStatus;
  177. if(videoWidth && videoHeight && videoHeight > videoWidth) {
  178. verticalFullScreen = true;
  179. }
  180. }
  181. if(verticalFullScreen) {
  182. this.setData({
  183. isFull: !this.data.isFull
  184. });
  185. } else {
  186. this.rotate();
  187. }
  188. // let playerList = this.data.playerList[this.data.bigIndex];
  189. // this.rotate();
  190. // if (this.data.bigIndex==-1 || playerList.userID.indexOf("student") !=-1
  191. // || playerList.userID.indexOf("guest_") !=-1 ){
  192. // this.setData({
  193. // isFull: !this.data.isFull
  194. // })
  195. // }
  196. // else{
  197. // this.rotate();
  198. // }
  199. },
  200. handlePusher(e) {
  201. console.log("handlePusher", e)
  202. },
  203. handlePlayer(e) {
  204. if(this.data.isRotate){
  205. console.log("旋转状态下不允许切换了");
  206. return;
  207. }
  208. console.log("handlePlayer", e)
  209. let index = getDataSet(e, 'index');
  210. if (this.data.bigIndex == index || (index == -1 && !this.data.pusher.enableCamera)) {
  211. return;
  212. }
  213. this.setData({
  214. bigIndex: index
  215. })
  216. },
  217. switchCamera() {
  218. wx.createLivePusherContext().switchCamera({
  219. success() {
  220. },
  221. fail() {
  222. toast("切换失败")
  223. },
  224. }
  225. )
  226. },
  227. quitLink() {
  228. this.setPusherAttributesHandler({enableCamera: false, enableMic: false})
  229. },
  230. // 请保持跟 wxml 中绑定的事件名称一致
  231. _pusherStateChangeHandler(event) {
  232. console.log("_pusherStateChangeHandler************", event);
  233. const code = getEventParam(event, "code")
  234. if (code == 1018) {
  235. this.setData({
  236. isLive: true
  237. })
  238. }
  239. EduTRTC.getInstance().getSDK().pusherEventHandler(event)
  240. },
  241. _pusherNetStatusHandler(event) {
  242. EduTRTC.getInstance().getSDK().pusherNetStatusHandler(event)
  243. // try{
  244. // EduTRTC.getInstance().getSDK().pusherNetStatusHandler(event)
  245. // } catch(err) {
  246. // console.log('_pusherNetStatusHandler error:', err);
  247. // }
  248. },
  249. _pusherErrorHandler(event) {
  250. console.log("_pusherErrorHandler", event);
  251. EduTRTC.getInstance().getSDK().pusherErrorHandler(event)
  252. },
  253. _pusherBGMStartHandler(event) {
  254. EduTRTC.getInstance().getSDK().pusherBGMStartHandler(event)
  255. },
  256. _pusherBGMProgressHandler(event) {
  257. EduTRTC.getInstance().getSDK().pusherBGMProgressHandler(event)
  258. },
  259. _pusherBGMCompleteHandler(event) {
  260. EduTRTC.getInstance().getSDK().pusherBGMCompleteHandler(event)
  261. },
  262. _pusherAudioVolumeNotify(event) {
  263. EduTRTC.getInstance().getSDK().pusherAudioVolumeNotify(event)
  264. },
  265. _playerStateChange(event) {
  266. console.log("_playerStateChange", event);
  267. EduTRTC.getInstance().getSDK().playerEventHandler(event)
  268. },
  269. _playerFullscreenChange(event) {
  270. EduTRTC.getInstance().getSDK().playerFullscreenChange(event)
  271. let playerList = this.data.playerList[this.data.bigIndex];
  272. console.log("event",event)
  273. if (event.detail.fullScreen){
  274. this.setPlayerAttributesHandler(playerList,{objectFit:'contain'})
  275. }else{
  276. this.setPlayerAttributesHandler(playerList,{objectFit:'fillCrop'})
  277. }
  278. },
  279. _playerNetStatus(event) {
  280. EduTRTC.getInstance().getSDK().playerNetStatus(event)
  281. },
  282. _playerAudioVolumeNotify(event) {
  283. EduTRTC.getInstance().getSDK().playerAudioVolumeNotify(event)
  284. },
  285. onShareAppMessage(options) {
  286. let obj = {};
  287. if (this.data.pic){
  288. obj.imageUrl = this.data.pic
  289. }
  290. return {
  291. path: Route.getIndexUrl(this.data.scheduleId),
  292. ...obj
  293. }
  294. },
  295. rotate(){
  296. let that = this;
  297. let playerList = this.data.playerList[this.data.bigIndex];
  298. let livePlayerContext = wx.createLivePlayerContext(playerList.id);
  299. // let livePlayerContext = EduTRTC.getInstance().getPlayerInstance(playerList.id);
  300. const {videoWidth, videoHeight} = playerList.netStatus;
  301. // if(!videoWidth || !videoHeight) {
  302. // toast("网络状态不好,请稍后再试!");
  303. // return;
  304. // }
  305. const direction = videoWidth && videoHeight > videoWidth? 0 : 90;
  306. livePlayerContext.requestFullScreen({
  307. // direction: 90,
  308. direction,
  309. success(res) {
  310. that.setData({isRotate:true})
  311. },
  312. fail(e){
  313. toast("屏幕旋转失败,请稍后重试")
  314. console.log(e)
  315. }
  316. })
  317. },
  318. rotate2(){
  319. this.setPusherAttributesHandler({enableCamera: true, enableMic: true})
  320. },
  321. exitRotate(){
  322. let that = this;
  323. let playerList = this.data.playerList[this.data.bigIndex];
  324. let livePlayerContext = wx.createLivePlayerContext(playerList.id);
  325. // 解决退出全屏后 屏幕还是在旋转状态的问题 --- start
  326. livePlayerContext.requestFullScreen({
  327. direction: 0
  328. });
  329. // 解决退出全屏后 屏幕还是在旋转状态的问题 --- end
  330. wx.nextTick(() => {
  331. livePlayerContext.exitFullScreen({
  332. success(res) {
  333. that.setData({isRotate:false})
  334. },
  335. fail(e){
  336. toast("屏幕旋转失败,请稍后重试")
  337. console.log(e)
  338. }
  339. })
  340. });
  341. },
  342. //放大pusher的方法(就是改变pusher控件的大小)
  343. //放大player的方法
  344. testPlayerFullScreen(id) {
  345. let livePlayerContext = wx.createLivePlayerContext(id);
  346. //进入全屏
  347. let direction = 0;
  348. let item = this.data.playerList[0];//item是流集合里的一个
  349. // // 已知问题:视频的尺寸需要等待player触发NetStatus事件才能获取到,如果进房就双击全屏,全屏后的方向有可能不对。
  350. if (item.netStatus && item.netStatus.videoWidth && item.netStatus.videoHeight) {
  351. // 如果是横视频,全屏时进行横屏处理。如果是竖视频,则为0
  352. direction = item.netStatus.videoWidth > item.netStatus.videoHeight ? 90 : 0
  353. }
  354. livePlayerContext.requestFullScreen({
  355. direction,
  356. success(res) {
  357. }
  358. })
  359. //退出全屏
  360. livePlayerContext.exitFullScreen({
  361. success(res) {
  362. }
  363. })
  364. }
  365. });