This commit is contained in:
@@ -304,6 +304,7 @@ export const useChatStore = defineStore('chat', () => {
|
||||
if (!navigator.mediaDevices?.getUserMedia) return null;
|
||||
|
||||
try {
|
||||
console.log('[video] getUserMedia:start');
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: {
|
||||
facingMode: 'user',
|
||||
@@ -312,12 +313,20 @@ export const useChatStore = defineStore('chat', () => {
|
||||
},
|
||||
audio: true
|
||||
});
|
||||
console.log('[video] getUserMedia:success', {
|
||||
audioTracks: stream.getAudioTracks().length,
|
||||
videoTracks: stream.getVideoTracks().length
|
||||
});
|
||||
selfPreviewStream.value = stream;
|
||||
selfMuted.value = false;
|
||||
selfCameraEnabled.value = true;
|
||||
return stream;
|
||||
} catch (error) {
|
||||
console.error('Lokale Video-Vorschau konnte nicht gestartet werden:', error);
|
||||
console.error('[video] getUserMedia:error', {
|
||||
name: error?.name,
|
||||
message: error?.message
|
||||
});
|
||||
setTemporaryError('Lokale Kamera/Vorschau konnte nicht gestartet werden.');
|
||||
return null;
|
||||
}
|
||||
@@ -360,6 +369,12 @@ export const useChatStore = defineStore('chat', () => {
|
||||
bundlePolicy: 'max-bundle',
|
||||
rtcpMuxPolicy: 'require'
|
||||
});
|
||||
console.log('[video] peer:create', {
|
||||
callId: session.callId,
|
||||
isCaller: !!session.media?.isCaller,
|
||||
iceServers: session.media.iceServers || [],
|
||||
iceTransportPolicy: session.media.iceTransportPolicy || 'relay'
|
||||
});
|
||||
|
||||
const runtime = {
|
||||
pc,
|
||||
@@ -374,6 +389,11 @@ export const useChatStore = defineStore('chat', () => {
|
||||
}
|
||||
|
||||
pc.ontrack = (event) => {
|
||||
console.log('[video] peer:track', {
|
||||
callId: session.callId,
|
||||
streamCount: event.streams?.length || 0,
|
||||
trackKind: event.track?.kind
|
||||
});
|
||||
const [stream] = event.streams || [];
|
||||
if (stream) {
|
||||
setRemoteStream(session.callId, stream);
|
||||
@@ -389,6 +409,11 @@ export const useChatStore = defineStore('chat', () => {
|
||||
|
||||
pc.onicecandidate = (event) => {
|
||||
if (!event.candidate) return;
|
||||
console.log('[video] peer:icecandidate', {
|
||||
callId: session.callId,
|
||||
type: event.candidate.type,
|
||||
candidate: String(event.candidate.candidate || '').slice(0, 140)
|
||||
});
|
||||
emitVideoSignal(session.callId, 'candidate', {
|
||||
candidate: event.candidate.toJSON()
|
||||
});
|
||||
@@ -396,6 +421,10 @@ export const useChatStore = defineStore('chat', () => {
|
||||
|
||||
pc.onconnectionstatechange = () => {
|
||||
const state = pc.connectionState;
|
||||
console.log('[video] peer:connectionstate', {
|
||||
callId: session.callId,
|
||||
state
|
||||
});
|
||||
if (state === 'connected' && runtime.connectTimeoutId) {
|
||||
window.clearTimeout(runtime.connectTimeoutId);
|
||||
runtime.connectTimeoutId = null;
|
||||
@@ -406,6 +435,10 @@ export const useChatStore = defineStore('chat', () => {
|
||||
};
|
||||
|
||||
pc.oniceconnectionstatechange = () => {
|
||||
console.log('[video] peer:iceconnectionstate', {
|
||||
callId: session.callId,
|
||||
state: pc.iceConnectionState
|
||||
});
|
||||
if (pc.iceConnectionState === 'failed') {
|
||||
emitConnectionState(session.callId, 'failed');
|
||||
}
|
||||
@@ -435,11 +468,17 @@ export const useChatStore = defineStore('chat', () => {
|
||||
if (!runtime || runtime.offerCreated) return;
|
||||
|
||||
runtime.offerCreated = true;
|
||||
console.log('[video] offer:create', { callId: session.callId });
|
||||
const offer = await runtime.pc.createOffer({
|
||||
offerToReceiveAudio: true,
|
||||
offerToReceiveVideo: true
|
||||
});
|
||||
await runtime.pc.setLocalDescription(offer);
|
||||
console.log('[video] offer:local-description-set', {
|
||||
callId: session.callId,
|
||||
type: offer.type,
|
||||
sdpLength: String(offer.sdp || '').length
|
||||
});
|
||||
emitVideoSignal(session.callId, 'description', {
|
||||
description: {
|
||||
type: offer.type,
|
||||
@@ -451,6 +490,11 @@ export const useChatStore = defineStore('chat', () => {
|
||||
async function startVideoMediaForSession(session) {
|
||||
if (!session?.media) return;
|
||||
try {
|
||||
console.log('[video] media:start', {
|
||||
callId: session.callId,
|
||||
status: session.status,
|
||||
isCaller: !!session.media?.isCaller
|
||||
});
|
||||
const runtime = await ensurePeerConnectionForSession(session);
|
||||
if (runtime && !runtime.connectTimeoutId) {
|
||||
runtime.connectTimeoutId = window.setTimeout(() => {
|
||||
@@ -479,16 +523,33 @@ export const useChatStore = defineStore('chat', () => {
|
||||
if (!session || !session.media) return;
|
||||
|
||||
try {
|
||||
console.log('[video] signal:incoming', {
|
||||
callId,
|
||||
signalType,
|
||||
descriptionType: data.description?.type || null,
|
||||
candidateType: data.candidate?.type || null
|
||||
});
|
||||
const runtime = await ensurePeerConnectionForSession(session);
|
||||
if (!runtime) return;
|
||||
|
||||
if (signalType === 'description' && data.description?.type && data.description?.sdp) {
|
||||
await runtime.pc.setRemoteDescription(new RTCSessionDescription(data.description));
|
||||
console.log('[video] signal:remote-description-set', {
|
||||
callId,
|
||||
type: data.description.type,
|
||||
sdpLength: String(data.description.sdp || '').length
|
||||
});
|
||||
await flushPendingRemoteCandidates(runtime);
|
||||
|
||||
if (data.description.type === 'offer') {
|
||||
console.log('[video] answer:create', { callId });
|
||||
const answer = await runtime.pc.createAnswer();
|
||||
await runtime.pc.setLocalDescription(answer);
|
||||
console.log('[video] answer:local-description-set', {
|
||||
callId,
|
||||
type: answer.type,
|
||||
sdpLength: String(answer.sdp || '').length
|
||||
});
|
||||
emitVideoSignal(callId, 'description', {
|
||||
description: {
|
||||
type: answer.type,
|
||||
@@ -501,8 +562,17 @@ export const useChatStore = defineStore('chat', () => {
|
||||
|
||||
if (signalType === 'candidate' && data.candidate) {
|
||||
if (runtime.pc.remoteDescription) {
|
||||
console.log('[video] candidate:add', {
|
||||
callId,
|
||||
type: data.candidate.type,
|
||||
candidate: String(data.candidate.candidate || '').slice(0, 140)
|
||||
});
|
||||
await runtime.pc.addIceCandidate(new RTCIceCandidate(data.candidate));
|
||||
} else {
|
||||
console.log('[video] candidate:queue', {
|
||||
callId,
|
||||
type: data.candidate.type
|
||||
});
|
||||
runtime.pendingCandidates.push(data.candidate);
|
||||
}
|
||||
}
|
||||
@@ -1006,6 +1076,7 @@ export const useChatStore = defineStore('chat', () => {
|
||||
|
||||
async function inviteVideoCall() {
|
||||
if (!socket.value?.connected || !currentConversation.value || !canStartVideoCall.value) return;
|
||||
console.log('[video] invite:client', { withUserName: currentConversation.value });
|
||||
const stream = await ensureLocalPreviewStream();
|
||||
if (!stream) {
|
||||
setTemporaryError('Kamera/Mikrofon konnten nicht für den Videochat gestartet werden.');
|
||||
@@ -1016,11 +1087,13 @@ export const useChatStore = defineStore('chat', () => {
|
||||
|
||||
async function acceptVideoCall(callId) {
|
||||
if (!socket.value?.connected || !callId) return;
|
||||
console.log('[video] accept:client:start', { callId });
|
||||
const stream = await ensureLocalPreviewStream();
|
||||
if (!stream) {
|
||||
setTemporaryError('Kamera/Mikrofon konnten nicht für den Videochat gestartet werden.');
|
||||
return;
|
||||
}
|
||||
console.log('[video] accept:client:emit', { callId });
|
||||
socket.value.emit('videoCall:accept', { callId });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user