@havue/use-ws-video 1.0.0
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 +0 -0
- package/dist/types/src/index.d.ts +72 -0
- package/dist/use-ws-video.mjs +206 -0
- package/dist/use-ws-video.umd.js +207 -0
- package/package.json +49 -0
package/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { Ref, MaybeRef } from 'vue';
|
|
2
|
+
import type { RenderConstructorOptionType, VideoInfo, WsVideoManager } from '@havue/ws-video-manager';
|
|
3
|
+
export type UseWsVideoCanvasResizeOption = {
|
|
4
|
+
/** 是否启用自动更新canvas width 和 height属性,默认为true */
|
|
5
|
+
enable?: boolean;
|
|
6
|
+
/** 设置canvas width 和 height时,
|
|
7
|
+
* 缩放的比例,即元素实际尺寸乘以scale,
|
|
8
|
+
* 放大是为了画面更清晰
|
|
9
|
+
* 默认 1
|
|
10
|
+
*/
|
|
11
|
+
scale?: number;
|
|
12
|
+
/** 限制canvas width最大值,默认1920 */
|
|
13
|
+
maxWidth?: number;
|
|
14
|
+
/** 限制canvas height最大值,默认1080 */
|
|
15
|
+
maxHeight?: number;
|
|
16
|
+
};
|
|
17
|
+
export type UseWsVideoParamsOptions = {
|
|
18
|
+
/** websocket 地址 */
|
|
19
|
+
wsUrl: MaybeRef<string | undefined>;
|
|
20
|
+
/** 是否播放视频 */
|
|
21
|
+
isReady: MaybeRef<boolean>;
|
|
22
|
+
/** 使用的WsVideoManager 实例 默认为wsVideoPlayer */
|
|
23
|
+
wsVideoPlayerIns?: WsVideoManager;
|
|
24
|
+
/** 视频渲染到的canvas元素, 不传会返回一个元素引用变量:canvasRef */
|
|
25
|
+
target?: MaybeRef<HTMLCanvasElement | undefined>;
|
|
26
|
+
/** 是否自动更新canvas width和height属性的配置, 默认为 USE_WS_VIDEO_DEFAULT_RESIZE_OPTIONS */
|
|
27
|
+
canvasResize?: MaybeRef<UseWsVideoCanvasResizeOption | undefined>;
|
|
28
|
+
/** 视口中元素不可见时断开连接, 默认为true */
|
|
29
|
+
closeOnHidden?: MaybeRef<boolean>;
|
|
30
|
+
/** 自定义Render配置 */
|
|
31
|
+
renderOptions?: MaybeRef<Partial<RenderConstructorOptionType>>;
|
|
32
|
+
};
|
|
33
|
+
export declare const USE_WS_VIDEO_DEFAULT_RESIZE_OPTIONS: Readonly<{
|
|
34
|
+
enable: true;
|
|
35
|
+
scale: 1;
|
|
36
|
+
maxWidth: 1920;
|
|
37
|
+
maxHeight: 1080;
|
|
38
|
+
}>;
|
|
39
|
+
export type UseWsVideoReturnType = {
|
|
40
|
+
/** canvas引用 */
|
|
41
|
+
canvasRef: Ref<HTMLCanvasElement | undefined>;
|
|
42
|
+
/** 是否静音 */
|
|
43
|
+
isMuted: Ref<boolean>;
|
|
44
|
+
/** 是否暂停 */
|
|
45
|
+
isPaused: Ref<boolean>;
|
|
46
|
+
/** 视频信息 */
|
|
47
|
+
videoInfo: Ref<VideoInfo>;
|
|
48
|
+
/** 已经连接的WebSocket地址列表 */
|
|
49
|
+
linkedWsUrlList: Ref<string[]>;
|
|
50
|
+
/** 视频流地址是否已添加 */
|
|
51
|
+
isLinked: Ref<boolean>;
|
|
52
|
+
/** 是否达到websocket拉流数最大值 */
|
|
53
|
+
isReachConnectLimit: Ref<boolean>;
|
|
54
|
+
/** 暂停其他WebSocket视频流的音频播放 */
|
|
55
|
+
pauseOtherAudio: () => void;
|
|
56
|
+
/** 设置当前WebSocket视频流的音频是否暂停 */
|
|
57
|
+
setAudioMutedState: (muted: boolean) => void;
|
|
58
|
+
/** 暂停其他WebSocket视频流的视频播放 */
|
|
59
|
+
pauseOtherVideo: () => void;
|
|
60
|
+
/** 设置当前WebSocket视频流的视频是否暂停 */
|
|
61
|
+
setOneVideoPausedState: (paused: boolean) => void;
|
|
62
|
+
/** 设置所有WebSocket视频流的视频是否暂停 */
|
|
63
|
+
setAllVideoPausedState: (paused: boolean) => void;
|
|
64
|
+
/** 刷新当前WebSocket视频流的时间,如果连接断开会进行重连 */
|
|
65
|
+
refresh: () => void;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* websocket视频流播放
|
|
69
|
+
* @param {UseWsVideoParamsOptions} options 配置项
|
|
70
|
+
* @returns
|
|
71
|
+
*/
|
|
72
|
+
export declare function useWsVideo(options: UseWsVideoParamsOptions): UseWsVideoReturnType;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { ref, computed, toValue, isRef, watch, onBeforeUnmount } from "vue";
|
|
2
|
+
import { useElementVisibility, useResizeObserver } from "@vueuse/core";
|
|
3
|
+
import wsVideoPlayer, { WsVideoManagerEventEnums, AudioState, VideoState } from "@havue/ws-video-manager";
|
|
4
|
+
const USE_WS_VIDEO_DEFAULT_RESIZE_OPTIONS = Object.freeze({
|
|
5
|
+
enable: true,
|
|
6
|
+
scale: 1,
|
|
7
|
+
maxWidth: 1920,
|
|
8
|
+
maxHeight: 1080
|
|
9
|
+
});
|
|
10
|
+
function useWsVideo(options) {
|
|
11
|
+
let canvasRef = ref();
|
|
12
|
+
const {
|
|
13
|
+
wsUrl,
|
|
14
|
+
isReady,
|
|
15
|
+
target,
|
|
16
|
+
wsVideoPlayerIns = wsVideoPlayer,
|
|
17
|
+
canvasResize,
|
|
18
|
+
closeOnHidden,
|
|
19
|
+
renderOptions
|
|
20
|
+
} = options;
|
|
21
|
+
if (target) {
|
|
22
|
+
canvasRef = computed(() => {
|
|
23
|
+
return isRef(target) ? toValue(target) : target;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const _isReady = computed(() => {
|
|
27
|
+
return isRef(isReady) ? toValue(isReady) : isReady;
|
|
28
|
+
});
|
|
29
|
+
const previewWsUrl = computed(() => {
|
|
30
|
+
const url = wsUrl;
|
|
31
|
+
const _wsUrl = (isRef(url) ? toValue(url) : url) || "";
|
|
32
|
+
return _wsUrl;
|
|
33
|
+
});
|
|
34
|
+
const _canvasResizeOpt = computed(() => {
|
|
35
|
+
const canvasResizeOpt = isRef(canvasResize) ? toValue(canvasResize) : canvasResize || {};
|
|
36
|
+
const opt = Object.assign({}, USE_WS_VIDEO_DEFAULT_RESIZE_OPTIONS, canvasResizeOpt || {});
|
|
37
|
+
return opt;
|
|
38
|
+
});
|
|
39
|
+
const _closeOnHidden = computed(() => {
|
|
40
|
+
const closeOpt = isRef(closeOnHidden) ? toValue(closeOnHidden) : closeOnHidden;
|
|
41
|
+
return closeOpt === void 0 ? true : closeOpt;
|
|
42
|
+
});
|
|
43
|
+
const _renderOptions = computed(() => {
|
|
44
|
+
const renderOpt = isRef(renderOptions) ? toValue(renderOptions) : renderOptions || void 0;
|
|
45
|
+
return renderOpt;
|
|
46
|
+
});
|
|
47
|
+
const isMuted = ref(true);
|
|
48
|
+
const isPaused = ref(false);
|
|
49
|
+
const videoInfo = ref({
|
|
50
|
+
width: 0,
|
|
51
|
+
height: 0
|
|
52
|
+
});
|
|
53
|
+
const lastPreviewUrl = ref();
|
|
54
|
+
const linkedWsUrlList = ref([...wsVideoPlayer.linkedUrlList]);
|
|
55
|
+
const isLinked = computed(() => {
|
|
56
|
+
return linkedWsUrlList.value.includes(previewWsUrl.value);
|
|
57
|
+
});
|
|
58
|
+
const connectLimit = wsVideoPlayer.connectLimit;
|
|
59
|
+
const isReachConnectLimit = computed(() => {
|
|
60
|
+
return linkedWsUrlList.value.length >= connectLimit;
|
|
61
|
+
});
|
|
62
|
+
function handleWsUrlChange(urls) {
|
|
63
|
+
linkedWsUrlList.value = [...urls];
|
|
64
|
+
}
|
|
65
|
+
function handleAudioStateChange(url, state) {
|
|
66
|
+
if (url === previewWsUrl.value) {
|
|
67
|
+
console.log("音频状态更改", url, state);
|
|
68
|
+
isMuted.value = state === AudioState.MUTED;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function handleVideoStateChange(url, state) {
|
|
72
|
+
if (url === previewWsUrl.value) {
|
|
73
|
+
console.log("视频状态更改", url, state);
|
|
74
|
+
isPaused.value = state === VideoState.PAUSE;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function handleVideoInfoUpdate(url, info) {
|
|
78
|
+
if (url === previewWsUrl.value) {
|
|
79
|
+
videoInfo.value = {
|
|
80
|
+
...info
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
wsVideoPlayer.on(WsVideoManagerEventEnums.WS_URL_CHANGE, handleWsUrlChange);
|
|
85
|
+
wsVideoPlayer.on(WsVideoManagerEventEnums.AUDIO_STATE_CHANGE, handleAudioStateChange);
|
|
86
|
+
wsVideoPlayer.on(WsVideoManagerEventEnums.VIDEO_STATE_CHANGE, handleVideoStateChange);
|
|
87
|
+
wsVideoPlayer.on(WsVideoManagerEventEnums.VIDEO_INFO_UPDATE, handleVideoInfoUpdate);
|
|
88
|
+
const canvasIsVisible = useElementVisibility(canvasRef);
|
|
89
|
+
let stopResizeObserver = () => {
|
|
90
|
+
};
|
|
91
|
+
watch(
|
|
92
|
+
_canvasResizeOpt,
|
|
93
|
+
(val) => {
|
|
94
|
+
stopResizeObserver && stopResizeObserver();
|
|
95
|
+
if (val.enable) {
|
|
96
|
+
const { stop } = useResizeObserver(canvasRef, (entries) => {
|
|
97
|
+
if (!canvasRef.value) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const [entry] = entries;
|
|
101
|
+
const { width, height } = entry.contentRect;
|
|
102
|
+
const { scale, maxWidth, maxHeight } = _canvasResizeOpt.value;
|
|
103
|
+
let comWidth = width * scale;
|
|
104
|
+
let comHeight = height * scale;
|
|
105
|
+
const canvasRate = width / height;
|
|
106
|
+
if (comWidth > maxWidth || comHeight > maxHeight) {
|
|
107
|
+
const optionRate = maxWidth / maxHeight;
|
|
108
|
+
comWidth = canvasRate > optionRate ? maxWidth : maxHeight * canvasRate;
|
|
109
|
+
comHeight = canvasRate > optionRate ? maxWidth / canvasRate : maxHeight;
|
|
110
|
+
}
|
|
111
|
+
canvasRef.value.width = comWidth;
|
|
112
|
+
canvasRef.value.height = comHeight;
|
|
113
|
+
});
|
|
114
|
+
stopResizeObserver = stop;
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
immediate: true,
|
|
119
|
+
deep: true
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
watch(
|
|
123
|
+
_renderOptions,
|
|
124
|
+
() => {
|
|
125
|
+
if (_renderOptions.value && isLinked.value) {
|
|
126
|
+
wsVideoPlayerIns.updateRenderOptions(previewWsUrl.value, _renderOptions.value);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
deep: true
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
onBeforeUnmount(() => {
|
|
134
|
+
stopResizeObserver();
|
|
135
|
+
wsVideoPlayer.off(WsVideoManagerEventEnums.WS_URL_CHANGE, handleWsUrlChange);
|
|
136
|
+
wsVideoPlayer.off(WsVideoManagerEventEnums.AUDIO_STATE_CHANGE, handleAudioStateChange);
|
|
137
|
+
wsVideoPlayer.off(WsVideoManagerEventEnums.VIDEO_STATE_CHANGE, handleVideoStateChange);
|
|
138
|
+
wsVideoPlayer.off(WsVideoManagerEventEnums.VIDEO_INFO_UPDATE, handleVideoInfoUpdate);
|
|
139
|
+
if (!canvasRef.value) return;
|
|
140
|
+
wsVideoPlayerIns.removeCanvas(canvasRef.value);
|
|
141
|
+
isMuted.value = true;
|
|
142
|
+
});
|
|
143
|
+
const canPreview = computed(() => {
|
|
144
|
+
if (_closeOnHidden.value) {
|
|
145
|
+
return canvasIsVisible.value && _isReady.value && previewWsUrl.value;
|
|
146
|
+
}
|
|
147
|
+
return _isReady.value && previewWsUrl.value;
|
|
148
|
+
});
|
|
149
|
+
watch([canvasRef, canPreview, linkedWsUrlList, previewWsUrl], () => {
|
|
150
|
+
if (!canvasRef.value) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (canPreview.value) {
|
|
154
|
+
if (lastPreviewUrl.value && previewWsUrl.value !== lastPreviewUrl.value && wsVideoPlayerIns.isCanvasExist(canvasRef.value)) {
|
|
155
|
+
wsVideoPlayerIns.removeCanvas(canvasRef.value);
|
|
156
|
+
}
|
|
157
|
+
if (!wsVideoPlayerIns.isCanvasExist(canvasRef.value)) {
|
|
158
|
+
wsVideoPlayerIns.addCanvas(canvasRef.value, previewWsUrl.value, _renderOptions.value);
|
|
159
|
+
lastPreviewUrl.value = previewWsUrl.value;
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
if (wsVideoPlayerIns.isCanvasExist(canvasRef.value)) {
|
|
163
|
+
wsVideoPlayerIns.removeCanvas(canvasRef.value);
|
|
164
|
+
isMuted.value = true;
|
|
165
|
+
isPaused.value = false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
function pauseOtherAudio() {
|
|
170
|
+
wsVideoPlayer.playOneAudio(previewWsUrl.value);
|
|
171
|
+
}
|
|
172
|
+
function setAudioMutedState(muted) {
|
|
173
|
+
wsVideoPlayer.setOneMutedState(previewWsUrl.value, muted);
|
|
174
|
+
}
|
|
175
|
+
function pauseOtherVideo() {
|
|
176
|
+
wsVideoPlayer.playOneVideo(previewWsUrl.value);
|
|
177
|
+
}
|
|
178
|
+
function setOneVideoPausedState(paused) {
|
|
179
|
+
wsVideoPlayer.setOneVideoPausedState(previewWsUrl.value, paused);
|
|
180
|
+
}
|
|
181
|
+
function setAllVideoPausedState(paused) {
|
|
182
|
+
wsVideoPlayer.setAllVideoPausedState(paused);
|
|
183
|
+
}
|
|
184
|
+
const refresh = () => {
|
|
185
|
+
wsVideoPlayer.refresh(previewWsUrl.value);
|
|
186
|
+
};
|
|
187
|
+
return {
|
|
188
|
+
canvasRef,
|
|
189
|
+
isMuted,
|
|
190
|
+
isPaused,
|
|
191
|
+
videoInfo,
|
|
192
|
+
linkedWsUrlList,
|
|
193
|
+
isLinked,
|
|
194
|
+
isReachConnectLimit,
|
|
195
|
+
pauseOtherAudio,
|
|
196
|
+
setAudioMutedState,
|
|
197
|
+
pauseOtherVideo,
|
|
198
|
+
setOneVideoPausedState,
|
|
199
|
+
setAllVideoPausedState,
|
|
200
|
+
refresh
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
export {
|
|
204
|
+
USE_WS_VIDEO_DEFAULT_RESIZE_OPTIONS,
|
|
205
|
+
useWsVideo
|
|
206
|
+
};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
(function(global, factory) {
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("vue"), require("@vueuse/core"), require("@havue/ws-video-manager")) : typeof define === "function" && define.amd ? define(["exports", "vue", "@vueuse/core", "@havue/ws-video-manager"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["use-ws-video"] = {}, global.Vue, global.core, global.wsVideoPlayer));
|
|
3
|
+
})(this, function(exports2, vue, core, wsVideoPlayer) {
|
|
4
|
+
"use strict";
|
|
5
|
+
const USE_WS_VIDEO_DEFAULT_RESIZE_OPTIONS = Object.freeze({
|
|
6
|
+
enable: true,
|
|
7
|
+
scale: 1,
|
|
8
|
+
maxWidth: 1920,
|
|
9
|
+
maxHeight: 1080
|
|
10
|
+
});
|
|
11
|
+
function useWsVideo(options) {
|
|
12
|
+
let canvasRef = vue.ref();
|
|
13
|
+
const {
|
|
14
|
+
wsUrl,
|
|
15
|
+
isReady,
|
|
16
|
+
target,
|
|
17
|
+
wsVideoPlayerIns = wsVideoPlayer,
|
|
18
|
+
canvasResize,
|
|
19
|
+
closeOnHidden,
|
|
20
|
+
renderOptions
|
|
21
|
+
} = options;
|
|
22
|
+
if (target) {
|
|
23
|
+
canvasRef = vue.computed(() => {
|
|
24
|
+
return vue.isRef(target) ? vue.toValue(target) : target;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const _isReady = vue.computed(() => {
|
|
28
|
+
return vue.isRef(isReady) ? vue.toValue(isReady) : isReady;
|
|
29
|
+
});
|
|
30
|
+
const previewWsUrl = vue.computed(() => {
|
|
31
|
+
const url = wsUrl;
|
|
32
|
+
const _wsUrl = (vue.isRef(url) ? vue.toValue(url) : url) || "";
|
|
33
|
+
return _wsUrl;
|
|
34
|
+
});
|
|
35
|
+
const _canvasResizeOpt = vue.computed(() => {
|
|
36
|
+
const canvasResizeOpt = vue.isRef(canvasResize) ? vue.toValue(canvasResize) : canvasResize || {};
|
|
37
|
+
const opt = Object.assign({}, USE_WS_VIDEO_DEFAULT_RESIZE_OPTIONS, canvasResizeOpt || {});
|
|
38
|
+
return opt;
|
|
39
|
+
});
|
|
40
|
+
const _closeOnHidden = vue.computed(() => {
|
|
41
|
+
const closeOpt = vue.isRef(closeOnHidden) ? vue.toValue(closeOnHidden) : closeOnHidden;
|
|
42
|
+
return closeOpt === void 0 ? true : closeOpt;
|
|
43
|
+
});
|
|
44
|
+
const _renderOptions = vue.computed(() => {
|
|
45
|
+
const renderOpt = vue.isRef(renderOptions) ? vue.toValue(renderOptions) : renderOptions || void 0;
|
|
46
|
+
return renderOpt;
|
|
47
|
+
});
|
|
48
|
+
const isMuted = vue.ref(true);
|
|
49
|
+
const isPaused = vue.ref(false);
|
|
50
|
+
const videoInfo = vue.ref({
|
|
51
|
+
width: 0,
|
|
52
|
+
height: 0
|
|
53
|
+
});
|
|
54
|
+
const lastPreviewUrl = vue.ref();
|
|
55
|
+
const linkedWsUrlList = vue.ref([...wsVideoPlayer.linkedUrlList]);
|
|
56
|
+
const isLinked = vue.computed(() => {
|
|
57
|
+
return linkedWsUrlList.value.includes(previewWsUrl.value);
|
|
58
|
+
});
|
|
59
|
+
const connectLimit = wsVideoPlayer.connectLimit;
|
|
60
|
+
const isReachConnectLimit = vue.computed(() => {
|
|
61
|
+
return linkedWsUrlList.value.length >= connectLimit;
|
|
62
|
+
});
|
|
63
|
+
function handleWsUrlChange(urls) {
|
|
64
|
+
linkedWsUrlList.value = [...urls];
|
|
65
|
+
}
|
|
66
|
+
function handleAudioStateChange(url, state) {
|
|
67
|
+
if (url === previewWsUrl.value) {
|
|
68
|
+
console.log("音频状态更改", url, state);
|
|
69
|
+
isMuted.value = state === wsVideoPlayer.AudioState.MUTED;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function handleVideoStateChange(url, state) {
|
|
73
|
+
if (url === previewWsUrl.value) {
|
|
74
|
+
console.log("视频状态更改", url, state);
|
|
75
|
+
isPaused.value = state === wsVideoPlayer.VideoState.PAUSE;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function handleVideoInfoUpdate(url, info) {
|
|
79
|
+
if (url === previewWsUrl.value) {
|
|
80
|
+
videoInfo.value = {
|
|
81
|
+
...info
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
wsVideoPlayer.on(wsVideoPlayer.WsVideoManagerEventEnums.WS_URL_CHANGE, handleWsUrlChange);
|
|
86
|
+
wsVideoPlayer.on(wsVideoPlayer.WsVideoManagerEventEnums.AUDIO_STATE_CHANGE, handleAudioStateChange);
|
|
87
|
+
wsVideoPlayer.on(wsVideoPlayer.WsVideoManagerEventEnums.VIDEO_STATE_CHANGE, handleVideoStateChange);
|
|
88
|
+
wsVideoPlayer.on(wsVideoPlayer.WsVideoManagerEventEnums.VIDEO_INFO_UPDATE, handleVideoInfoUpdate);
|
|
89
|
+
const canvasIsVisible = core.useElementVisibility(canvasRef);
|
|
90
|
+
let stopResizeObserver = () => {
|
|
91
|
+
};
|
|
92
|
+
vue.watch(
|
|
93
|
+
_canvasResizeOpt,
|
|
94
|
+
(val) => {
|
|
95
|
+
stopResizeObserver && stopResizeObserver();
|
|
96
|
+
if (val.enable) {
|
|
97
|
+
const { stop } = core.useResizeObserver(canvasRef, (entries) => {
|
|
98
|
+
if (!canvasRef.value) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const [entry] = entries;
|
|
102
|
+
const { width, height } = entry.contentRect;
|
|
103
|
+
const { scale, maxWidth, maxHeight } = _canvasResizeOpt.value;
|
|
104
|
+
let comWidth = width * scale;
|
|
105
|
+
let comHeight = height * scale;
|
|
106
|
+
const canvasRate = width / height;
|
|
107
|
+
if (comWidth > maxWidth || comHeight > maxHeight) {
|
|
108
|
+
const optionRate = maxWidth / maxHeight;
|
|
109
|
+
comWidth = canvasRate > optionRate ? maxWidth : maxHeight * canvasRate;
|
|
110
|
+
comHeight = canvasRate > optionRate ? maxWidth / canvasRate : maxHeight;
|
|
111
|
+
}
|
|
112
|
+
canvasRef.value.width = comWidth;
|
|
113
|
+
canvasRef.value.height = comHeight;
|
|
114
|
+
});
|
|
115
|
+
stopResizeObserver = stop;
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
immediate: true,
|
|
120
|
+
deep: true
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
vue.watch(
|
|
124
|
+
_renderOptions,
|
|
125
|
+
() => {
|
|
126
|
+
if (_renderOptions.value && isLinked.value) {
|
|
127
|
+
wsVideoPlayerIns.updateRenderOptions(previewWsUrl.value, _renderOptions.value);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
deep: true
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
vue.onBeforeUnmount(() => {
|
|
135
|
+
stopResizeObserver();
|
|
136
|
+
wsVideoPlayer.off(wsVideoPlayer.WsVideoManagerEventEnums.WS_URL_CHANGE, handleWsUrlChange);
|
|
137
|
+
wsVideoPlayer.off(wsVideoPlayer.WsVideoManagerEventEnums.AUDIO_STATE_CHANGE, handleAudioStateChange);
|
|
138
|
+
wsVideoPlayer.off(wsVideoPlayer.WsVideoManagerEventEnums.VIDEO_STATE_CHANGE, handleVideoStateChange);
|
|
139
|
+
wsVideoPlayer.off(wsVideoPlayer.WsVideoManagerEventEnums.VIDEO_INFO_UPDATE, handleVideoInfoUpdate);
|
|
140
|
+
if (!canvasRef.value) return;
|
|
141
|
+
wsVideoPlayerIns.removeCanvas(canvasRef.value);
|
|
142
|
+
isMuted.value = true;
|
|
143
|
+
});
|
|
144
|
+
const canPreview = vue.computed(() => {
|
|
145
|
+
if (_closeOnHidden.value) {
|
|
146
|
+
return canvasIsVisible.value && _isReady.value && previewWsUrl.value;
|
|
147
|
+
}
|
|
148
|
+
return _isReady.value && previewWsUrl.value;
|
|
149
|
+
});
|
|
150
|
+
vue.watch([canvasRef, canPreview, linkedWsUrlList, previewWsUrl], () => {
|
|
151
|
+
if (!canvasRef.value) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (canPreview.value) {
|
|
155
|
+
if (lastPreviewUrl.value && previewWsUrl.value !== lastPreviewUrl.value && wsVideoPlayerIns.isCanvasExist(canvasRef.value)) {
|
|
156
|
+
wsVideoPlayerIns.removeCanvas(canvasRef.value);
|
|
157
|
+
}
|
|
158
|
+
if (!wsVideoPlayerIns.isCanvasExist(canvasRef.value)) {
|
|
159
|
+
wsVideoPlayerIns.addCanvas(canvasRef.value, previewWsUrl.value, _renderOptions.value);
|
|
160
|
+
lastPreviewUrl.value = previewWsUrl.value;
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
if (wsVideoPlayerIns.isCanvasExist(canvasRef.value)) {
|
|
164
|
+
wsVideoPlayerIns.removeCanvas(canvasRef.value);
|
|
165
|
+
isMuted.value = true;
|
|
166
|
+
isPaused.value = false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
function pauseOtherAudio() {
|
|
171
|
+
wsVideoPlayer.playOneAudio(previewWsUrl.value);
|
|
172
|
+
}
|
|
173
|
+
function setAudioMutedState(muted) {
|
|
174
|
+
wsVideoPlayer.setOneMutedState(previewWsUrl.value, muted);
|
|
175
|
+
}
|
|
176
|
+
function pauseOtherVideo() {
|
|
177
|
+
wsVideoPlayer.playOneVideo(previewWsUrl.value);
|
|
178
|
+
}
|
|
179
|
+
function setOneVideoPausedState(paused) {
|
|
180
|
+
wsVideoPlayer.setOneVideoPausedState(previewWsUrl.value, paused);
|
|
181
|
+
}
|
|
182
|
+
function setAllVideoPausedState(paused) {
|
|
183
|
+
wsVideoPlayer.setAllVideoPausedState(paused);
|
|
184
|
+
}
|
|
185
|
+
const refresh = () => {
|
|
186
|
+
wsVideoPlayer.refresh(previewWsUrl.value);
|
|
187
|
+
};
|
|
188
|
+
return {
|
|
189
|
+
canvasRef,
|
|
190
|
+
isMuted,
|
|
191
|
+
isPaused,
|
|
192
|
+
videoInfo,
|
|
193
|
+
linkedWsUrlList,
|
|
194
|
+
isLinked,
|
|
195
|
+
isReachConnectLimit,
|
|
196
|
+
pauseOtherAudio,
|
|
197
|
+
setAudioMutedState,
|
|
198
|
+
pauseOtherVideo,
|
|
199
|
+
setOneVideoPausedState,
|
|
200
|
+
setAllVideoPausedState,
|
|
201
|
+
refresh
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
exports2.USE_WS_VIDEO_DEFAULT_RESIZE_OPTIONS = USE_WS_VIDEO_DEFAULT_RESIZE_OPTIONS;
|
|
205
|
+
exports2.useWsVideo = useWsVideo;
|
|
206
|
+
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
207
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@havue/use-ws-video",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Ws video manager hook for Vue3",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"havue",
|
|
7
|
+
"hook",
|
|
8
|
+
"ws",
|
|
9
|
+
"video",
|
|
10
|
+
"fmp4",
|
|
11
|
+
"vue3"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"homepage": "https://happypedestrian.github.io/havue/guide/",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/HappyPedestrian/havue.git"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@vueuse/core": "^11.0.3",
|
|
21
|
+
"@havue/ws-video-manager": "^1.0.0"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"vue": "^3.3.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"vue": "^3.3.0"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public",
|
|
31
|
+
"registry": "https://registry.npmjs.org/"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"main": "./dist/use-ws-video.umd.js",
|
|
37
|
+
"module": "./dist/use-ws-video.mjs",
|
|
38
|
+
"types": "./dist/types/src/index.d.ts",
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"require": "./dist/use-ws-video.umd.js",
|
|
42
|
+
"import": "./dist/use-ws-video.mjs",
|
|
43
|
+
"types": "./dist/types/src/index.d.ts"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "vite build --mode package"
|
|
48
|
+
}
|
|
49
|
+
}
|