flutter-webrtc / dart-sip-ua

A dart-lang version of the SIP UA stack.
MIT License
331 stars 255 forks source link

Toggle Speaker #217

Open ifightcode opened 3 years ago

ifightcode commented 3 years ago

How can I toggle speaker? I mean switch between loudspeaker and top speaker. Despite of voiceonly true or false, my phones always using loudspeakers.

RaviGaruda commented 3 years ago

Same issue! Toggle speaker not working. @ifightcode have you find any solution?

ifightcode commented 3 years ago

Same issue! Toggle speaker not working. @ifightcode have you find any solution?

No. I had to abandon the project due to numerous issues.

RaviGaruda commented 3 years ago

okay, so have you found any other sip/voip client for flutter?

turtlepigg commented 3 years ago

I'm using Flutter as a module in our native iOS and Android apps (which I assume a lot of people who are using this are doing since they have to interface with CallKit for iOS). I was able to solve this by just talking to native directly via MethodChannel's. I've only done Android at this point but will do it in iOS in a week or two, they both work similarly as far as audio goes, you just get the apps current audio session (which flutter is also using) and you can mess with it. When I start the call it starts the audio session just fine. From that point forward I can use a method channel to tell native to set the audio output to whatever I want it to be. Here's what the native Android side looks like: flutterPhoneChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { if (call.method.equals("toggleSpeaker")) { boolean speakerOn = ((Map<String, Boolean>) call.arguments).get("speakerOn"); AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); am.setMode(AudioManager.MODE_IN_CALL); am.setSpeakerphoneOn(speakerOn); } } });

If someone wants the native solution for iOS tag me if it's been a week or so since this post and I can share my solution from that side. Would definitely be nice if controlling the audio this way was part of this library though since you can't really release a VOIP solution without those basic controls. Alternatively there may be a Flutter package out there that allows you to mess with the audio sessions from dart. I didn't look into it since my apps are already going back and forth from Flutter and native, making this a quick solution for me.

zi6xuan commented 2 years ago
  void _handelStreams(CallState event) async {
    MediaStream stream = event.stream;
    if (event.originator == 'local') {
      if (_localRenderer != null) {
        _localRenderer.srcObject = stream;
      }
      if (!kIsWeb) {
        event.stream?.getAudioTracks()?.first?.enableSpeakerphone(false);
      }
      _localStream = stream;
    }
    if (event.originator == 'remote') {
      if (_remoteRenderer != null) {
        _remoteRenderer.srcObject = stream;
      }
      _remoteStream = stream;
    }

    this.setState(() {
      _resizeLocalVideo();
    });
  }

This can help you

ShahzadUmarBaig commented 2 years ago

I'm using Flutter as a module in our native iOS and Android apps (which I assume a lot of people who are using this are doing since they have to interface with CallKit for iOS). I was able to solve this by just talking to native directly via MethodChannel's. I've only done Android at this point but will do it in iOS in a week or two, they both work similarly as far as audio goes, you just get the apps current audio session (which flutter is also using) and you can mess with it. When I start the call it starts the audio session just fine. From that point forward I can use a method channel to tell native to set the audio output to whatever I want it to be. Here's what the native Android side looks like: flutterPhoneChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { if (call.method.equals("toggleSpeaker")) { boolean speakerOn = ((Map<String, Boolean>) call.arguments).get("speakerOn"); AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); am.setMode(AudioManager.MODE_IN_CALL); am.setSpeakerphoneOn(speakerOn); } } });

If someone wants the native solution for iOS tag me if it's been a week or so since this post and I can share my solution from that side. Would definitely be nice if controlling the audio this way was part of this library though since you can't really release a VOIP solution without those basic controls. Alternatively there may be a Flutter package out there that allows you to mess with the audio sessions from dart. I didn't look into it since my apps are already going back and forth from Flutter and native, making this a quick solution for me.

I have been trying to achieve the solution through native code using Swift. So far I am unable to achieve it, can you share the code that worked on iOS device switching from Speaker to Receiver?

Although my native code print statement shows that the output port is Receiver but still the audio is attached to speaker somehow.

Ossyman7 commented 1 year ago

@turtlepigg if you found a workaround for iOS can you please share it

viniciusoliverrs commented 1 year ago

Estou usando o Flutter como um módulo em nossos aplicativos nativos para iOS e Android (o que presumo que muitas pessoas que usam isso estão fazendo, pois precisam fazer interface com o CallKit para iOS). Consegui resolver isso conversando diretamente com o nativo através do MethodChannel. Eu só fiz Android neste momento, mas farei isso no iOS em uma semana ou duas, ambos funcionam de forma semelhante no que diz respeito ao áudio, você apenas obtém a sessão de áudio atual do aplicativo (que o flutter também está usando) e você pode bagunçar com isso. Quando inicio a chamada, a sessão de áudio inicia perfeitamente. Desse ponto em diante, posso usar um canal de método para dizer ao nativo para definir a saída de áudio como eu quiser. Esta é a aparência do lado nativo do Android: flutterPhoneChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { if (call.method.equals("toggleSpeaker")) { boolean speakerOn = ((Map<String, Boolean>) call.arguments).get("speakerOn"); AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); am.setMode(AudioManager.MODE_IN_CALL); am.setSpeakerphoneOn(speakerOn); } } });

Se alguém quiser a solução nativa para iOS, marque-me se já faz uma semana ou mais desde este post e posso compartilhar minha solução desse lado. Definitivamente seria bom se controlar o áudio dessa forma fizesse parte desta biblioteca, já que você não pode realmente lançar uma solução VOIP sem esses controles básicos. Alternativamente, pode haver um pacote Flutter que permite mexer nas sessões de áudio do Dart. Não investiguei isso porque meus aplicativos já estão indo e voltando do Flutter e do nativo, tornando esta uma solução rápida para mim.

hi, did you find any solution for iOS?

yusuf-umarr commented 1 year ago
  void _handelStreams(CallState event) async {
    MediaStream stream = event.stream;
    if (event.originator == 'local') {
      if (_localRenderer != null) {
        _localRenderer.srcObject = stream;
      }
      if (!kIsWeb) {
        event.stream?.getAudioTracks()?.first?.enableSpeakerphone(false);
      }
      _localStream = stream;
    }
    if (event.originator == 'remote') {
      if (_remoteRenderer != null) {
        _remoteRenderer.srcObject = stream;
      }
      _remoteStream = stream;
    }

    this.setState(() {
      _resizeLocalVideo();
    });
  }

This can help you

hi, i am currently facing this issue and please where should i call this above method "_handelStreams" thanks