index.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <template>
  2. <view>
  3. </view>
  4. </template>
  5. <script lang="uts">
  6. /**
  7. * 引用 Android 系统库
  8. * [可选实现,按需引入]
  9. */
  10. import TextUtils from 'android.text.TextUtils';
  11. import Button from 'android.widget.Button';
  12. import View from 'android.view.View';
  13. import SurfaceViewRenderer from "org.webrtc.SurfaceViewRenderer"
  14. import LinearLayout from "android.widget.LinearLayout"
  15. import { UTSWebRTC } from "./index.uts"
  16. import { UTSAndroid } from "io.dcloud.uts"
  17. /**
  18. * 引入三方库
  19. * [可选实现,按需引入]
  20. *
  21. * 在 Android 平台引入三方库有以下两种方式:
  22. * 1、[推荐] 通过 仓储 方式引入,将 三方库的依赖信息 配置到 config.json 文件下的 dependencies 字段下。详细配置方式[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#dependencies)
  23. * 2、直接引入,将 三方库的aar或jar文件 放到libs目录下。更多信息[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#android%E5%B9%B3%E5%8F%B0%E5%8E%9F%E7%94%9F%E9%85%8D%E7%BD%AE)
  24. *
  25. * 在通过上述任意方式依赖三方库后,使用时需要在文件中 import
  26. * import { LottieAnimationView } from 'com.airbnb.lottie.LottieAnimationView'
  27. */
  28. /**
  29. * UTSAndroid 为平台内置对象,不需要 import 可直接调用其API,[详见](https://uniapp.dcloud.net.cn/uts/utsandroid.html#utsandroid)
  30. */
  31. //原生提供以下属性或方法的实现
  32. export default {
  33. /**
  34. * 组件名称,也就是开发者使用的标签
  35. */
  36. name: "wrs-uts-webrtc-view",
  37. /**
  38. * 组件涉及的事件声明,只有声明过的事件,才能被正常发送
  39. */
  40. emits: [],
  41. /**
  42. * 属性声明,组件的使用者会传递这些属性值到组件
  43. */
  44. props: {
  45. "userId": {
  46. type: String,
  47. default: ""
  48. }
  49. },
  50. /**
  51. * 组件内部变量声明
  52. */
  53. data() {
  54. return {}
  55. },
  56. /**
  57. * 属性变化监听器实现
  58. */
  59. watch: {
  60. "userId": {
  61. /**
  62. * 这里监听属性变化,并进行组件内部更新
  63. */
  64. handler(newValue : string, oldValue : string) {
  65. this.refreshUserId()
  66. },
  67. immediate: false // 创建时是否通过此方法更新属性,默认值为false
  68. },
  69. },
  70. /**
  71. * 规则:如果没有配置expose,则methods中的方法均对外暴露,如果配置了expose,则以expose的配置为准向外暴露
  72. * ['publicMethod'] 含义为:只有 `publicMethod` 在实例上可用
  73. */
  74. methods: {
  75. refreshUserId() {
  76. if (this.userId.length > 0) {
  77. this.$el?.removeAllViews()
  78. const rendererView = new SurfaceViewRenderer(context)
  79. const layout = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
  80. this.$el?.addView(rendererView, layout)
  81. const webRTC = UTSWebRTC.currentWebRTC
  82. if (webRTC != null) {
  83. const mediaStream = webRTC.getMediaStream(this.userId)
  84. if (mediaStream != null) {
  85. const eglBase = webRTC.eglBase
  86. if (eglBase != null) {
  87. rendererView.init(eglBase.getEglBaseContext(), null);
  88. mediaStream.videoTracks.get(0).addSink(rendererView);
  89. } else {
  90. console.log('eglBase is null')
  91. }
  92. } else {
  93. console.log('user MediaStream is null')
  94. }
  95. } else {
  96. console.log('UTSWebRTC.currentWebRTC is null')
  97. }
  98. }
  99. },
  100. renderRemoteVideo(userId : string) {
  101. this.userId = userId
  102. this.refreshUserId()
  103. },
  104. renderLocalVideo() {
  105. // console.log(`${Thread.currentThread()}`)
  106. UTSAndroid.getDispatcher("main").async((_) => {
  107. this.$el?.removeAllViews()
  108. const rendererView = new SurfaceViewRenderer(context)
  109. const layout = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
  110. this.$el?.addView(rendererView, layout)
  111. const webRTC = UTSWebRTC.currentWebRTC
  112. if (webRTC != null) {
  113. const localVideoTrack = webRTC.localVideoTrack
  114. if (localVideoTrack != null) {
  115. const eglBase = webRTC.eglBase
  116. if (eglBase != null) {
  117. rendererView.init(eglBase.getEglBaseContext(), null);
  118. localVideoTrack.addSink(rendererView);
  119. } else {
  120. console.log('eglBase is null')
  121. }
  122. } else {
  123. console.log('localVideoTrack is null')
  124. }
  125. } else {
  126. console.log('UTSWebRTC.currentWebRTC is null')
  127. }
  128. }, null)
  129. }
  130. },
  131. /**
  132. * [可选实现] 组件被创建,组件第一个生命周期,
  133. * 在内存中被占用的时候被调用,开发者可以在这里执行一些需要提前执行的初始化逻辑
  134. */
  135. created() {
  136. },
  137. /**
  138. * [可选实现] 对应平台的view载体即将被创建,对应前端beforeMount
  139. */
  140. NVBeforeLoad() {
  141. },
  142. /**
  143. * [必须实现] 创建原生View,必须定义返回值类型
  144. * 开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型
  145. * (Android需要明确知道View类型,需特殊校验)
  146. */
  147. NVLoad() : LinearLayout {
  148. let view = new LinearLayout($androidContext!);
  149. return view;
  150. },
  151. /**
  152. * [可选实现] 原生View已创建
  153. */
  154. NVLoaded() {
  155. this.refreshUserId()
  156. this.$emit("onLoadView", {})
  157. },
  158. /**
  159. * [可选实现] 原生View布局完成
  160. */
  161. NVLayouted() {
  162. },
  163. /**
  164. * [可选实现] 原生View将释放
  165. */
  166. NVBeforeUnload() {
  167. },
  168. /**
  169. * [可选实现] 原生View已释放,这里可以做释放View之后的操作
  170. */
  171. NVUnloaded() {
  172. },
  173. /**
  174. * [可选实现] 组件销毁
  175. */
  176. unmounted() {
  177. },
  178. /**
  179. * [可选实现] 自定组件布局尺寸,用于告诉排版系统,组件自身需要的宽高
  180. * 一般情况下,组件的宽高应该是由终端系统的排版引擎决定,组件开发者不需要实现此函数
  181. * 但是部分场景下,组件开发者需要自己维护宽高,则需要开发者重写此函数
  182. */
  183. NVMeasure(size : UTSSize) : UTSSize {
  184. // size.width = 300.0.toFloat();
  185. // size.height = 200.0.toFloat();
  186. return size;
  187. }
  188. }
  189. /**
  190. * 定义按钮点击后触发回调的类
  191. * [可选实现]
  192. */
  193. class ButtonClickListener extends View.OnClickListener {
  194. /**
  195. * 如果需要在回调类或者代理类中对组件进行操作,比如调用组件方法,发送事件等,需要在该类中持有组件对应的原生类的对象
  196. * 组件原生类的基类为 UTSComponent,该类是一个泛型类,需要接收一个类型变量,该类型变量就是原生组件的类型
  197. */
  198. private comp : UTSComponent<Button>;
  199. constructor(comp : UTSComponent<Button>) {
  200. super();
  201. this.comp = comp;
  202. }
  203. /**
  204. * 按钮点击回调方法
  205. */
  206. override onClick(v ?: View) {
  207. console.log("按钮被点击");
  208. // 发送事件
  209. this.comp.$emit("buttonclick");
  210. }
  211. }
  212. </script>
  213. <style>
  214. </style>