yjz-web-sdk 1.0.10 → 1.0.11-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -0
- package/lib/ScreenControlUtil-D4-BTCo9.js +5230 -0
- package/lib/components/RemotePlayer/index.vue.d.ts +1 -73
- package/lib/composables/useCursorStyle.d.ts +1 -1
- package/lib/composables/useKeyboardControl.d.ts +5 -1
- package/lib/composables/useMouseTouchControl.d.ts +5 -4
- package/lib/composables/useRemoteVideo.d.ts +8 -25
- package/lib/composables/useResizeObserver.d.ts +1 -1
- package/lib/core/WebRTCSdk.d.ts +3 -0
- package/lib/core/data/WebRtcError.d.ts +3 -3
- package/lib/core/data/WebrtcDataType.d.ts +1 -11
- package/lib/core/groupctrl/SdkController.d.ts +2 -2
- package/lib/core/rtc/WebRTCClient.d.ts +13 -3
- package/lib/core/rtc/WebRTCConfig.d.ts +3 -1
- package/lib/core/rtc/WebRtcNegotiate.d.ts +3 -3
- package/lib/core/signal/SignalingClient.d.ts +1 -1
- package/lib/core/util/KeyCodeUtil.d.ts +6 -0
- package/lib/core/util/TurnTestUtil.d.ts +4 -4
- package/lib/index.d.ts +3 -3
- package/lib/uni/KeyboardControl.d.ts +53 -0
- package/lib/uni/Logger.d.ts +13 -0
- package/lib/uni/MouseTouchControl.d.ts +56 -0
- package/lib/uni/RemoteCanvasController.d.ts +11 -0
- package/lib/uni/RemoteController.d.ts +23 -0
- package/lib/uni/RemoteVideoController.d.ts +38 -0
- package/lib/uni/WebRTCWrapper.d.ts +57 -0
- package/lib/uni/constants.d.ts +42 -0
- package/lib/uni/index.d.ts +110 -0
- package/lib/{components/RemotePlayer → uni}/type.d.ts +1 -0
- package/lib/uni-sdk.js +1263 -0
- package/lib/yjz-web-sdk.js +312 -5955
- package/package.json +10 -20
- package/lib/core/data/TurnType.d.ts +0 -21
- package/lib/core/util/MapCache.d.ts +0 -20
- package/lib/render/Canvas2DRenderer.d.ts +0 -10
- package/lib/render/WebGLRenderer.d.ts +0 -16
- package/lib/render/WebGPURenderer.d.ts +0 -18
- package/lib/types/index.d.ts +0 -13
- package/lib/util/WasmUtil.d.ts +0 -17
- package/lib/worker/worker.d.ts +0 -1
- package/src/assets/icon/circle.svg +0 -1
- package/src/assets/icon/triangle.svg +0 -1
- package/src/assets/wasm/h264-atomic.wasm +0 -0
- package/src/assets/wasm/h264-simd.wasm +0 -0
- package/src/components/RemotePlayer/index.vue +0 -170
- package/src/components/RemotePlayer/type.ts +0 -11
- package/src/composables/useCursorStyle.ts +0 -15
- package/src/composables/useKeyboardControl.ts +0 -32
- package/src/composables/useMouseTouchControl.ts +0 -158
- package/src/composables/useRemoteVideo.ts +0 -248
- package/src/composables/useResizeObserver.ts +0 -27
- package/src/core/WebRTCSdk.ts +0 -561
- package/src/core/data/MessageType.ts +0 -70
- package/src/core/data/TurnType.ts +0 -25
- package/src/core/data/WebRtcError.ts +0 -93
- package/src/core/data/WebrtcDataType.ts +0 -354
- package/src/core/groupctrl/GroupCtrlSocketManager.ts +0 -94
- package/src/core/groupctrl/SdkController.ts +0 -96
- package/src/core/rtc/WebRTCClient.ts +0 -862
- package/src/core/rtc/WebRTCConfig.ts +0 -86
- package/src/core/rtc/WebRtcNegotiate.ts +0 -164
- package/src/core/signal/SignalingClient.ts +0 -221
- package/src/core/util/FileTypeUtils.ts +0 -75
- package/src/core/util/KeyCodeUtil.ts +0 -162
- package/src/core/util/Logger.ts +0 -83
- package/src/core/util/MapCache.ts +0 -135
- package/src/core/util/ScreenControlUtil.ts +0 -174
- package/src/core/util/TurnTestUtil.ts +0 -123
- package/src/env.d.ts +0 -30
- package/src/index.ts +0 -61
- package/src/render/Canvas2DRenderer.ts +0 -38
- package/src/render/WebGLRenderer.ts +0 -150
- package/src/render/WebGPURenderer.ts +0 -194
- package/src/types/index.ts +0 -15
- package/src/types/webgpu.d.ts +0 -1158
- package/src/util/WasmUtil.ts +0 -291
- package/src/worker/worker.ts +0 -292
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
import type {Ref} from 'vue';
|
|
2
|
-
import {computed, onBeforeUnmount, onMounted, ref} from 'vue';
|
|
3
|
-
import {Dimension} from '../components/RemotePlayer/type';
|
|
4
|
-
import {
|
|
5
|
-
checkDecoderSupport,
|
|
6
|
-
detectRenderingCapabilities,
|
|
7
|
-
VideoCodecType
|
|
8
|
-
} from "../util/WasmUtil";
|
|
9
|
-
import DecodeWorker from '../worker/worker.ts?worker&inline';
|
|
10
|
-
|
|
11
|
-
import {DecoderSupportResult, RendererType} from "../types";
|
|
12
|
-
|
|
13
|
-
export default function useRemoteVideo(
|
|
14
|
-
videoContainer: Ref<HTMLElement | null>,
|
|
15
|
-
remoteVideoElement: Ref<HTMLCanvasElement | null>,
|
|
16
|
-
audioElement: Ref<HTMLAudioElement | null>,
|
|
17
|
-
videoAngle: Ref<number>,
|
|
18
|
-
emit: (event: 'loadedSuccess' | 'loadedFailure', reason?: string) => void
|
|
19
|
-
) {
|
|
20
|
-
const screenStatus = ref(false);
|
|
21
|
-
const remoteVideo = ref<Partial<Dimension>>({});
|
|
22
|
-
const dimensions = ref<Dimension>({ width: 0, height: 0 });
|
|
23
|
-
const widthRadio = ref(0);
|
|
24
|
-
const heightRadio = ref(0);
|
|
25
|
-
const resizeObserver = ref<ResizeObserver | null>(null);
|
|
26
|
-
|
|
27
|
-
const renderType = ref<RendererType | null>(null)
|
|
28
|
-
|
|
29
|
-
const isRotated = computed(() => videoAngle.value % 180 !== 0);
|
|
30
|
-
// Worker 相关
|
|
31
|
-
const worker = ref<Worker | null>(null)
|
|
32
|
-
const offscreen = ref<OffscreenCanvas | null>(null)
|
|
33
|
-
const workerInited = ref(false)
|
|
34
|
-
const visible = ref<boolean>(true);
|
|
35
|
-
|
|
36
|
-
const videoSize = computed(() => {
|
|
37
|
-
let width: number;
|
|
38
|
-
let height: number;
|
|
39
|
-
|
|
40
|
-
const containerWidth = isRotated.value ? dimensions.value.height : dimensions.value.width;
|
|
41
|
-
const containerHeight = isRotated.value ? dimensions.value.width : dimensions.value.height;
|
|
42
|
-
|
|
43
|
-
const vWidth = remoteVideo.value.width ?? 720;
|
|
44
|
-
const vHeight = remoteVideo.value.height ?? 1280;
|
|
45
|
-
const aspect = vWidth / vHeight;
|
|
46
|
-
const videoHeight = containerWidth / aspect;
|
|
47
|
-
if (videoHeight > containerHeight) {
|
|
48
|
-
height = containerHeight;
|
|
49
|
-
width = height * aspect;
|
|
50
|
-
} else {
|
|
51
|
-
width = containerWidth;
|
|
52
|
-
height = videoHeight;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
widthRadio.value = vWidth / width;
|
|
56
|
-
heightRadio.value = vHeight / height;
|
|
57
|
-
|
|
58
|
-
return { width, height };
|
|
59
|
-
});
|
|
60
|
-
const waitingKeyFrame = ref(true)
|
|
61
|
-
const checkResult = ref<DecoderSupportResult | null>(null)
|
|
62
|
-
|
|
63
|
-
const observeContainer = () => {
|
|
64
|
-
if (!videoContainer.value) return;
|
|
65
|
-
resizeObserver.value = new ResizeObserver(([entry]) => {
|
|
66
|
-
const { width, height } = entry.contentRect;
|
|
67
|
-
dimensions.value = { width, height };
|
|
68
|
-
});
|
|
69
|
-
resizeObserver.value.observe(videoContainer.value);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const initVideoContainer = () => {
|
|
73
|
-
observeContainer();
|
|
74
|
-
bindVideoEvents()
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
const bindVideoEvents = async () => {
|
|
78
|
-
const video = remoteVideoElement.value;
|
|
79
|
-
if (!video) return;
|
|
80
|
-
checkResult.value = await checkDecoderSupport(VideoCodecType.H264)
|
|
81
|
-
console.log("checkResult.value====>", checkResult.value)
|
|
82
|
-
const result = await detectRenderingCapabilities()
|
|
83
|
-
console.log("detectRenderingCapabilities===>", result)
|
|
84
|
-
renderType.value = result.best
|
|
85
|
-
initWorker(video)
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const initWorker = (video: HTMLCanvasElement) => {
|
|
89
|
-
if (workerInited.value) return;
|
|
90
|
-
console.log("initWorker===>");
|
|
91
|
-
worker.value = new DecodeWorker();
|
|
92
|
-
const pixelRatio = window.devicePixelRatio || 1;
|
|
93
|
-
if (!offscreen.value) {
|
|
94
|
-
offscreen.value = video.transferControlToOffscreen();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
worker.value.onmessage = (event: MessageEvent) => {
|
|
98
|
-
const { data } = event;
|
|
99
|
-
switch (data.type) {
|
|
100
|
-
case 'decoderError':
|
|
101
|
-
case 'rendererError':
|
|
102
|
-
emit('loadedFailure', data.error)
|
|
103
|
-
break
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
worker.value.onerror = (event: ErrorEvent) => {
|
|
107
|
-
console.error('error', event);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
worker.value?.postMessage({
|
|
111
|
-
type: 'init',
|
|
112
|
-
supportH265: checkResult.value?.supported,
|
|
113
|
-
isHardware: checkResult.value?.hardware,
|
|
114
|
-
isSoftware: checkResult.value?.software,
|
|
115
|
-
canvas: offscreen.value,
|
|
116
|
-
pixelRatio: pixelRatio,
|
|
117
|
-
renderType: renderType.value
|
|
118
|
-
}, [offscreen.value])
|
|
119
|
-
workerInited.value = true;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const startDecode = (arrayBuffer: ArrayBuffer) => {
|
|
123
|
-
handleMessage(arrayBuffer)
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const handleMessage = (arrayBuffer: ArrayBuffer) => {
|
|
127
|
-
const data = new Uint8Array(arrayBuffer); // ArrayBuffer -> Uint8Array
|
|
128
|
-
if (data.length < 4) return;
|
|
129
|
-
|
|
130
|
-
// 读取 label 长度(前 4 个字节,Big Endian)
|
|
131
|
-
const labelLen = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
|
|
132
|
-
if (data.length < 4 + labelLen) return;
|
|
133
|
-
|
|
134
|
-
// 读取 label
|
|
135
|
-
const labelBytes = data.subarray(4, 4 + labelLen);
|
|
136
|
-
const label = new TextDecoder().decode(labelBytes);
|
|
137
|
-
|
|
138
|
-
// 读取 frame
|
|
139
|
-
const frame = data.subarray(4 + labelLen); // Uint8Array 视图,底层 buffer 没拷贝
|
|
140
|
-
|
|
141
|
-
// 调用回调
|
|
142
|
-
decodeVideo(label, frame)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const decodeVideo = (label: String, data: Uint8Array) => {
|
|
146
|
-
if(label !== 'key' && !visible){
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
if (label === 'config'){
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
if (waitingKeyFrame.value){
|
|
153
|
-
if(label === 'delta'){
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
waitingKeyFrame.value = false;
|
|
157
|
-
emit("loadedSuccess")
|
|
158
|
-
}
|
|
159
|
-
worker.value?.postMessage(
|
|
160
|
-
{
|
|
161
|
-
type: 'decode',
|
|
162
|
-
label,
|
|
163
|
-
data
|
|
164
|
-
},
|
|
165
|
-
[data.buffer]
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const stopPlay = () => {
|
|
170
|
-
screenStatus.value = false;
|
|
171
|
-
waitingKeyFrame.value = true;
|
|
172
|
-
const audio = audioElement.value;
|
|
173
|
-
worker.value?.postMessage({type: 'clearRender'});
|
|
174
|
-
if (audio && audio.srcObject) {
|
|
175
|
-
const stream = audio.srcObject as MediaStream;
|
|
176
|
-
|
|
177
|
-
stream.getTracks().forEach(t => t.stop());
|
|
178
|
-
|
|
179
|
-
audio.pause();
|
|
180
|
-
audio.srcObject = null;
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
const startPlay = (track: MediaStreamTrack) => {
|
|
185
|
-
const audio = audioElement.value;
|
|
186
|
-
if (!audio) return;
|
|
187
|
-
|
|
188
|
-
replaceAudioTrack(audio, track);
|
|
189
|
-
audio.autoplay = true;
|
|
190
|
-
audio.muted = false;
|
|
191
|
-
audio.setAttribute('playsinline', 'true');
|
|
192
|
-
audio.setAttribute('webkit-playsinline', 'true');
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
const replaceAudioTrack = (audioEl: HTMLAudioElement, newTrack: MediaStreamTrack) => {
|
|
196
|
-
if (!audioEl.srcObject) {
|
|
197
|
-
audioEl.srcObject = new MediaStream();
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const stream = audioEl.srcObject as MediaStream;
|
|
201
|
-
updateTrack(stream, newTrack);
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
const updateTrack = (stream: MediaStream, newTrack: MediaStreamTrack) => {
|
|
205
|
-
if (newTrack.kind === 'audio') {
|
|
206
|
-
// 移除旧音频轨
|
|
207
|
-
stream.getAudioTracks().forEach(oldTrack => {
|
|
208
|
-
stream.removeTrack(oldTrack);
|
|
209
|
-
oldTrack.stop();
|
|
210
|
-
});
|
|
211
|
-
stream.addTrack(newTrack);
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
const handleVisibilityChange = () => {
|
|
216
|
-
visible.value = document.visibilityState === "visible";
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
onMounted(() => {
|
|
220
|
-
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
onBeforeUnmount(async () => {
|
|
224
|
-
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
225
|
-
if (resizeObserver.value && videoContainer.value) {
|
|
226
|
-
resizeObserver.value.unobserve(videoContainer.value);
|
|
227
|
-
}
|
|
228
|
-
stopPlay();
|
|
229
|
-
worker.value?.postMessage({type: 'stopDecode'});
|
|
230
|
-
if(worker.value) {
|
|
231
|
-
worker.value.terminate()
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
return {
|
|
237
|
-
videoSize,
|
|
238
|
-
remoteVideo,
|
|
239
|
-
dimensions,
|
|
240
|
-
widthRadio,
|
|
241
|
-
heightRadio,
|
|
242
|
-
screenStatus,
|
|
243
|
-
initVideoContainer,
|
|
244
|
-
startDecode,
|
|
245
|
-
stopPlay,
|
|
246
|
-
startPlay
|
|
247
|
-
};
|
|
248
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { Ref } from 'vue'
|
|
2
|
-
import { onMounted, onUnmounted } from 'vue'
|
|
3
|
-
import type {Dimension} from "../components/RemotePlayer/type";
|
|
4
|
-
|
|
5
|
-
export default function useResizeObserver(target: Ref<HTMLElement | null>, dimension: Ref<Dimension>) {
|
|
6
|
-
let observer: ResizeObserver | null = null
|
|
7
|
-
|
|
8
|
-
const init = () => {
|
|
9
|
-
if (!target.value) return
|
|
10
|
-
|
|
11
|
-
observer = new ResizeObserver(entries => {
|
|
12
|
-
for (const entry of entries) {
|
|
13
|
-
const { width, height } = entry.contentRect
|
|
14
|
-
dimension.value = { width, height }
|
|
15
|
-
}
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
observer.observe(target.value)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const destroy = () => {
|
|
22
|
-
observer?.disconnect()
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
onMounted(init)
|
|
26
|
-
onUnmounted(destroy)
|
|
27
|
-
}
|