This document is about: VOICE 1

Photon Voice 1 is the original and first major version of Photon Voice. It is now replaced by Photon Voice 2 which is refactored and enhanced. We highly recommend starting new projects with Photon Voice 2 and if possible migrating existing ones from Photon Voice 1 to Photon Voice 2. Photon Voice will be maintained for the coming months. We will fix important bugs and support new Unity versions but new features will be added only to Photon Voice 2.

PUN Voice Push To Talk Demo

The Push To Talk demo scene showcases how to achieve:

  • Push-to-Talk feature.
  • Private Voice Chat.

In this document we will describe each feature and how you can use it.

pun voice ptt demo screenshot
PUN Voice Push-To-Talk demo running

Push-to-Talk Mode

To transmit voice on demand:

  • set PhotonVoiceSettings.AutoTransmit to false.
  • when you want to start transmission set PhotonVoiceRecorder.Transmit to true.
  • to stop transmission set it back to false.

In the demo we bind keyboard keys ('v' for broadcast and numeric keys corresponding to joined actors' numbers) and UI buttons ("TalkToAll" for broadcast, "TalkToX" per joined actor number 'X') to Push-to-Talk groups and use PushToTalkOn and PushToTalkOff methods.

Interest Groups Usage Demystified

Photon Voice uses Photon Realtime's "Interest Groups" to separate mutually exclusive "voice channels" belonging to different "voice conversations".

Select "Who To Listen To"

Each actor needs to subscribe to interest groups it's interested in. By default, all actors listen to interest group 0 which could be seen as a global interest group for voice broadcast. If you want to listen to voice sent to other groups you need to subscribe to those groups. You can also unsubscribe from previously subscribed ones. The operation to do all this is:


PhotonVoiceNetwork.Client.ChangeAudioGroups(groupsToRemove, groupsToAdd);

Select "Who To Talk To"

Each actor needs to decide to which interest group it wants to transmit audio to. The target interest group can be set using:


photonVoiceRecorder.AudioGroup = targetGroup;

Use Cases

In all cases, you always listen to default interest group 0 and you can transmit voice to a single interest group at the same time per PhotonVoiceRecorder component. Use cases could be grouped into three different categories:

1. Single Global Group

If you use one single group, at a time, to transmit voice to in all clients and all PhotonVoiceRecorder components, there is a shortcut to set or switch this global group:


PhotonVoiceNetwork.Client.GlobalAudioGroup = targetGroup;

In this case no need to call ChangeAudioGroups or set PhotonVoiceRecorder.AudioGroup as it's done internally for you.


  • If targetGroup is equal to 0 then you have the default behaviour. No need to explicitly set it as a global group unless you changed something and want to reset setup.
  • If targetGroup is not equal to 0 then you can still receive voice streams transmitted to that same group.
  • All PhotonVoiceRecorder components transmitting will use the same globally set target group in this case.

2. Listen To A Single Group

This is not the same as the previous category as it allows the following:

  • Set a different target group per PhotonVoiceRecorder.
  • The group to listen to can be different from the group to talk to.
A. Default Group


// unsubscribe from all groups, this is optional if groups were not changed before
PhotonVoiceNetwork.Client.ChangeAudioGroups(new byte[0], null);

// set target interest group
photonVoiceRecorder.AudioGroup = targetGroup;
B. Other Group


// subscribe to the group to listen to
PhotonVoiceNetwork.Client.ChangeAudioGroups(new byte[0], new byte[1] { groupToListenTo });

// set target interest group
photonVoiceRecorder.AudioGroup = targetGroup;

3. Listen To Multiple Groups

A. Listen To All Pre-Existing Groups


// subscribe to all pre-existing groups
PhotonVoiceNetwork.Client.ChangeAudioGroups(null, new byte[0]);

// set target interest group
photonVoiceRecorder.AudioGroup = targetGroup;

Later, you may need to subscribe to groups created after this call.

B. Listen To A List Of Groups


// subscribe to a custom list of groups
PhotonVoiceNetwork.Client.ChangeAudioGroups(new byte[0], groupsToListenTo);

// set target interest group
photonVoiceRecorder.AudioGroup = targetGroup;

You can speak to a group other than those you listen to. i.e. groupsToListenTo could not contain targetGroup.

C. Listen To All Possible Groups

This should be used carefully as it may subscribe the client to groups that will never be used.


using System;
using System.Linq;
// [...]
byte[] allByteValues = Enumerable.Range(1, 255).SelectMany(BitConverter.GetBytes).ToArray(); 

// subscribe to all possible groups
PhotonVoiceNetwork.Client.ChangeAudioGroups(null, allByteValues);

// set target interest group
photonVoiceRecorder.AudioGroup = targetGroup;

How We Use Audio Groups In The Demo

The Photon Voice Push-to-Talk demo offers two options for voice chat:

  • "MuteOthers" enabled: corresponds to case n°3.A (above). When PushToTalkScript.MuteOthersWhileTalking is equal to true we call PushToTalkScript.KeepOnlyOneGroup((byte)CurrentTargetGroup);.
  • "MuteOthers" disabled: corresponds to case n°2 (above). When PushToTalkScript.MuteOthersWhileTalking is equal to false we call PushToTalkScript.SubscribeToAllPrivateGroups();.

The "MuteOthers" mode could be changed on the fly at any time using a UI toggle.

The audio groups in the demo are designed this way:

  • We have rooms of 4 actors.
  • We use default group 0 as target audio group for broadcast.
  • We need 6 custom private audio groups: for each pair of actors we calculate a unique group code.
  • When the local actor joins the room it subscribes to the audio groups of the previously joined ones.
  • When a new remote actor joins the room the local actor subscribes to the corresponding audio group. See PushToTalkScript.OnPhotonPlayerConnected.
  • When a remote actor leaves the room the local actor unsubscribes from the corresponding audio group. See PushToTalkScript.OnPhotonPlayerDisonnected.
  • Here is how we get the audio group of private voice chat between two players (local and remote):


// snippet from PushToTalkPrivateButton.SetAudioGroup
if (PhotonNetwork.player.ID < TargetActorNr)
    // note: actor numbers should not reach 25
    AudioGroup = (byte) (TargetActorNr + PhotonNetwork.player.ID * 10);
else if (PhotonNetwork.player.ID > TargetActorNr)
    AudioGroup = (byte) (PhotonNetwork.player.ID + TargetActorNr * 10);

Example: The audio group for actors 1 and 2 is 12.

Another Variant

Another possible approach of "calculating" private voice groups is to use the actor number as audio group:

  • Each actor subscribes to a single audio group with a code equal to its actor number.
  • Whenever you want to talk to a remote actor you set the target audio group (using PhotonVoiceRecorder.AudioGroup only) to the target actor number.


  • Less audio groups: we need as many audio groups as actors.
  • Less audio groups switching: single audio group to subscribe to and no unsubscribing.


  • You can't mute any other actor. You will listen to anyone who wants to talk to you privately.
Back to top