|
@@ -0,0 +1,117 @@
|
|
|
+import { defineComponent, ref } from 'vue'
|
|
|
+import * as RongIMLib from '@rongcloud/imlib-next'
|
|
|
+import { installer, RCRTCCode, RCRTCClient, RCLocalTrack } from '@rongcloud/plugin-rtc'
|
|
|
+import runtime from './runtime'
|
|
|
+import { requireMedia, removeMedia } from './helpers'
|
|
|
+
|
|
|
+const RONG_IM_TOKEN = 'c9kqb3rdc451j'
|
|
|
+
|
|
|
+RongIMLib.init({
|
|
|
+ appkey: RONG_IM_TOKEN,
|
|
|
+})
|
|
|
+
|
|
|
+/**
|
|
|
+ * 监听消息通知
|
|
|
+ */
|
|
|
+ const Events = RongIMLib.Events;
|
|
|
+ RongIMLib.addEventListener(Events.MESSAGES, (event) => {
|
|
|
+ console.log('received messages', event.messages)
|
|
|
+ })
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 监听 IM 连接状态变化
|
|
|
+ */
|
|
|
+ RongIMLib.addEventListener(Events.CONNECTING, () => {
|
|
|
+ runtime.imConnectStatus = 'connecting'
|
|
|
+ })
|
|
|
+
|
|
|
+ RongIMLib.addEventListener(Events.CONNECTED, () => {
|
|
|
+ runtime.imConnectStatus = 'connected'
|
|
|
+ })
|
|
|
+
|
|
|
+ RongIMLib.addEventListener(Events.DISCONNECT, () => {
|
|
|
+ runtime.imConnectStatus = 'disconnect'
|
|
|
+ })
|
|
|
+
|
|
|
+ let rtcClient: RCRTCClient | null
|
|
|
+
|
|
|
+ RongIMLib.connect('hXAfqkZDs146m6MjMukBMEHvmRoZQV7Hgh8ZG4iscyE=@n56a.cn.rongnav.com;n56a.cn.rongcfg.com').then((user) => {
|
|
|
+ console.log('connect success', user.data?.userId);
|
|
|
+ rtcClient = RongIMLib.installPlugin(installer, { /*初始化参数请参考下方参数说明*/ })
|
|
|
+})
|
|
|
+.catch((error) => {
|
|
|
+ console.log(`连接失败: ${error}`);
|
|
|
+});
|
|
|
+
|
|
|
+
|
|
|
+const videoRef = ref<HTMLVideoElement | null>(null)
|
|
|
+
|
|
|
+type VideoStatus = 'init' | 'stream' | 'liveing' | 'stopped' | 'error' | 'loading'
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'LiveBroadcast',
|
|
|
+ data () {
|
|
|
+ return {
|
|
|
+ mediaStreamTrack: [] as MediaStreamTrack[],
|
|
|
+ mediaStreams: null as MediaStream | null,
|
|
|
+ videoStatus: 'init' as VideoStatus,
|
|
|
+ screenShareStatus: false,
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async mounted() {
|
|
|
+ try {
|
|
|
+ const mediaStreams = await requireMedia({
|
|
|
+ audio: true,
|
|
|
+ video: true
|
|
|
+ })
|
|
|
+ this.videoStatus = 'stream'
|
|
|
+ this.mediaStreams = mediaStreams
|
|
|
+ this.mediaStreamTrack = mediaStreams.getTracks()
|
|
|
+ this.setVideoSrcObject(mediaStreams)
|
|
|
+ } catch (error) {
|
|
|
+ this.videoStatus = 'error'
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ setVideoSrcObject (mediaStreams: MediaStream | null) {
|
|
|
+ const video = videoRef.value
|
|
|
+ if (video && mediaStreams) {
|
|
|
+ video.srcObject = mediaStreams
|
|
|
+ video.onloadedmetadata = () => {
|
|
|
+ video.play()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ closeLive() {
|
|
|
+ removeMedia(this.mediaStreams, this.mediaStreamTrack)
|
|
|
+ this.videoStatus = 'stopped'
|
|
|
+ },
|
|
|
+ async screenVideo() {
|
|
|
+ if (rtcClient) {
|
|
|
+ const { code, track: screenTrack } = await rtcClient.createScreenVideoTrack()
|
|
|
+ if (code !== RCRTCCode.SUCCESS) {
|
|
|
+ this.screenShareStatus = false
|
|
|
+ } else {
|
|
|
+ this.screenShareStatus = true
|
|
|
+ this.setVideoSrcObject(screenTrack?._msStream as MediaStream)
|
|
|
+ }
|
|
|
+ screenTrack?.on(RCLocalTrack.EVENT_LOCAL_TRACK_END, (track: RCLocalTrack) => {
|
|
|
+ console.log('screen track end', track)
|
|
|
+ this.screenShareStatus = false
|
|
|
+ this.setVideoSrcObject(this.mediaStreams)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ render() {
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <video ref={videoRef}></video>
|
|
|
+ <button onClick={this.closeLive}>关闭直播</button>
|
|
|
+ <button onClick={this.screenVideo}>屏幕共享</button>
|
|
|
+ <div>video: {this.videoStatus}, imStatus: {runtime.imConnectStatus}</div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+})
|