RightPopup.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <template>
  2. <!-- 右侧弹框 -->
  3. <van-popup :value="levitatedSphereVisible" @input="showChange" position="right" class="levitated-sphere-drawer"
  4. overlay-class="levitated-sphere-overlay" :overlay-style="{'background-color': 'transparent !important'}">
  5. <div class="flex-column" style="min-width: 50px;">
  6. <div class="flex-column-container">
  7. <div>
  8. <div v-for="item in definitionList" :key="item.key"
  9. :class="['tc drawer-item mb-4', {active: actDefinition === item.name}]"
  10. @click.prevent="definitionFun(item)">
  11. {{item.name}}
  12. </div>
  13. <!-- <div class="tc drawer-item mb-4" @click.prevent="resolutionRatio">
  14. 分辨率
  15. </div> -->
  16. <div class="tc drawer-item mb-4" @click.prevent="volumeControl(24)">
  17. 音量 +
  18. </div>
  19. <div class="tc drawer-item" @click.prevent="volumeControl(25)">
  20. 音量 -
  21. </div>
  22. </div>
  23. </div>
  24. <div class="exit">
  25. <template v-for="(item, index) in exitList">
  26. <div :key="item.key" :class="['tc', {'mb-4': index !== exitList.length - 1}, item.key]"
  27. @click.prevent="exitFun(item.key)">
  28. <img :src="item.img" alt="">
  29. <div class="drawer-item">
  30. {{item.name}}
  31. </div>
  32. </div>
  33. </template>
  34. </div>
  35. </div>
  36. </van-popup>
  37. </template>
  38. <script>
  39. export default {
  40. name: 'RightPopup',
  41. props: {
  42. // 拉流渲染引擎实例
  43. engine: {
  44. type: Object,
  45. default: () => ({})
  46. },
  47. userCardId: {
  48. type: String,
  49. default: ''
  50. },
  51. // popup是否显示
  52. levitatedSphereVisible: {
  53. type: Boolean,
  54. default: false
  55. },
  56. // 清晰度默认值
  57. definitionValue: {
  58. type: String,
  59. default: ()=> localStorage.getItem('definitionValue') ?? '标清',
  60. },
  61. // 清晰度列表
  62. definitionList: {
  63. type: Array,
  64. default: () => [{
  65. name: '自动',
  66. value: 2800
  67. }, {
  68. name: '高清',
  69. value: 2800
  70. }, {
  71. name: '标清',
  72. value: 1500,
  73. }, {
  74. name: '流畅',
  75. value: 1000,
  76. }]
  77. },
  78. // 清晰度对应分辨率和帧率列表
  79. resolutionRatioList: {
  80. type: Object,
  81. default: () => ({
  82. '自动': { width: 720, height: 1280, fps: 30 },
  83. '高清': { width: 720, height: 1280, fps: 30 },
  84. '标清': { width: 540, height: 960, fps: 25 },
  85. '流畅': { width: 450, height: 800, fps: 20 },
  86. })
  87. },
  88. // url中获取的参数, 父组件传递
  89. parametersData: {
  90. type: Object,
  91. default: () => ({})
  92. },
  93. },
  94. data() {
  95. return {
  96. // 当前清晰度
  97. actDefinition: this.definitionValue,
  98. }
  99. },
  100. computed: {
  101. // 右侧弹框退出相关按钮
  102. exitList() {
  103. let arr = [{
  104. name: '剪贴版',
  105. key: "shearplate",
  106. img: '../static/img/wx/jianqieban_icon.png'
  107. }, {
  108. name: '退出',
  109. key: 'signout',
  110. img: '../static/img/wx/tuichu_icon.png'
  111. }]
  112. if ([1, 2, 3].includes(+this.parametersData.userCardType)) {
  113. arr.push({
  114. name: '退出并下机',
  115. key: 'dormant',
  116. img: '../static/img/wx/tuichu_icon.png'
  117. })
  118. }
  119. return arr
  120. }
  121. },
  122. methods: {
  123. showChange(val){
  124. this.$emit('update:levitatedSphereVisible', val);
  125. },
  126. // 清晰度 画质
  127. definitionFun(item) {
  128. try {
  129. this.actDefinition = item.name;
  130. // 设置日志参数 推流质量
  131. // logReportObj.setParams({ imageQuality: item.name });
  132. localStorage.setItem('definitionValue', item.name);
  133. // 设置码率
  134. this.setBitrate(item);
  135. this.$emit('update:levitatedSphereVisible', false);
  136. } catch (err) {
  137. console.log(err)
  138. }
  139. },
  140. // 设置码率
  141. setBitrate(item) {
  142. // 设置码率和是否允许自动
  143. this.engine?.setCustomBitrate(item.value, item.name === '自动');
  144. // 获取并设置编码器分辨率和帧率
  145. const config = this.resolutionRatioList[item.name];
  146. if (config) {
  147. this.engine?.setEncoderSize(config);
  148. }
  149. },
  150. // 分辨率 已无用,2.0sdk只能固定的几个分辨率值 resolutionRatioList
  151. resolutionRatio() {
  152. request.get('/api/resources/v5/machine/resolution/getResolvingPower', { params: { userCardId: this.parametersData.userCardId } }).then(res => {
  153. if (res.success) {
  154. this.resolutionRatioList = res.data.map(item => {
  155. item.height = item.high
  156. return item
  157. })
  158. }
  159. })
  160. },
  161. // 音量控制 24: 音量+ 25: 音量-
  162. volumeControl(value) {
  163. this.engine.sendKey && this.engine.sendKey(value);
  164. },
  165. // 退出相关按钮操作
  166. exitFun(key) {
  167. console.log(key)
  168. switch (key) {
  169. case 'dormant': // 退出并下机
  170. this.$dialog.alert({
  171. title: '提示',
  172. message: '确定退出云手机并下机',
  173. confirmButtonText: '确定',
  174. confirmButtonColor: '#3cc51f',
  175. showCancelButton: true,
  176. beforeClose: (action, done) => {
  177. if (action === 'cancel') done()
  178. if (action === 'confirm') {
  179. this.downline(done)
  180. }
  181. }
  182. })
  183. break;
  184. case 'shearplate': // 剪贴板
  185. // 打开剪贴板
  186. this.$emit('shearplate');
  187. // 关闭popup
  188. this.$emit('update:levitatedSphereVisible', false);
  189. break;
  190. case 'signout':
  191. // 关闭popup
  192. this.$emit('update:levitatedSphereVisible', false);
  193. this.$emit('exit');
  194. break;
  195. }
  196. },
  197. // 退出并下机
  198. async downline(fun = () => {}) {
  199. try {
  200. const res = await this.$axios.get('/resources/yearMember/downline?userCardId=${this.userCardId}`');
  201. if(!res.status){
  202. fun(true);
  203. // 判断是否是顶级窗口(不是嵌套在 iframe 中)目前只有ios的浏览器中才会是顶级窗口
  204. const isTopWindow = window.parent === window.self;
  205. if(isTopWindow){
  206. // 通信给h5项目告知是退出并下机
  207. parent.postMessage({ type: 'exit' }, '*');
  208. uni.postMessage({ data: { type: 'exit' }});
  209. }
  210. this.$emit('exit');
  211. return
  212. }
  213. fun(false)
  214. this.$toast(res.msg);
  215. } catch (error) {
  216. console.log(error);
  217. }
  218. },
  219. }
  220. }
  221. </script>
  222. <style lang="less" scoped>
  223. .levitated-sphere-drawer {
  224. height: 100%;
  225. max-height: none !important;
  226. min-width: 1rem;
  227. color: #fff;
  228. background-color: rgba(2, 2, 6, 0.5);
  229. padding: 30px 10px 0;
  230. box-sizing: border-box;
  231. }
  232. .levitated-sphere-drawer .drawer-item {
  233. line-height: 30px;
  234. border-radius: 3px;
  235. -moz-user-select: none;
  236. -webkit-user-select: none;
  237. -ms-user-select: none;
  238. -khtml-user-select: none;
  239. user-select: none;
  240. }
  241. .levitated-sphere-drawer .drawer-item.active {
  242. background: rgb(255, 255, 255);
  243. color: #000;
  244. }
  245. .levitated-sphere-drawer .exit {
  246. line-height: 30px;
  247. }
  248. .levitated-sphere-drawer .exit img {
  249. width: 24px;
  250. height: 24px;
  251. }
  252. .flex-column {
  253. height: 100%;
  254. display: flex;
  255. flex-direction: column;
  256. }
  257. .flex-column-container {
  258. flex: 1;
  259. overflow-y: auto;
  260. }
  261. .tc {
  262. text-align: center;
  263. }
  264. </style>