translationSpeakerOutputChanged function

Future<void> translationSpeakerOutputChanged(
  1. TranslationSpeakerOutputChangedOptions options
)

Handles the translation:speakerOutputChanged socket event. Called when a speaker changes their output language.

Implementation

Future<void> translationSpeakerOutputChanged(
    TranslationSpeakerOutputChangedOptions options) async {
  try {
    final data = options.data;

    // Update local tracking state
    options.updateSpeakerTranslationState?.call(
      data.speakerId,
      data.outputLanguage,
      data.originalProducerId,
    );

    // Check if listener has an override
    final listenerWantsOriginal =
        options.listenerOverride?.wantOriginal == true;
    final listenerWantsDifferentLanguage =
        options.listenerOverride?.preferredLanguage != null &&
            options.listenerOverride!.preferredLanguage!.toLowerCase() !=
                data.outputLanguage?.toLowerCase();

    // If listener wants original audio, don't pause
    if (listenerWantsOriginal) {
      options.showAlert?.call(
        message:
            '${data.speakerName} is speaking in ${data.outputLanguage != null ? getLanguageName(data.outputLanguage!) : 'translated'} but you\'re hearing original',
        type: 'info',
        duration: 3000,
      );
      return;
    }

    // If listener wants a different language, still pause original
    if (listenerWantsDifferentLanguage) {
      if (options.pauseOriginalProducer != null) {
        await options.pauseOriginalProducer!(
            data.originalProducerId, data.speakerId);
      }
      return;
    }

    if (data.enabled && data.outputLanguage != null) {
      // Speaker has enabled translation output - pause original audio
      if (options.pauseOriginalProducer != null) {
        await options.pauseOriginalProducer!(
            data.originalProducerId, data.speakerId);
      }

      options.showAlert?.call(
        message:
            '${data.speakerName} is now speaking in ${getLanguageName(data.outputLanguage!)}',
        type: 'info',
        duration: 3000,
      );
    } else {
      // Speaker disabled translation - stop consuming and resume original
      if (options.stopConsumingTranslationForSpeaker != null) {
        await options.stopConsumingTranslationForSpeaker!(data.speakerId);
      }

      if (options.resumeOriginalProducer != null) {
        await options.resumeOriginalProducer!(
            data.originalProducerId, data.speakerId);
      }

      if (!data.enabled) {
        options.showAlert?.call(
          message: '${data.speakerName} returned to original language',
          type: 'info',
          duration: 3000,
        );
      }
    }
  } catch (e) {
    // Handle error silently
  }
}