call-live-sdk1 0.0.20 → 0.0.21
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/dist/call-live-sdk.es.js
CHANGED
|
@@ -189243,7 +189243,7 @@ const useCallStore = create$c()(
|
|
|
189243
189243
|
nickname,
|
|
189244
189244
|
token: token2,
|
|
189245
189245
|
device: isMobile$3 ? "mobile" : "pc",
|
|
189246
|
-
videoList: [rtc_userid, rtc_userid + "screen", rtc_userid + "main"],
|
|
189246
|
+
videoList: [rtc_userid, rtc_userid + "screen", rtc_userid + "main", rtc_userid + "self"],
|
|
189247
189247
|
...initCallUser,
|
|
189248
189248
|
// 根据enter_muted配置设置初始音频状态
|
|
189249
189249
|
// enter_muted: 0-否(音频开启) 1-是(音频关闭/静音)
|
|
@@ -189921,17 +189921,6 @@ const useCallStore = create$c()(
|
|
|
189921
189921
|
isAudioEnabled,
|
|
189922
189922
|
isAudioDisabled: isBanned ?? false
|
|
189923
189923
|
});
|
|
189924
|
-
if (rtc && rtc.engine) {
|
|
189925
|
-
await rtc.engine.sendRoomMessage(
|
|
189926
|
-
JSON.stringify({
|
|
189927
|
-
type: "media",
|
|
189928
|
-
data: {
|
|
189929
|
-
media_type: "audio",
|
|
189930
|
-
media_state: isAudioEnabled ? 1 : 0
|
|
189931
|
-
}
|
|
189932
|
-
})
|
|
189933
|
-
);
|
|
189934
|
-
}
|
|
189935
189924
|
return {
|
|
189936
189925
|
success: true,
|
|
189937
189926
|
message: isAudioEnabled ? "麦克风已开启" : "麦克风已关闭",
|
|
@@ -189958,17 +189947,6 @@ const useCallStore = create$c()(
|
|
|
189958
189947
|
isVideoEnabled: newVideoState,
|
|
189959
189948
|
isVideoDisabled: isBanned ?? false
|
|
189960
189949
|
});
|
|
189961
|
-
if (rtc && rtc.engine) {
|
|
189962
|
-
await rtc.engine.sendRoomMessage(
|
|
189963
|
-
JSON.stringify({
|
|
189964
|
-
type: "media",
|
|
189965
|
-
data: {
|
|
189966
|
-
media_type: "video",
|
|
189967
|
-
media_state: newVideoState ? 1 : 0
|
|
189968
|
-
}
|
|
189969
|
-
})
|
|
189970
|
-
);
|
|
189971
|
-
}
|
|
189972
189950
|
return {
|
|
189973
189951
|
success: true,
|
|
189974
189952
|
message: newVideoState ? "摄像头已开启" : "摄像头已关闭",
|
|
@@ -190182,7 +190160,7 @@ const useCallStore = create$c()(
|
|
|
190182
190160
|
context.arc(avatarX + avatarRadius, avatarY + avatarRadius, avatarRadius, 0, 2 * Math.PI);
|
|
190183
190161
|
context.fill();
|
|
190184
190162
|
if (user && user.nickname) {
|
|
190185
|
-
const firstLetter = user.nickname.
|
|
190163
|
+
const firstLetter = user.nickname.trim().charAt(0);
|
|
190186
190164
|
context.fillStyle = "#ffffff";
|
|
190187
190165
|
context.font = `${avatarSize * 0.5}px Arial`;
|
|
190188
190166
|
context.textAlign = "center";
|
|
@@ -202729,6 +202707,185 @@ const DropdownButton = (props) => {
|
|
|
202729
202707
|
DropdownButton.__ANT_BUTTON = true;
|
|
202730
202708
|
const Dropdown = Dropdown$1;
|
|
202731
202709
|
Dropdown.Button = DropdownButton;
|
|
202710
|
+
const useVideoSlotBinding = ({
|
|
202711
|
+
item,
|
|
202712
|
+
livePlayerRef,
|
|
202713
|
+
fenge
|
|
202714
|
+
}) => {
|
|
202715
|
+
const { callUsers, getter } = useCallStore();
|
|
202716
|
+
const [selectedValue, setSelectedValue] = reactExports.useState(
|
|
202717
|
+
item.objectType === "videoSlot" && item.userId && item.streamIndex ? `${item.userId}${fenge}${item.streamIndex}` : ""
|
|
202718
|
+
);
|
|
202719
|
+
reactExports.useEffect(() => {
|
|
202720
|
+
if (item.objectType === "videoSlot" && item.userId && item.streamIndex) {
|
|
202721
|
+
setSelectedValue(`${item.userId}${fenge}${item.streamIndex}`);
|
|
202722
|
+
}
|
|
202723
|
+
}, [item.userId, item.streamIndex, item.objectType, fenge]);
|
|
202724
|
+
const targetUser = reactExports.useMemo(() => {
|
|
202725
|
+
if (!selectedValue)
|
|
202726
|
+
return void 0;
|
|
202727
|
+
const userId = selectedValue.split(fenge)[0];
|
|
202728
|
+
return callUsers.find((user) => user.rtc_userid === userId);
|
|
202729
|
+
}, [selectedValue, fenge, callUsers]);
|
|
202730
|
+
const handleStreamChange = (value, option) => {
|
|
202731
|
+
var _a2, _b;
|
|
202732
|
+
console.log("选择的视频槽:", value, option);
|
|
202733
|
+
setSelectedValue(value);
|
|
202734
|
+
if (!value) {
|
|
202735
|
+
try {
|
|
202736
|
+
if (!livePlayerRef.current) {
|
|
202737
|
+
console.error("livePlayerRef未初始化");
|
|
202738
|
+
return;
|
|
202739
|
+
}
|
|
202740
|
+
livePlayerRef.current.addEmptyVideoSlot({ id: item.id });
|
|
202741
|
+
console.log("成功清除连麦嘉宾绑定状态");
|
|
202742
|
+
} catch (error2) {
|
|
202743
|
+
console.error("清除连麦嘉宾绑定状态失败:", error2);
|
|
202744
|
+
}
|
|
202745
|
+
return;
|
|
202746
|
+
}
|
|
202747
|
+
try {
|
|
202748
|
+
const [userId, streamIndex] = String(value).split(fenge);
|
|
202749
|
+
const canvas = getter().fabricInstance;
|
|
202750
|
+
if (!canvas) {
|
|
202751
|
+
console.error("画布未初始化");
|
|
202752
|
+
return;
|
|
202753
|
+
}
|
|
202754
|
+
const videoSlotObj = ((_a2 = canvas.getObjects()) == null ? void 0 : _a2.find((o2) => o2.id === item.id)) || item;
|
|
202755
|
+
canvas.setActiveObject(videoSlotObj);
|
|
202756
|
+
const user = callUsers.find((user2) => user2.rtc_userid === userId);
|
|
202757
|
+
if (!user) {
|
|
202758
|
+
console.error("找不到用户:", userId);
|
|
202759
|
+
return;
|
|
202760
|
+
}
|
|
202761
|
+
if (user.isVideoEnabled) {
|
|
202762
|
+
livePlayerRef.current.bindVideoSlotToFirstEmpty({
|
|
202763
|
+
id: item.id,
|
|
202764
|
+
userId,
|
|
202765
|
+
device: user.device,
|
|
202766
|
+
streamIndex: streamIndex === "screen" ? "screen" : "main",
|
|
202767
|
+
userName: targetUser == null ? void 0 : targetUser.nickname
|
|
202768
|
+
});
|
|
202769
|
+
if (videoSlotObj) {
|
|
202770
|
+
videoSlotObj.userId = userId;
|
|
202771
|
+
videoSlotObj.streamIndex = streamIndex;
|
|
202772
|
+
}
|
|
202773
|
+
} else {
|
|
202774
|
+
const targetObj = (_b = canvas.getObjects()) == null ? void 0 : _b.find((o2) => o2.id === item.id);
|
|
202775
|
+
if (targetObj) {
|
|
202776
|
+
livePlayerRef.current.createCameraClosedPlaceholder(
|
|
202777
|
+
{ ...targetObj, streamIndex },
|
|
202778
|
+
user
|
|
202779
|
+
);
|
|
202780
|
+
}
|
|
202781
|
+
}
|
|
202782
|
+
} catch (error2) {
|
|
202783
|
+
console.error("绑定连麦嘉宾失败:", error2);
|
|
202784
|
+
}
|
|
202785
|
+
};
|
|
202786
|
+
reactExports.useEffect(() => {
|
|
202787
|
+
var _a2;
|
|
202788
|
+
if (item.objectType !== "videoSlot" || !livePlayerRef.current)
|
|
202789
|
+
return;
|
|
202790
|
+
try {
|
|
202791
|
+
const canvas = getter().fabricInstance;
|
|
202792
|
+
if (!canvas) {
|
|
202793
|
+
console.error("画布未初始化");
|
|
202794
|
+
return;
|
|
202795
|
+
}
|
|
202796
|
+
const videoSlotObj = (_a2 = canvas.getObjects()) == null ? void 0 : _a2.find((o2) => o2.id === item.id);
|
|
202797
|
+
if (!videoSlotObj) {
|
|
202798
|
+
console.error("找不到对应的连麦嘉宾对象:", item.id);
|
|
202799
|
+
return;
|
|
202800
|
+
}
|
|
202801
|
+
const [, streamIndex = "main"] = selectedValue.split(fenge);
|
|
202802
|
+
if (!targetUser || streamIndex === "screen" && !targetUser.isScreenEnabled) {
|
|
202803
|
+
console.log(`用户${item.userId}已退出,恢复为空连麦嘉宾`);
|
|
202804
|
+
setSelectedValue("");
|
|
202805
|
+
try {
|
|
202806
|
+
livePlayerRef.current.addEmptyVideoSlot({ id: item.id });
|
|
202807
|
+
} catch (error2) {
|
|
202808
|
+
console.error("恢复空连麦嘉宾失败:", error2);
|
|
202809
|
+
}
|
|
202810
|
+
return;
|
|
202811
|
+
}
|
|
202812
|
+
console.log(
|
|
202813
|
+
`${targetUser.nickname || targetUser.rtc_userid}摄像头状态变更为: ${targetUser.isVideoEnabled ? "开启" : "关闭"}`
|
|
202814
|
+
);
|
|
202815
|
+
if (targetUser.isVideoEnabled) {
|
|
202816
|
+
try {
|
|
202817
|
+
livePlayerRef.current.bindVideoSlotToFirstEmpty({
|
|
202818
|
+
id: item.id,
|
|
202819
|
+
userId: targetUser.rtc_userid,
|
|
202820
|
+
streamIndex: streamIndex === "screen" ? "screen" : "main",
|
|
202821
|
+
userName: targetUser.nickname
|
|
202822
|
+
});
|
|
202823
|
+
videoSlotObj.userId = targetUser.rtc_userid;
|
|
202824
|
+
videoSlotObj.streamIndex = streamIndex;
|
|
202825
|
+
} catch (bindError) {
|
|
202826
|
+
console.error("绑定视频流失败:", bindError);
|
|
202827
|
+
}
|
|
202828
|
+
} else {
|
|
202829
|
+
try {
|
|
202830
|
+
livePlayerRef.current.createCameraClosedPlaceholder(
|
|
202831
|
+
{ ...videoSlotObj, streamIndex },
|
|
202832
|
+
targetUser
|
|
202833
|
+
);
|
|
202834
|
+
videoSlotObj._cameraClosedPlaceholder = true;
|
|
202835
|
+
} catch (placeholderError) {
|
|
202836
|
+
console.error("创建摄像头关闭占位符失败:", placeholderError);
|
|
202837
|
+
}
|
|
202838
|
+
}
|
|
202839
|
+
} catch (error2) {
|
|
202840
|
+
console.error("监听嘉宾视频状态变化时发生错误:", error2);
|
|
202841
|
+
}
|
|
202842
|
+
}, [targetUser, targetUser == null ? void 0 : targetUser.isVideoEnabled, targetUser == null ? void 0 : targetUser.isPublishStream, item.userId, item.id, selectedValue, fenge, livePlayerRef, getter]);
|
|
202843
|
+
return {
|
|
202844
|
+
selectedValue,
|
|
202845
|
+
setSelectedValue,
|
|
202846
|
+
targetUser,
|
|
202847
|
+
handleStreamChange
|
|
202848
|
+
};
|
|
202849
|
+
};
|
|
202850
|
+
const useVideoSlotStreams = () => {
|
|
202851
|
+
const { callUsers, callConfig } = useCallStore();
|
|
202852
|
+
const fenge = '-":}{_+';
|
|
202853
|
+
const availableStreams = reactExports.useMemo(
|
|
202854
|
+
() => callUsers.flatMap((user) => {
|
|
202855
|
+
const list = [];
|
|
202856
|
+
if (user.waiting_mode_state === WaitingModeState.WAITING) {
|
|
202857
|
+
return list;
|
|
202858
|
+
}
|
|
202859
|
+
if (user.rtc_userid === (callConfig == null ? void 0 : callConfig.drawing_board_id)) {
|
|
202860
|
+
return list;
|
|
202861
|
+
}
|
|
202862
|
+
list.push({
|
|
202863
|
+
label: `${user.nickname || user.rtc_userid} · 摄像头`,
|
|
202864
|
+
value: `${user.rtc_userid}${fenge}main`,
|
|
202865
|
+
isVideoEnabled: user.isVideoEnabled,
|
|
202866
|
+
rtc_userid: user.rtc_userid,
|
|
202867
|
+
nickname: user.nickname,
|
|
202868
|
+
isScreenEnabled: user.isScreenEnabled
|
|
202869
|
+
});
|
|
202870
|
+
if (user == null ? void 0 : user.isScreenEnabled) {
|
|
202871
|
+
list.push({
|
|
202872
|
+
label: `${user.nickname || user.rtc_userid} · 屏幕共享`,
|
|
202873
|
+
value: `${user.rtc_userid}${fenge}screen`,
|
|
202874
|
+
isVideoEnabled: user.isScreenEnabled,
|
|
202875
|
+
rtc_userid: user.rtc_userid,
|
|
202876
|
+
nickname: user.nickname,
|
|
202877
|
+
isScreenEnabled: user.isScreenEnabled
|
|
202878
|
+
});
|
|
202879
|
+
}
|
|
202880
|
+
return list;
|
|
202881
|
+
}),
|
|
202882
|
+
[callUsers, callConfig == null ? void 0 : callConfig.drawing_board_id]
|
|
202883
|
+
);
|
|
202884
|
+
return {
|
|
202885
|
+
availableStreams,
|
|
202886
|
+
fenge
|
|
202887
|
+
};
|
|
202888
|
+
};
|
|
202732
202889
|
const {
|
|
202733
202890
|
useToken: useToken$2
|
|
202734
202891
|
} = theme;
|
|
@@ -202753,31 +202910,32 @@ const MetaItem = ({
|
|
|
202753
202910
|
setFabricObjects,
|
|
202754
202911
|
setDocumentInfo,
|
|
202755
202912
|
scenes,
|
|
202756
|
-
currentScene
|
|
202757
|
-
|
|
202758
|
-
|
|
202759
|
-
callUsers,
|
|
202760
|
-
getter,
|
|
202761
|
-
callConfig
|
|
202913
|
+
currentScene,
|
|
202914
|
+
callConfig,
|
|
202915
|
+
getter
|
|
202762
202916
|
} = useCallStore();
|
|
202763
202917
|
const [items, setItems] = reactExports.useState(item);
|
|
202764
202918
|
const [isHoveredId, setIsHoveredId] = reactExports.useState(null);
|
|
202919
|
+
const [itemKeyColor, setItemKeyColor] = reactExports.useState((_a2 = item == null ? void 0 : item.chromaKeyOptions) == null ? void 0 : _a2.keyColor);
|
|
202765
202920
|
reactExports.useEffect(() => {
|
|
202766
202921
|
setItems(item);
|
|
202767
202922
|
}, [item]);
|
|
202923
|
+
const videoSlotStreams = useVideoSlotStreams();
|
|
202924
|
+
const videoSlotBinding = useVideoSlotBinding({
|
|
202925
|
+
item,
|
|
202926
|
+
livePlayerRef,
|
|
202927
|
+
fenge: videoSlotStreams.fenge
|
|
202928
|
+
});
|
|
202768
202929
|
const isMutedRef = reactExports.useRef(true);
|
|
202769
202930
|
const [isMuted, setIsMuted] = reactExports.useState(true);
|
|
202770
202931
|
const [isLoop, setIsLoop] = reactExports.useState(false);
|
|
202771
|
-
const fenge = '-":}{_+';
|
|
202772
|
-
const [selectedValue, setSelectedValue] = reactExports.useState(item.objectType === "videoSlot" && item.userId && item.streamIndex ? `${item.userId}${fenge}${item.streamIndex}` : "");
|
|
202773
202932
|
const [currentTime, setCurrentTime] = reactExports.useState(0);
|
|
202774
202933
|
const [isPlay, setIsPlay] = reactExports.useState(false);
|
|
202775
202934
|
const [duration, setDuration] = reactExports.useState(0);
|
|
202776
202935
|
const sliderStateRef = reactExports.useRef(false);
|
|
202936
|
+
const [isSliderHovered, setIsSliderHovered] = reactExports.useState(false);
|
|
202777
202937
|
const [hasMicrophone, setHasMicrophone] = reactExports.useState(false);
|
|
202778
202938
|
const [micMuted, setMicMuted] = reactExports.useState(true);
|
|
202779
|
-
const [isSliderHovered, setIsSliderHovered] = reactExports.useState(false);
|
|
202780
|
-
const [itemKeyColor, setItemKeyColor] = reactExports.useState((_a2 = item == null ? void 0 : item.chromaKeyOptions) == null ? void 0 : _a2.keyColor);
|
|
202781
202939
|
const handleLoopChange = (checked) => {
|
|
202782
202940
|
setIsLoop(checked);
|
|
202783
202941
|
if (item.objectType === "video" || item.objectType === "audio") {
|
|
@@ -202800,7 +202958,7 @@ const MetaItem = ({
|
|
|
202800
202958
|
},
|
|
202801
202959
|
audio: (checked) => {
|
|
202802
202960
|
var _a3, _b;
|
|
202803
|
-
const audioStream = livePlayerRef.current.
|
|
202961
|
+
const audioStream = livePlayerRef.current.getActiveVideoStreams().get(item.id);
|
|
202804
202962
|
if (audioStream) {
|
|
202805
202963
|
audioStream.getAudioTracks().forEach((track) => {
|
|
202806
202964
|
track.enabled = !checked;
|
|
@@ -202965,34 +203123,6 @@ const MetaItem = ({
|
|
|
202965
203123
|
width: 300,
|
|
202966
203124
|
padding: "12px 16px"
|
|
202967
203125
|
};
|
|
202968
|
-
const availableStreams = React$2.useMemo(() => callUsers.flatMap((user) => {
|
|
202969
|
-
const list = [];
|
|
202970
|
-
if (user.waiting_mode_state === WaitingModeState.WAITING) {
|
|
202971
|
-
return list;
|
|
202972
|
-
}
|
|
202973
|
-
if (user.rtc_userid === (callConfig == null ? void 0 : callConfig.drawing_board_id)) {
|
|
202974
|
-
return list;
|
|
202975
|
-
}
|
|
202976
|
-
list.push({
|
|
202977
|
-
label: `${user.nickname || user.rtc_userid} · 摄像头`,
|
|
202978
|
-
value: `${user.rtc_userid}${fenge}main`,
|
|
202979
|
-
isVideoEnabled: user.isVideoEnabled,
|
|
202980
|
-
rtc_userid: user.rtc_userid,
|
|
202981
|
-
nickname: user.nickname,
|
|
202982
|
-
isScreenEnabled: user.isScreenEnabled
|
|
202983
|
-
});
|
|
202984
|
-
if (user == null ? void 0 : user.isScreenEnabled) {
|
|
202985
|
-
list.push({
|
|
202986
|
-
label: `${user.nickname || user.rtc_userid} · 屏幕共享`,
|
|
202987
|
-
value: `${user.rtc_userid}${fenge}screen`,
|
|
202988
|
-
isVideoEnabled: user.isScreenEnabled,
|
|
202989
|
-
rtc_userid: user.rtc_userid,
|
|
202990
|
-
nickname: user.nickname,
|
|
202991
|
-
isScreenEnabled: user.isScreenEnabled
|
|
202992
|
-
});
|
|
202993
|
-
}
|
|
202994
|
-
return list;
|
|
202995
|
-
}), [callUsers]);
|
|
202996
203126
|
reactExports.useEffect(() => {
|
|
202997
203127
|
const handleCallStatusChanged = (data2) => {
|
|
202998
203128
|
if (item.objectType === "camera" || item.objectType === "microphone") {
|
|
@@ -203011,67 +203141,6 @@ const MetaItem = ({
|
|
|
203011
203141
|
}
|
|
203012
203142
|
}
|
|
203013
203143
|
}, [callConfig.isCall]);
|
|
203014
|
-
const targetUser = reactExports.useMemo(() => availableStreams.find((user) => user.rtc_userid === (selectedValue == null ? void 0 : selectedValue.split(fenge)[0])), [selectedValue, availableStreams]);
|
|
203015
|
-
reactExports.useEffect(() => {
|
|
203016
|
-
var _a3;
|
|
203017
|
-
if (item.objectType !== "videoSlot" || !livePlayerRef.current)
|
|
203018
|
-
return;
|
|
203019
|
-
try {
|
|
203020
|
-
const canvas = getter().fabricInstance;
|
|
203021
|
-
if (!canvas) {
|
|
203022
|
-
console.error("画布未初始化");
|
|
203023
|
-
return;
|
|
203024
|
-
}
|
|
203025
|
-
const videoSlotObj = (_a3 = canvas.getObjects()) == null ? void 0 : _a3.find((o2) => o2.id === item.id);
|
|
203026
|
-
if (!videoSlotObj) {
|
|
203027
|
-
console.error("找不到对应的连麦嘉宾对象:", item.id);
|
|
203028
|
-
return;
|
|
203029
|
-
}
|
|
203030
|
-
const [, streamIndex = "main"] = selectedValue.split(fenge);
|
|
203031
|
-
if (!targetUser || streamIndex === "screen" && !targetUser.isScreenEnabled) {
|
|
203032
|
-
console.log(`用户${item.userId}已退出,恢复为空连麦嘉宾`);
|
|
203033
|
-
setSelectedValue("");
|
|
203034
|
-
try {
|
|
203035
|
-
livePlayerRef.current.addEmptyVideoSlot({
|
|
203036
|
-
id: item.id
|
|
203037
|
-
});
|
|
203038
|
-
} catch (error2) {
|
|
203039
|
-
console.error("恢复空连麦嘉宾失败:", error2);
|
|
203040
|
-
}
|
|
203041
|
-
return;
|
|
203042
|
-
}
|
|
203043
|
-
console.log(`${targetUser.nickname || targetUser.rtc_userid}摄像头状态变更为: ${targetUser.isVideoEnabled ? "开启" : "关闭"}`);
|
|
203044
|
-
if (targetUser.isVideoEnabled) {
|
|
203045
|
-
try {
|
|
203046
|
-
livePlayerRef.current.bindVideoSlotToFirstEmpty({
|
|
203047
|
-
id: item.id,
|
|
203048
|
-
userId: targetUser.rtc_userid,
|
|
203049
|
-
streamIndex: streamIndex === "screen" ? "screen" : "main",
|
|
203050
|
-
userName: targetUser.nickname
|
|
203051
|
-
});
|
|
203052
|
-
videoSlotObj.userId = targetUser.rtc_userid;
|
|
203053
|
-
videoSlotObj.streamIndex = streamIndex;
|
|
203054
|
-
} catch (bindError) {
|
|
203055
|
-
console.error("绑定视频流失败:", bindError);
|
|
203056
|
-
}
|
|
203057
|
-
} else {
|
|
203058
|
-
try {
|
|
203059
|
-
livePlayerRef.current.createCameraClosedPlaceholder({
|
|
203060
|
-
...videoSlotObj,
|
|
203061
|
-
streamIndex
|
|
203062
|
-
}, targetUser);
|
|
203063
|
-
videoSlotObj._cameraClosedPlaceholder = true;
|
|
203064
|
-
} catch (placeholderError) {
|
|
203065
|
-
console.error("创建摄像头关闭占位符失败:", placeholderError);
|
|
203066
|
-
}
|
|
203067
|
-
}
|
|
203068
|
-
} catch (error2) {
|
|
203069
|
-
console.error("监听嘉宾视频状态变化时发生错误:", error2);
|
|
203070
|
-
}
|
|
203071
|
-
}, [targetUser, targetUser == null ? void 0 : targetUser.isVideoEnabled, item.userId, item.id, selectedValue]);
|
|
203072
|
-
reactExports.useEffect(() => {
|
|
203073
|
-
setItems(item);
|
|
203074
|
-
}, [item]);
|
|
203075
203144
|
return (
|
|
203076
203145
|
// 媒体项容器
|
|
203077
203146
|
// - 根据选中/悬停状态应用不同背景色
|
|
@@ -203214,72 +203283,15 @@ const MetaItem = ({
|
|
|
203214
203283
|
})]
|
|
203215
203284
|
}), item.objectType === "videoSlot" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
203216
203285
|
className: "mt-3.5 pl-1 pr-1",
|
|
203217
|
-
children: callConfig.isCall ? availableStreams.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(Select$1, {
|
|
203286
|
+
children: callConfig.isCall ? videoSlotStreams.availableStreams.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(Select$1, {
|
|
203218
203287
|
className: "w-full",
|
|
203219
203288
|
allowClear: true,
|
|
203220
|
-
value: selectedValue,
|
|
203289
|
+
value: videoSlotBinding.selectedValue,
|
|
203221
203290
|
placeholder: "选择嘉宾视频流绑定到此槽",
|
|
203222
|
-
options: availableStreams,
|
|
203291
|
+
options: videoSlotStreams.availableStreams,
|
|
203223
203292
|
showSearch: true,
|
|
203224
203293
|
optionFilterProp: "label",
|
|
203225
|
-
onChange:
|
|
203226
|
-
var _a3, _b;
|
|
203227
|
-
console.log("选择的视频槽:", val, opt);
|
|
203228
|
-
setSelectedValue(val);
|
|
203229
|
-
if (!val) {
|
|
203230
|
-
try {
|
|
203231
|
-
if (!livePlayerRef.current) {
|
|
203232
|
-
console.error("livePlayerRef未初始化");
|
|
203233
|
-
return;
|
|
203234
|
-
}
|
|
203235
|
-
livePlayerRef.current.addEmptyVideoSlot({
|
|
203236
|
-
id: item.id
|
|
203237
|
-
});
|
|
203238
|
-
console.log("成功清除连麦嘉宾绑定状态");
|
|
203239
|
-
} catch (error2) {
|
|
203240
|
-
console.error("清除连麦嘉宾绑定状态失败:", error2);
|
|
203241
|
-
}
|
|
203242
|
-
return;
|
|
203243
|
-
}
|
|
203244
|
-
try {
|
|
203245
|
-
const [userId, streamIndex] = String(val).split(fenge);
|
|
203246
|
-
const canvas = getter().fabricInstance;
|
|
203247
|
-
if (!canvas) {
|
|
203248
|
-
console.error("画布未初始化");
|
|
203249
|
-
return;
|
|
203250
|
-
}
|
|
203251
|
-
const videoSlotObj = ((_a3 = canvas.getObjects()) == null ? void 0 : _a3.find((o2) => o2.id === item.id)) || item;
|
|
203252
|
-
canvas.setActiveObject(videoSlotObj);
|
|
203253
|
-
const user = callUsers.find((user2) => user2.rtc_userid === userId);
|
|
203254
|
-
if (!user) {
|
|
203255
|
-
console.error("找不到用户:", userId);
|
|
203256
|
-
return;
|
|
203257
|
-
}
|
|
203258
|
-
if (user.isVideoEnabled) {
|
|
203259
|
-
livePlayerRef.current.bindVideoSlotToFirstEmpty({
|
|
203260
|
-
id: item.id,
|
|
203261
|
-
userId,
|
|
203262
|
-
device: user.device,
|
|
203263
|
-
streamIndex: streamIndex === "screen" ? "screen" : "main",
|
|
203264
|
-
userName: targetUser.nickname
|
|
203265
|
-
});
|
|
203266
|
-
if (videoSlotObj) {
|
|
203267
|
-
videoSlotObj.userId = userId;
|
|
203268
|
-
videoSlotObj.streamIndex = streamIndex;
|
|
203269
|
-
}
|
|
203270
|
-
} else {
|
|
203271
|
-
const targetObj = (_b = canvas.getObjects()) == null ? void 0 : _b.find((o2) => o2.id === item.id);
|
|
203272
|
-
if (targetObj) {
|
|
203273
|
-
livePlayerRef.current.createCameraClosedPlaceholder({
|
|
203274
|
-
...targetObj,
|
|
203275
|
-
streamIndex
|
|
203276
|
-
}, user);
|
|
203277
|
-
}
|
|
203278
|
-
}
|
|
203279
|
-
} catch (error2) {
|
|
203280
|
-
console.error("绑定连麦嘉宾失败:", error2);
|
|
203281
|
-
}
|
|
203282
|
-
},
|
|
203294
|
+
onChange: videoSlotBinding.handleStreamChange,
|
|
203283
203295
|
notFoundContent: /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
203284
203296
|
className: "text-#fff/80",
|
|
203285
203297
|
children: "暂无可用的远程视频流"
|
|
@@ -272872,7 +272884,7 @@ const LivePlayer = ({
|
|
|
272872
272884
|
await new Promise((resolve) => {
|
|
272873
272885
|
audioElement.onloadedmetadata = resolve;
|
|
272874
272886
|
});
|
|
272875
|
-
|
|
272887
|
+
audioElement.captureStream();
|
|
272876
272888
|
const audioObject = new oa(audioElement, {
|
|
272877
272889
|
selectable: true,
|
|
272878
272890
|
hasControls: true,
|
|
@@ -272898,9 +272910,10 @@ const LivePlayer = ({
|
|
|
272898
272910
|
canvas.add(audioObject);
|
|
272899
272911
|
setFabricObjects((old) => [audioObject, ...old]);
|
|
272900
272912
|
canvasRequestRenderAll();
|
|
272901
|
-
const
|
|
272902
|
-
|
|
272903
|
-
|
|
272913
|
+
const videoStream = audioElement.captureStream();
|
|
272914
|
+
const newVideoStreams = new Map(activeVideoStreamsRef.current);
|
|
272915
|
+
newVideoStreams.set(streamId, videoStream);
|
|
272916
|
+
activeVideoStreamsRef.current = newVideoStreams;
|
|
272904
272917
|
if (rtmpRef.current || canvasRtc) {
|
|
272905
272918
|
await audioMixing();
|
|
272906
272919
|
}
|
|
@@ -302346,6 +302359,9 @@ const RtcJoomRoom = reactExports.memo(({
|
|
|
302346
302359
|
(_a3 = rtc2 == null ? void 0 : rtc2.engine) == null ? void 0 : _a3.unsubscribeStream(userId, MediaType$1.AUDIO);
|
|
302347
302360
|
}, 100);
|
|
302348
302361
|
}
|
|
302362
|
+
updateCallUser(userId, {
|
|
302363
|
+
isPublishStream: stream.mediaType
|
|
302364
|
+
});
|
|
302349
302365
|
},
|
|
302350
302366
|
handleUserUnpublishStream: async (event) => {
|
|
302351
302367
|
var _a2, _b;
|
|
@@ -302360,6 +302376,9 @@ const RtcJoomRoom = reactExports.memo(({
|
|
|
302360
302376
|
if (mediaType & MediaType$1.AUDIO) {
|
|
302361
302377
|
await ((_b = getter().rtc) == null ? void 0 : _b.engine.unsubscribeStream(userId, MediaType$1.AUDIO));
|
|
302362
302378
|
}
|
|
302379
|
+
updateCallUser(userId, {
|
|
302380
|
+
isPublishStream: mediaType
|
|
302381
|
+
});
|
|
302363
302382
|
},
|
|
302364
302383
|
handleUserStartVideoCapture: (event) => {
|
|
302365
302384
|
const {
|
|
@@ -303694,7 +303713,7 @@ const WebLiveLogin = () => {
|
|
|
303694
303713
|
nickname: loginData.data.nickname || "",
|
|
303695
303714
|
token: loginData.data.token || "",
|
|
303696
303715
|
device: isMobile$3 ? "mobile" : "pc",
|
|
303697
|
-
videoList: [rtc_userid, rtc_userid + "screen", rtc_userid + "main"],
|
|
303716
|
+
videoList: [rtc_userid, rtc_userid + "screen", rtc_userid + "main", rtc_userid + "self"],
|
|
303698
303717
|
isAudioEnabled: !rtcConfig.enter_muted && devicePermissions.microphone.granted && devicePermissions.microphone.enabled,
|
|
303699
303718
|
isScreenEnabled: false,
|
|
303700
303719
|
// 屏幕共享是否开启
|
|
@@ -304252,8 +304271,7 @@ const UserAvatar = reactExports.memo(({
|
|
|
304252
304271
|
size = 40,
|
|
304253
304272
|
className = ""
|
|
304254
304273
|
}) => {
|
|
304255
|
-
|
|
304256
|
-
const avatarText = ((_a2 = nickname == null ? void 0 : nickname.charAt(0)) == null ? void 0 : _a2.toUpperCase()) || "?";
|
|
304274
|
+
const avatarText = (nickname == null ? void 0 : nickname.trim().charAt(0)) || "?";
|
|
304257
304275
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Avatar, {
|
|
304258
304276
|
size,
|
|
304259
304277
|
className,
|
|
@@ -304853,8 +304871,12 @@ const UserVideoContainer = reactExports.memo(({
|
|
|
304853
304871
|
const displayName = reactExports.useMemo(() => {
|
|
304854
304872
|
return user.nickname || "未知用户";
|
|
304855
304873
|
}, [user.nickname]);
|
|
304874
|
+
const isSelfWindow = reactExports.useMemo(() => {
|
|
304875
|
+
return videoId == null ? void 0 : videoId.includes("self");
|
|
304876
|
+
}, [videoId]);
|
|
304877
|
+
const maxNameLength = isSelfWindow ? 3 : 4;
|
|
304856
304878
|
const avatarChar = reactExports.useMemo(() => {
|
|
304857
|
-
return displayName.
|
|
304879
|
+
return displayName.trim().charAt(0);
|
|
304858
304880
|
}, [displayName]);
|
|
304859
304881
|
const handleClick = reactExports.useCallback(() => {
|
|
304860
304882
|
onClick == null ? void 0 : onClick(videoId || "");
|
|
@@ -304868,6 +304890,14 @@ const UserVideoContainer = reactExports.memo(({
|
|
|
304868
304890
|
console.log("main======", user, videoId);
|
|
304869
304891
|
}
|
|
304870
304892
|
const noMirror = user.rtc_userid === callConfig.drawing_board_id || (videoId == null ? void 0 : videoId.includes("screen")) || !user.isMirror;
|
|
304893
|
+
console.log("[UserVideoContainer] 镜像设置调试:", {
|
|
304894
|
+
videoId,
|
|
304895
|
+
userRtcUserid: user.rtc_userid,
|
|
304896
|
+
callConfigRtcUserid: callConfig.rtc_userid,
|
|
304897
|
+
userIsMirror: user.isMirror,
|
|
304898
|
+
noMirror,
|
|
304899
|
+
shouldMirror: +!noMirror
|
|
304900
|
+
});
|
|
304871
304901
|
const isModeFit = user.rtc_userid === callConfig.drawing_board_id || (videoId == null ? void 0 : videoId.includes("screen")) || user.device === "pc";
|
|
304872
304902
|
if (user.rtc_userid === callConfig.rtc_userid) {
|
|
304873
304903
|
rtc.engine.setLocalVideoPlayer((videoId == null ? void 0 : videoId.includes("screen")) ? StreamIndex$1.STREAM_INDEX_SCREEN : StreamIndex$1.STREAM_INDEX_MAIN, {
|
|
@@ -304935,7 +304965,7 @@ const UserVideoContainer = reactExports.memo(({
|
|
|
304935
304965
|
className: "",
|
|
304936
304966
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", {
|
|
304937
304967
|
className: "bg-black bg-opacity-50 rounded px-2 py-1 text-white text-xs font-medium truncate",
|
|
304938
|
-
children: displayName ? displayName.length >
|
|
304968
|
+
children: displayName ? displayName.length > maxNameLength ? `${displayName.substring(0, maxNameLength)}...` : displayName : ""
|
|
304939
304969
|
})
|
|
304940
304970
|
}), /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
304941
304971
|
className: `
|
|
@@ -305059,23 +305089,23 @@ const VideoSwipeContainer = reactExports.memo(
|
|
|
305059
305089
|
cols: 2,
|
|
305060
305090
|
rows: 1,
|
|
305061
305091
|
maxVisibleItems: 2,
|
|
305062
|
-
needsScroll:
|
|
305063
|
-
centerVertically:
|
|
305092
|
+
needsScroll: true,
|
|
305093
|
+
centerVertically: false
|
|
305064
305094
|
};
|
|
305065
305095
|
} else if (userCount <= 4) {
|
|
305066
305096
|
return {
|
|
305067
305097
|
cols: 2,
|
|
305068
305098
|
rows: 2,
|
|
305069
305099
|
maxVisibleItems: userCount,
|
|
305070
|
-
needsScroll:
|
|
305071
|
-
centerVertically:
|
|
305100
|
+
needsScroll: true,
|
|
305101
|
+
centerVertically: false
|
|
305072
305102
|
};
|
|
305073
305103
|
} else if (userCount <= 6) {
|
|
305074
305104
|
return {
|
|
305075
|
-
cols:
|
|
305076
|
-
rows:
|
|
305105
|
+
cols: 3,
|
|
305106
|
+
rows: 2,
|
|
305077
305107
|
maxVisibleItems: userCount,
|
|
305078
|
-
needsScroll:
|
|
305108
|
+
needsScroll: true,
|
|
305079
305109
|
centerVertically: true
|
|
305080
305110
|
};
|
|
305081
305111
|
} else if (userCount <= 9) {
|
|
@@ -305083,8 +305113,8 @@ const VideoSwipeContainer = reactExports.memo(
|
|
|
305083
305113
|
cols: 3,
|
|
305084
305114
|
rows: 3,
|
|
305085
305115
|
maxVisibleItems: userCount,
|
|
305086
|
-
needsScroll:
|
|
305087
|
-
centerVertically:
|
|
305116
|
+
needsScroll: true,
|
|
305117
|
+
centerVertically: false
|
|
305088
305118
|
};
|
|
305089
305119
|
} else {
|
|
305090
305120
|
return {
|
|
@@ -305100,79 +305130,85 @@ const VideoSwipeContainer = reactExports.memo(
|
|
|
305100
305130
|
const baseStyles = {
|
|
305101
305131
|
display: "grid",
|
|
305102
305132
|
width: "100%",
|
|
305103
|
-
height: gridLayout.needsScroll ? "100%" : "auto",
|
|
305104
305133
|
alignContent: gridLayout.centerVertically ? "center" : "start",
|
|
305105
305134
|
justifyContent: "center",
|
|
305106
305135
|
margin: "0 auto",
|
|
305107
305136
|
gap: "0",
|
|
305108
305137
|
// 网格间距
|
|
305109
|
-
padding: "0"
|
|
305138
|
+
padding: "0"
|
|
305110
305139
|
// 无内边距
|
|
305111
|
-
paddingBottom: gridLayout.needsScroll ? "env(safe-area-inset-bottom, 20px)" : "0"
|
|
305112
305140
|
};
|
|
305113
305141
|
if (userCount === 1) {
|
|
305114
305142
|
return {
|
|
305115
305143
|
...baseStyles,
|
|
305116
305144
|
gridTemplateColumns: "1fr",
|
|
305117
|
-
gridTemplateRows: "
|
|
305145
|
+
gridTemplateRows: "auto",
|
|
305118
305146
|
width: "100%",
|
|
305119
305147
|
height: "100%"
|
|
305120
305148
|
};
|
|
305121
305149
|
} else if (userCount === 2) {
|
|
305122
305150
|
return {
|
|
305123
305151
|
...baseStyles,
|
|
305124
|
-
gridTemplateColumns: "repeat(2, 1fr)",
|
|
305125
|
-
|
|
305152
|
+
gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
|
|
305153
|
+
gridAutoRows: "min-content",
|
|
305154
|
+
// 不压缩子元素
|
|
305126
305155
|
width: "100%",
|
|
305127
|
-
|
|
305156
|
+
maxHeight: "100%",
|
|
305157
|
+
overflowY: "auto"
|
|
305128
305158
|
};
|
|
305129
305159
|
} else if (userCount <= 4) {
|
|
305130
305160
|
return {
|
|
305131
305161
|
...baseStyles,
|
|
305132
|
-
gridTemplateColumns: "repeat(2, 1fr)",
|
|
305133
|
-
|
|
305162
|
+
gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
|
|
305163
|
+
gridAutoRows: "min-content",
|
|
305164
|
+
// 不压缩子元素
|
|
305134
305165
|
width: "100%",
|
|
305135
|
-
|
|
305166
|
+
maxHeight: "100%",
|
|
305167
|
+
overflowY: "auto"
|
|
305136
305168
|
};
|
|
305137
305169
|
} else if (userCount <= 6) {
|
|
305138
305170
|
return {
|
|
305139
305171
|
...baseStyles,
|
|
305140
|
-
gridTemplateColumns: "repeat(
|
|
305141
|
-
|
|
305172
|
+
gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
|
|
305173
|
+
gridAutoRows: "min-content",
|
|
305174
|
+
// 不压缩子元素
|
|
305142
305175
|
width: "100%",
|
|
305143
|
-
|
|
305176
|
+
maxHeight: "100%",
|
|
305177
|
+
overflowY: "auto"
|
|
305144
305178
|
};
|
|
305145
305179
|
} else if (userCount <= 9) {
|
|
305146
305180
|
return {
|
|
305147
305181
|
...baseStyles,
|
|
305148
|
-
gridTemplateColumns: "repeat(3, 1fr)",
|
|
305149
|
-
|
|
305182
|
+
gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
|
|
305183
|
+
gridAutoRows: "min-content",
|
|
305184
|
+
// 不压缩子元素
|
|
305150
305185
|
width: "100%",
|
|
305151
|
-
|
|
305186
|
+
maxHeight: "100%",
|
|
305187
|
+
overflowY: "auto"
|
|
305152
305188
|
};
|
|
305153
305189
|
} else {
|
|
305154
305190
|
return {
|
|
305155
305191
|
...baseStyles,
|
|
305156
|
-
gridTemplateColumns: "repeat(3, 1fr)",
|
|
305157
|
-
gridAutoRows: "
|
|
305158
|
-
//
|
|
305192
|
+
gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
|
|
305193
|
+
gridAutoRows: "min-content",
|
|
305194
|
+
// 不压缩子元素
|
|
305159
305195
|
width: "100%",
|
|
305160
305196
|
height: "100%",
|
|
305161
|
-
overflowY: "auto"
|
|
305197
|
+
overflowY: "auto",
|
|
305198
|
+
paddingBottom: "env(safe-area-inset-bottom, 20px)"
|
|
305162
305199
|
};
|
|
305163
305200
|
}
|
|
305164
305201
|
}, [gridLayout.centerVertically, gridLayout.needsScroll, userCount]);
|
|
305165
305202
|
const videoContainerStyles = reactExports.useMemo(() => {
|
|
305166
305203
|
return {
|
|
305167
305204
|
width: "100%",
|
|
305168
|
-
height: "100%",
|
|
305169
305205
|
aspectRatio: "9/16"
|
|
305170
|
-
// 保持9:16
|
|
305206
|
+
// 保持9:16比例,高度自动计算
|
|
305171
305207
|
};
|
|
305172
305208
|
}, [userCount]);
|
|
305173
305209
|
const gridItemClassName = reactExports.useMemo(() => {
|
|
305174
305210
|
const baseClass = " overflow-hidden shadow-sm";
|
|
305175
|
-
return `${baseClass} flex-shrink-0 w-full
|
|
305211
|
+
return `${baseClass} flex-shrink-0 w-full`;
|
|
305176
305212
|
}, [userCount]);
|
|
305177
305213
|
const slideContainerStyle = reactExports.useMemo(
|
|
305178
305214
|
() => ({
|
|
@@ -305651,7 +305687,12 @@ const MobileLive = reactExports.memo(({
|
|
|
305651
305687
|
}
|
|
305652
305688
|
const callUser = callUsers.find((user) => user.videoList.includes(videoId));
|
|
305653
305689
|
const index2 = callUser == null ? void 0 : callUser.videoList.findIndex((id3) => id3 === videoId);
|
|
305654
|
-
if (
|
|
305690
|
+
if (
|
|
305691
|
+
// 画板
|
|
305692
|
+
(callUser == null ? void 0 : callUser.rtc_userid) !== callConfig.drawing_board_id && // 共享屏幕
|
|
305693
|
+
index2 !== 1 && // 开镜像
|
|
305694
|
+
(callUser == null ? void 0 : callUser.isMirror)
|
|
305695
|
+
) {
|
|
305655
305696
|
videoElement.style.transform = "scaleX(-1)";
|
|
305656
305697
|
} else {
|
|
305657
305698
|
videoElement.style.transform = "scaleX(1)";
|