Skip to content

Commit

Permalink
feat: bili danmu
Browse files Browse the repository at this point in the history
  • Loading branch information
zijiren233 committed Jan 12, 2025
1 parent f737630 commit 06afd9c
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 26 deletions.
45 changes: 45 additions & 0 deletions src/plugins/danmu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
type Danmu = string | {
text: string;
opacity?: number;
color?: string;
border?: boolean;
style?: {}
}

export function sendDanmu(msg: Danmu, art?: Artplayer) {
if (!art || !art.plugins.artplayerPluginDanmuku) return;
if (typeof msg === "string") {
art.plugins.artplayerPluginDanmuku.emit({
direct: true,
text: msg,
});
} else {
art.plugins.artplayerPluginDanmuku.emit({
direct: true,
text: msg.text,
color: msg.color,
opacity: msg.opacity,
border: msg.border,
style: msg.style,
});
}
}

// SSE 弹幕
export function artplayerStreamDanmu(streamURL: string) {
return (art: Artplayer) => {
let eventSource: EventSource | null = null;
art.once("video:canplay", () => {
eventSource = new EventSource(streamURL);
eventSource.addEventListener("danmu", (event) => {
sendDanmu(event.data, art);
});
eventSource.onerror = (event) => {
console.error(event);
};
});
art.once("destroy", () => {
eventSource?.close();
});
};
}
2 changes: 2 additions & 0 deletions src/types/Movie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export interface BaseMovieInfo {
};
vendorInfo?: VendorInfo;
subtitles?: Subtitles;
danmu?: string;
streamDanmu?: string;
isFolder?: boolean;
parentId?: string;
}
Expand Down
48 changes: 22 additions & 26 deletions src/views/Cinema.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { currentMovieApi } from "@/services/apis/movie";
import { userStore } from "@/stores/user";
import { roomInfoApi } from "@/services/apis/room";
import { artplayerSubtitle } from "@/plugins/subtitle";
import { sendDanmu, artplayerStreamDanmu } from "@/plugins/danmu";
const Player = defineAsyncComponent(() => import("@/components/Player.vue"));
Expand All @@ -51,17 +52,6 @@ const { hasMemberPermission } = useRoomPermission();
let player: Artplayer | undefined;
const sendDanmuku = (msg: string) => {
if (!player || !player.plugins.artplayerPluginDanmuku) return;
player.plugins.artplayerPluginDanmuku.emit({
direct: true,
text: msg, // 弹幕文本
color: "#fff", // 弹幕局部颜色
border: false // 是否显示描边
//mode: 0, // 弹幕模式: 0表示滚动, 1静止
});
};
const wsProtocol = location.protocol === "https:" ? "wss:" : "ws:";
const { status, data, send, open } = useWebSocket(
`${wsProtocol}//${window.location.host}/api/room/ws?roomId=${roomID.value}`,
Expand Down Expand Up @@ -149,7 +139,7 @@ const playerOption = computed<options>(() => {
plugins: [
// 弹幕
artplayerPluginDanmuku({
danmuku: [],
danmuku: room.currentMovie.base!.danmu || [],
speed: 8,
async beforeEmit(danmu: any) {
if (danmu.direct) {
Expand All @@ -161,7 +151,7 @@ const playerOption = computed<options>(() => {
}),
// WARN: room.currentStatus 变了会导致重载
newSyncPlugin(sendElement, room.currentStatus, () => room.currentExpireId),
artplayerPluginMediaControl()
artplayerPluginMediaControl(),
]
};
Expand Down Expand Up @@ -209,6 +199,10 @@ const playerOption = computed<options>(() => {
);
}
if (room.currentMovie.base!.streamDanmu) {
option.plugins!.push(artplayerStreamDanmu(room.currentMovie.base!.streamDanmu));
}
return option;
});
Expand Down Expand Up @@ -285,12 +279,10 @@ const setPlayerStatus = (status: Status) => {
// key: userId:connId
const peerConnections = ref<{ [key: string]: RTCPeerConnection }>({});
const localStream = ref<MediaStream | undefined>(undefined);
let remoteAudioElements: {[key: string]: HTMLAudioElement} = {};
let remoteAudioElements: { [key: string]: HTMLAudioElement } = {};
const peerConnectionsLengthWithUserId = computed(() => {
const userIdSet = new Set(
Object.keys(peerConnections.value).map(key => key.split(":")[0])
);
const userIdSet = new Set(Object.keys(peerConnections.value).map((key) => key.split(":")[0]));
return userIdSet.size;
});
Expand All @@ -314,7 +306,7 @@ const getAudioDevices = async () => {
const toggleMute = () => {
if (!localStream.value) return;
isMuted.value = !isMuted.value;
localStream.value.getAudioTracks().forEach(track => {
localStream.value.getAudioTracks().forEach((track) => {
track.enabled = !isMuted.value;
});
};
Expand All @@ -325,11 +317,11 @@ const switchMicrophone = async () => {
try {
const newStream = await navigator.mediaDevices.getUserMedia({
audio: {
audio: {
deviceId: selectedAudioInput.value,
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true,
autoGainControl: true
}
});
Expand Down Expand Up @@ -562,7 +554,7 @@ const handleElementMessage = (msg: Message) => {
const messageWithTime = `${messageContent} <small>[${currentTime}]</small>`;
// 添加消息到消息列表
sendMsg(messageWithTime);
sendDanmuku(messageContent);
sendDanmu({ text: messageContent, border: true }, player);
break;
}
case MessageType.STATUS:
Expand Down Expand Up @@ -640,15 +632,15 @@ const chatArea = ref();
const resetChatAreaHeight = () => {
const h = playArea.value ? playArea : noPlayArea;
if (!chatArea.value || !h.value) return;
// 计算基础高度
let baseHeight = h.value.scrollHeight - 112;
// 如果有语音控制面板,减去其高度
if (audioControls.value && audioControls.value instanceof HTMLElement) {
baseHeight -= audioControls.value.offsetHeight + 16; // 16px for margin
}
chatArea.value.style.height = `${baseHeight}px`;
};
Expand Down Expand Up @@ -792,7 +784,11 @@ onBeforeUnmount(() => {
>退出语音 ({{ peerConnectionsLengthWithUserId }})</el-button
>
</div>
<div ref="audioControls" v-show="localStream" class="card-body mb-2 audio-controls-container">
<div
ref="audioControls"
v-show="localStream"
class="card-body mb-2 audio-controls-container"
>
<div class="audio-controls">
<el-select
v-model="selectedAudioInput"
Expand Down Expand Up @@ -837,7 +833,7 @@ onBeforeUnmount(() => {
size="small"
style="width: 100%"
>
{{ isMuted ? '取消闭麦' : '闭麦' }}
{{ isMuted ? "取消闭麦" : "闭麦" }}
</el-button>
</div>
</div>
Expand Down

0 comments on commit 06afd9c

Please sign in to comment.