refactored UDP audio sender/receiver scripts to support port reuse for shared access, enhanced logging for recording state and audio clip monitoring
This commit is contained in:
@ -234,10 +234,13 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_udpListener = new UdpClient(listenPort);
|
// Create UDP client with port reuse to allow sharing with UDPPeerDiscovery
|
||||||
|
_udpListener = new UdpClient();
|
||||||
|
_udpListener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||||
|
_udpListener.Client.Bind(new IPEndPoint(IPAddress.Any, listenPort));
|
||||||
_isListening = true;
|
_isListening = true;
|
||||||
|
|
||||||
ConvaiLogger.Info($"Simple UDP Audio Receiver V2 listening on port {listenPort}", ConvaiLogger.LogCategory.Character);
|
ConvaiLogger.Info($"Simple UDP Audio Receiver V2 listening on port {listenPort} (shared)", ConvaiLogger.LogCategory.Character);
|
||||||
|
|
||||||
// Start listening for incoming packets
|
// Start listening for incoming packets
|
||||||
_ = ListenForAudioPackets(_cancellationTokenSource.Token);
|
_ = ListenForAudioPackets(_cancellationTokenSource.Token);
|
||||||
|
|||||||
@ -487,7 +487,7 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
|||||||
_localSamples.Clear();
|
_localSamples.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvaiLogger.Info("Started recording for UDP transmission (Simple)", ConvaiLogger.LogCategory.Character);
|
ConvaiLogger.Info($"🎤 Started recording for UDP transmission to {targetIP}:{targetPort}", ConvaiLogger.LogCategory.Character);
|
||||||
OnRecordingStateChanged?.Invoke(true);
|
OnRecordingStateChanged?.Invoke(true);
|
||||||
|
|
||||||
// Send START control and wait briefly for ACK to ensure receiver is ready
|
// Send START control and wait briefly for ACK to ensure receiver is ready
|
||||||
|
|||||||
@ -201,10 +201,13 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_udpListener = new UdpClient(listenPort);
|
// Create UDP client with port reuse to allow sharing with UDPPeerDiscovery
|
||||||
|
_udpListener = new UdpClient();
|
||||||
|
_udpListener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||||
|
_udpListener.Client.Bind(new IPEndPoint(IPAddress.Any, listenPort));
|
||||||
_isListening = true;
|
_isListening = true;
|
||||||
|
|
||||||
ConvaiLogger.Info($"UDP Speech Receiver listening on port {listenPort}", ConvaiLogger.LogCategory.Character);
|
ConvaiLogger.Info($"UDP Speech Receiver listening on port {listenPort} (shared)", ConvaiLogger.LogCategory.Character);
|
||||||
|
|
||||||
// Start listening for incoming packets
|
// Start listening for incoming packets
|
||||||
_ = ListenForSpeechPackets(_cancellationTokenSource.Token);
|
_ = ListenForSpeechPackets(_cancellationTokenSource.Token);
|
||||||
|
|||||||
@ -207,18 +207,23 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
|||||||
|
|
||||||
private void SubscribeToNPCEvents()
|
private void SubscribeToNPCEvents()
|
||||||
{
|
{
|
||||||
if (sourceNPC?.AudioManager != null)
|
if (sourceNPC == null)
|
||||||
{
|
{
|
||||||
// Hook into the character talking events
|
ConvaiLogger.Warn("SubscribeToNPCEvents: sourceNPC is null", ConvaiLogger.LogCategory.Character);
|
||||||
sourceNPC.AudioManager.OnCharacterTalkingChanged += HandleCharacterTalkingChanged;
|
return;
|
||||||
sourceNPC.AudioManager.OnAudioTranscriptAvailable += HandleTranscriptAvailable;
|
}
|
||||||
|
|
||||||
ConvaiLogger.Info($"UDP Speech Sender subscribed to NPC: {sourceNPC.characterName}", ConvaiLogger.LogCategory.Character);
|
if (sourceNPC.AudioManager == null)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
ConvaiLogger.Warn("No source NPC available for speech transmission", ConvaiLogger.LogCategory.Character);
|
ConvaiLogger.Warn($"SubscribeToNPCEvents: AudioManager is null for {sourceNPC.characterName}", ConvaiLogger.LogCategory.Character);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hook into the character talking events
|
||||||
|
sourceNPC.AudioManager.OnCharacterTalkingChanged += HandleCharacterTalkingChanged;
|
||||||
|
sourceNPC.AudioManager.OnAudioTranscriptAvailable += HandleTranscriptAvailable;
|
||||||
|
|
||||||
|
ConvaiLogger.Info($"✅ UDP Speech Sender subscribed to NPC: {sourceNPC.characterName} (on {sourceNPC.gameObject.name}), AudioManager: {sourceNPC.AudioManager.name}", ConvaiLogger.LogCategory.Character);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleCharacterTalkingChanged(bool isTalking)
|
private void HandleCharacterTalkingChanged(bool isTalking)
|
||||||
@ -227,11 +232,13 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
|||||||
|
|
||||||
if (isTalking)
|
if (isTalking)
|
||||||
{
|
{
|
||||||
|
ConvaiLogger.Info($"🔊 NPC {sourceNPC.characterName} started talking, monitoring audio clips...", ConvaiLogger.LogCategory.Character);
|
||||||
// Start monitoring for audio clips
|
// Start monitoring for audio clips
|
||||||
StartCoroutine(MonitorAudioClips());
|
StartCoroutine(MonitorAudioClips());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ConvaiLogger.Info($"🔊 NPC {sourceNPC.characterName} stopped talking", ConvaiLogger.LogCategory.Character);
|
||||||
// End speech transmission
|
// End speech transmission
|
||||||
_ = SendFinalPacket();
|
_ = SendFinalPacket();
|
||||||
}
|
}
|
||||||
@ -247,9 +254,20 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
|||||||
|
|
||||||
private IEnumerator MonitorAudioClips()
|
private IEnumerator MonitorAudioClips()
|
||||||
{
|
{
|
||||||
if (sourceNPC?.AudioManager == null) yield break;
|
if (sourceNPC?.AudioManager == null)
|
||||||
|
{
|
||||||
|
ConvaiLogger.Warn("MonitorAudioClips: AudioManager is null", ConvaiLogger.LogCategory.Character);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
AudioSource audioSource = sourceNPC.AudioManager.GetComponent<AudioSource>();
|
AudioSource audioSource = sourceNPC.AudioManager.GetComponent<AudioSource>();
|
||||||
|
if (audioSource == null)
|
||||||
|
{
|
||||||
|
ConvaiLogger.Warn("MonitorAudioClips: AudioSource is null", ConvaiLogger.LogCategory.Character);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvaiLogger.Info($"🔊 Started monitoring audio clips on {audioSource.name}", ConvaiLogger.LogCategory.Character);
|
||||||
AudioClip lastClip = null;
|
AudioClip lastClip = null;
|
||||||
|
|
||||||
while (sourceNPC.IsCharacterTalking)
|
while (sourceNPC.IsCharacterTalking)
|
||||||
@ -258,6 +276,7 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
|||||||
{
|
{
|
||||||
// New clip detected!
|
// New clip detected!
|
||||||
lastClip = audioSource.clip;
|
lastClip = audioSource.clip;
|
||||||
|
ConvaiLogger.Info($"🔊 Detected new audio clip: {lastClip.name}, length: {lastClip.length:F2}s", ConvaiLogger.LogCategory.Character);
|
||||||
|
|
||||||
// Only send if we haven't sent this clip before
|
// Only send if we haven't sent this clip before
|
||||||
if (!_sentClips.Contains(lastClip))
|
if (!_sentClips.Contains(lastClip))
|
||||||
@ -268,13 +287,19 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
|||||||
string transcript = GetRecentTranscript();
|
string transcript = GetRecentTranscript();
|
||||||
|
|
||||||
// Send this clip
|
// Send this clip
|
||||||
|
ConvaiLogger.Info($"🔊 Transmitting audio clip to {targetIP}:{targetPort}", ConvaiLogger.LogCategory.Character);
|
||||||
_ = TransmitAudioClip(lastClip, transcript);
|
_ = TransmitAudioClip(lastClip, transcript);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConvaiLogger.Info($"🔊 Clip already sent, skipping", ConvaiLogger.LogCategory.Character);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return new WaitForSeconds(0.1f); // Check every 100ms
|
yield return new WaitForSeconds(0.1f); // Check every 100ms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConvaiLogger.Info($"🔊 Stopped monitoring audio clips (NPC stopped talking)", ConvaiLogger.LogCategory.Character);
|
||||||
// Clear sent clips when done
|
// Clear sent clips when done
|
||||||
_sentClips.Clear();
|
_sentClips.Clear();
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
Unity-Master/ProjectSettings/EditorBuildSettings.asset
(Stored with Git LFS)
BIN
Unity-Master/ProjectSettings/EditorBuildSettings.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Unity-Master/ProjectSettings/ProjectSettings.asset
(Stored with Git LFS)
BIN
Unity-Master/ProjectSettings/ProjectSettings.asset
(Stored with Git LFS)
Binary file not shown.
Reference in New Issue
Block a user