index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <template>
  2. <view class="defaultStyles">
  3. </view>
  4. </template>
  5. <script lang="uts">
  6. /**
  7. * 引用 iOS 系统库
  8. * [可选实现,按需引入]
  9. */
  10. import {
  11. UIButton,
  12. UIControl
  13. } from "UIKit"
  14. /**
  15. * 引入三方库
  16. * [可选实现,按需引入]
  17. *
  18. * 在 iOS 平台引入三方库有以下两种方式:
  19. * 1、通过引入三方库framework 或者.a 等方式,需要将 .framework 放到 ./Frameworks 目录下,将.a 放到 ./Libs 目录下。更多信息[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#ios-平台原生配置)
  20. * 2、通过 cocoaPods 方式引入,将要引入的 pod 信息配置到 config.json 文件下的 dependencies-pods 字段下。详细配置方式[详见](https://uniapp.dcloud.net.cn/plugin/uts-ios-cocoapods.html)
  21. *
  22. * 在通过上述任意方式依赖三方库后,使用时需要在文件中 import:
  23. * 示例:import { LottieAnimationView, LottieAnimation, LottieLoopMode } from 'Lottie'
  24. */
  25. /**
  26. * UTSiOS、UTSComponent 为平台内置对象,不需要 import 可直接调用其API,[详见](https://uniapp.dcloud.net.cn/uts/utsios.html)
  27. */
  28. import { UTSComponent } from "DCloudUTSFoundation"
  29. import { RTCMTLVideoView } from "WebRTC"
  30. import { UTSWebRTC } from "./index.uts"
  31. import { expandToSuperView } from "./layout_utils.uts"
  32. //原生提供以下属性或方法的实现
  33. export default {
  34. data() {
  35. return {
  36. isFront: true
  37. };
  38. },
  39. /**
  40. * 组件名称,也就是开发者使用的标签
  41. */
  42. name: "wrs-uts-webrtc-view",
  43. /**
  44. * 组件涉及的事件声明,只有声明过的事件,才能被正常发送
  45. */
  46. emits: [],
  47. /**
  48. * 属性声明,组件的使用者会传递这些属性值到组件
  49. */
  50. props: {
  51. /**
  52. * 字符串类型 属性:buttontext 需要设置默认值
  53. */
  54. "userId": {
  55. type: String,
  56. default: ""
  57. }
  58. },
  59. /**
  60. * 组件内部变量声明
  61. */
  62. /**
  63. * 属性变化监听器实现
  64. */
  65. watch: {
  66. "userId": {
  67. /**
  68. * 这里监听属性变化,并进行组件内部更新
  69. */
  70. handler(newValue : String, oldValue : String) {
  71. this.refreshUserId()
  72. },
  73. /**
  74. * 创建时是否通过此方法更新属性,默认值为false
  75. */
  76. immediate: false
  77. },
  78. },
  79. /**
  80. * 规则:如果没有配置expose,则methods中的方法均对外暴露,如果配置了expose,则以expose的配置为准向外暴露
  81. * ['publicMethod'] 含义为:只有 `publicMethod` 在实例上可用
  82. */
  83. methods: {
  84. refreshUserId() {
  85. if (this.userId.count > 0) {
  86. const supView = this.$el
  87. this.clearSubViews()
  88. let view = RTCMTLVideoView()
  89. view.videoContentMode = UIView.ContentMode.scaleAspectFill
  90. supView.addSubview(view)
  91. expandToSuperView(view)
  92. view.clipsToBounds = true
  93. const webRTC = UTSWebRTC.currentWebRTC
  94. if (webRTC != null) {
  95. const mediaStream = webRTC?.getMediaStream(this.userId)
  96. if (mediaStream != null) {
  97. let track = mediaStream?.videoTracks.first
  98. if (track != null) {
  99. track?.add(view)
  100. } else {
  101. console.log("video track is null")
  102. }
  103. } else {
  104. console.log("mediaStream is null")
  105. }
  106. } else {
  107. console.log("UTSWebRTC.currentWebRTC is null")
  108. }
  109. } else {
  110. // console.log(`userId is empty:${this.userId}`)
  111. }
  112. },
  113. renderRemoteVideo(userId : string) {
  114. this.userId = userId
  115. this.refreshUserId()
  116. },
  117. renderLocalVideo() {
  118. this.clearSubViews()
  119. let view = RTCMTLVideoView()
  120. view.videoContentMode = UIView.ContentMode.scaleAspectFill
  121. view.clipsToBounds = true
  122. const supView = this.$el
  123. supView.addSubview(view)
  124. expandToSuperView(view)
  125. const webRTC = UTSWebRTC.currentWebRTC
  126. if (webRTC != null) {
  127. const localVideoTrack = webRTC?.localVideoTrack
  128. if(localVideoTrack != null) {
  129. localVideoTrack?.add(view)
  130. } else {
  131. console.log("localVideoTrack is null")
  132. }
  133. } else {
  134. console.log("UTSWebRTC.currentWebRTC is null")
  135. }
  136. },
  137. clearSubViews() {
  138. const supView = this.$el
  139. let subviews = supView.subviews
  140. const count = subviews.count
  141. for (let i : Int = 0; i < count; i++) {
  142. const view = subviews[i]
  143. view.removeFromSuperview()
  144. }
  145. },
  146. startCaptureLocalVideo(params : string) {
  147. let isFront = true
  148. let model = JSON.parse(params)
  149. if (model != null) {
  150. const json = model! as UTSJSONObject
  151. const isFrontValue = json["isFront"]
  152. if (isFrontValue != null) {
  153. isFront = isFrontValue! as boolean
  154. }
  155. }
  156. this.startCapture(isFront, true)
  157. },
  158. switchCamera(isFront : boolean) {
  159. this.startCapture(isFront, false)
  160. },
  161. stopCapture() {
  162. const webRTC = UTSWebRTC.currentWebRTC
  163. if (webRTC != null) {
  164. const videoCapturer = webRTC?.videoCapturer
  165. if (videoCapturer != null) {
  166. if (videoCapturer! instanceof RTCCameraVideoCapturer) {
  167. const capturer = videoCapturer! as RTCCameraVideoCapturer
  168. capturer.stopCapture()
  169. }
  170. }
  171. }
  172. },
  173. resumeCapture() {
  174. this.startCapture(this.isFront, false)
  175. },
  176. startCapture(isFront : boolean, addView : boolean) {
  177. },
  178. renderRemoteVideo000() {
  179. let view = this.$el
  180. const webRTC = UTSWebRTC.currentWebRTC
  181. if (webRTC != null) {
  182. // webRTC?.remoteVideoTrack?.add(view)
  183. }
  184. },
  185. getDevice(isFront : boolean) : AVCaptureDevice | null {
  186. const devices = RTCCameraVideoCapturer.captureDevices()
  187. const count = devices.count
  188. for (let i : Int = 0; i < count; i++) {
  189. let device = devices[i]
  190. if (isFront) {
  191. if (device.position == AVCaptureDevice.Position.front) {
  192. return device
  193. }
  194. } else {
  195. if (device.position == AVCaptureDevice.Position.back) {
  196. return device
  197. }
  198. }
  199. }
  200. return null
  201. }
  202. /**
  203. * 内部使用的组件方法
  204. */
  205. },
  206. /**
  207. * 组件被创建,组件第一个生命周期,
  208. * 在内存中被占用的时候被调用,开发者可以在这里执行一些需要提前执行的初始化逻辑
  209. * [可选实现]
  210. */
  211. created() {
  212. },
  213. /**
  214. * 对应平台的view载体即将被创建,对应前端beforeMount
  215. * [可选实现]
  216. */
  217. NVBeforeLoad() {
  218. },
  219. /**
  220. * 创建原生View,必须定义返回值类型
  221. * 开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型
  222. * [必须实现]
  223. */
  224. NVLoad() : UIView {
  225. let view = UIView()
  226. view.clipsToBounds = true
  227. return view
  228. },
  229. /**
  230. * 原生View已创建
  231. * [可选实现]
  232. */
  233. NVLoaded() {
  234. this.refreshUserId()
  235. this.$emit("onLoadView")
  236. },
  237. /**
  238. * 原生View布局完成
  239. * [可选实现]
  240. */
  241. NVLayouted() {
  242. },
  243. /**
  244. * 原生View将释放
  245. * [可选实现]
  246. */
  247. NVBeforeUnload() { },
  248. /**
  249. * 原生View已释放,这里可以做释放View之后的操作
  250. * [可选实现]
  251. */
  252. NVUnloaded() {
  253. },
  254. /**
  255. * 组件销毁
  256. * [可选实现]
  257. */
  258. unmounted() { }
  259. /**
  260. * 更多组件开发的信息详见:https://uniapp.dcloud.net.cn/plugin/uts-component.html
  261. */
  262. }
  263. </script>
  264. <style>
  265. </style>