Bernds Anruftest Handy↔PC (2026-10-07): - Teilen am Handy: App "verkleinerte sich", Anruf danach weg. Ursache: Android 14+ verlangt vor MediaProjection einen Vordergrunddienst vom Typ mediaProjection; flutter_webrtc startet keinen, der Manifest-Eintrag verwies auf eine nicht mehr existierende Klasse. Neu: CallService (microphone|mediaProjection) + CallForeground: Zustimmung → Dienst (wartet auf echten startForeground) → Mitschnitt. Emulator-Test (Android 16): mit Fix 1080x2400@30 läuft; Gegenprobe ohne Dienst wirft genau 'Media projections require a foreground service ...'. - Dienst läuft während jedes Anrufs: Mikrofon bleibt im Hintergrund aktiv, Benachrichtigung "Anruf läuft" führt zurück. Mikrofon-Typ nur mit Berechtigung, sonst schmalere Variante statt Dienst-Abbruch. - Handy hörte nichts: SDK schaltet Sprachanrufe auf die Hörmuschel. Jetzt Lautsprecher als Standard (wie Discord) + Umschalter in der Anrufleiste. - LiveKit-Teilen am Handy öffnete den PC-Quellen-Auswähler → System-Dialog. - Im offenen Chat (Handy) Leiste "Anruf läuft · Zurück". - Einstellungen → Sprache & Video: Mikrofontest mit Pegel (PC-Diagnose: das Standardgerät lieferte nur Stille – Voicemeeter/virtuelle Geräte). Co-Authored-By: Claude Opus 5.5 <[email protected]>
81 lines
2.9 KiB
Dart
81 lines
2.9 KiB
Dart
import 'package:flutter/foundation.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import 'package:livekit_client/livekit_client.dart' as lk;
|
||
import 'package:matrix/matrix.dart' hide Room;
|
||
import 'package:pyramid/features/voice_channel/livekit_call_manager.dart';
|
||
|
||
/// Öffentliche Schnittstelle des Moduls `voice_channel` – LiveKit-SFU-basierte,
|
||
/// dauerhafte Voice-Channels (Discord-artig: Presence über Matrix-State-Events,
|
||
/// Screensharing, Mehrpersonen). Schnitt nach `docs/M2_MODULE_SCHNITT.md`;
|
||
/// bewusst GETRENNT vom 1:1-Modul `call_signaling`, siehe dort.
|
||
///
|
||
/// Andere Module konsumieren ausschließlich diese Schnittstelle über
|
||
/// [voiceChannelProvider] – nie `livekit_call_manager.dart` direkt.
|
||
///
|
||
/// Bewusste Abweichungen vom Entwurf im Doc (Verhaltensgleichheit vor
|
||
/// Schönheit): ChangeNotifier statt `stateStream`, Methodennamen wie im
|
||
/// Bestand (`startCall`/`hangUp` statt `join`/`leave`), und [room] bleibt
|
||
/// als LiveKit-Typ sichtbar, weil die Teilnehmer-Kacheln der UI direkt
|
||
/// LiveKit-Tracks rendern (analog zu den WebRTC-Renderern im Signaling).
|
||
abstract class VoiceChannelService extends ChangeNotifier {
|
||
bool get isActive;
|
||
bool get isConnecting;
|
||
String? get error;
|
||
bool get isMuted;
|
||
bool get isCameraOff;
|
||
bool get isScreenSharing;
|
||
bool get isDeafened;
|
||
bool get isVoiceChannel;
|
||
|
||
/// Der verbundene LiveKit-Raum (null = nicht verbunden).
|
||
lk.Room? get room;
|
||
|
||
/// Matrix-Raum-ID des aktiven Voice-Channels.
|
||
String? get currentRoomId;
|
||
String get displayName;
|
||
|
||
/// Sende-Qualität ('sd' | 'hd' | 'hd60' | 'fhd' | 'fhd60' | '4k').
|
||
/// Die *60-Presets sind für flüssiges Bildschirm-Streaming (M4).
|
||
String get currentQualityKey;
|
||
|
||
/// Empfangs-Qualität ('auto' | 'low' | 'medium' | 'high').
|
||
String get subscribeQualityKey;
|
||
|
||
Future<void> startCall({
|
||
required String roomName,
|
||
required String roomDisplayName,
|
||
required String identity,
|
||
bool audioOnly,
|
||
bool voiceChannel,
|
||
Client? matrixClient,
|
||
String? matrixRoomId,
|
||
});
|
||
Future<void> hangUp();
|
||
|
||
Future<void> toggleMute();
|
||
/// Handy: Ton über den Lautsprecher (true) oder die Hörmuschel (false).
|
||
/// Auf dem PC ohne Bedeutung.
|
||
bool get isSpeakerOn => true;
|
||
Future<void> toggleSpeaker() async {}
|
||
|
||
Future<void> toggleDeafen();
|
||
Future<void> toggleCamera();
|
||
Future<void> toggleScreenShare();
|
||
Future<void> startScreenShare(String sourceId);
|
||
Future<void> stopScreenShare();
|
||
|
||
Future<void> changeQuality(String qualityKey);
|
||
Future<void> setSubscribeQuality(String key);
|
||
|
||
/// Live-Anwendung des Lautstärke-Sliders auf alle Remote-Audio-Tracks.
|
||
Future<void> setOutputVolume(double v);
|
||
Future<void> changeAudioInput(String deviceId);
|
||
void setRemoteVolume(double volume);
|
||
}
|
||
|
||
/// Einziger Zugriffsweg der UI auf das Voice-Channel-Modul.
|
||
final voiceChannelProvider =
|
||
ChangeNotifierProvider<VoiceChannelService>((ref) {
|
||
return LiveKitCallManager.instance;
|
||
});
|