VoiceChat

AkiraHiro
edited February 2015 in Photon Voice
I'm a bit new to most of coding in C#, there's quite a few things I don't quite know yet, so sorry if I'm a bit of a noob.
I also don't really know how to accurately search this site for other posts similar to what I'm wanting to know, so sorry if this has already been posted.

I would like to ask what kind of code I'd use to send a Byte Array over the Photon Network, and maybe a few other questions relating to if I setup an asset called VoiceChat through the Photon Network correctly. I'm using Photon Cloud, and making a simple FPS game on Unity3D for Web Players, and my biggest problem is I don't know what code to use, or where to put it to send these to the other players using PUN Cloud:
public VoiceChatCompression Compression;
public int Length;
public byte[] Data;
public int NetworkId;

Answers

  • Hello AkiraHiro,

    I would suggest you to try out the demo scenes that come with PUN (or PUN+) so that you get's the basic around Photon, I would say it's a must. Basically, to send a buffer array or anything else, usually you do that through an RPC call. Here is the simplest code sample:
    // SENDER SIDE
    byte[] dummy = new byte[100];
    // TODO: fill the buffer with your data
    // GamePhotonView is a PhotonView instance, in my case owned by the scene.
    // PlayerTarget is an PhotonPlayer instance.
    GamePhotonView.RPC("SyncPlayerData", PlayerTarget, dummy);
    
    // RECEIVER SIDE
    [RPC]
    public void SyncPlayerData(byte[] data)
    {
    //TODO: do whatever you want with the data
    }
    

    Hope this helps a bit.

    Good luck!

    Don T.
  • dontonka wrote:
    Hello AkiraHiro,

    I would suggest you to try out the demo scenes that come with PUN (or PUN+) so that you get's the basic around Photon, I would say it's a must. Basically, to send a buffer array or anything else, usually you do that through an RPC call. Here is the simplest code sample:
    // SENDER SIDE
    byte[] dummy = new byte[100];
    // TODO: fill the buffer with your data
    // GamePhotonView is a PhotonView instance, in my case owned by the scene.
    // PlayerTarget is an PhotonPlayer instance.
    GamePhotonView.RPC("SyncPlayerData", PlayerTarget, dummy);
    
    // RECEIVER SIDE
    [RPC]
    public void SyncPlayerData(byte[] data)
    {
    //TODO: do whatever you want with the data
    }
    

    Hope this helps a bit.

    Good luck!

    Don T.

    Not sure if that code works alone, or if I need to add "VoiceChat" somewhere in there. (I'm guessing to replace "dummy"? Also don't know if I need to replace "PlayerTarget" with some specific, though if I do, then I don't really know what. x_x) Otherwise thanks, and I'll try the demos soon. (Gotta re-download them, because I deleted them on instructions of a tutorial from a person that gave precise instructions, and didn't need them. Though he wasn't installing VoiceChat so yeah. lol)


    Edit: Just watched a part in the tutorial about RPCs, and it showed PlayerTargets.All in use, so I at least understand that a bit better now.
  • Hello AkiraHiro.

    No no that code would not work alone, you need to replace with your own PhotonView instance etc, but the idea is there. BTW, there is two method for the RPC, one is by specifying a PhotonPlayer (which I used in my example, called PlayerTarget, which can be misleading with PhotonTargets, sorry)

    Have a look at the doc here:
    http://doc-api.exitgames.com/en/pun/current/pun/doc/class_photon_view.html

    BTW, which VoiceChat solution are you using :), I'm curious?

    Regards,
    Don T.
  • Alright I think I got it... I'm guessing I make a new script, and add the above code to it, but is there any kind of code I need to add to reference to the VoiceChat scripts? Also I'm using the third party solution.
  • Hello AkiraHiro,
    Also I'm using the third party solution.
    Indeed, what is the 3rd party solution you are using for voice chat? If you tell me that, maybe I can help a little bit further :).

    Basically, depending on that voice solution that you have, you will need to integrate it in a certain way with Photon. That voice chat solution should take care of recording voice data, and at least allow you to play it back on the receive side. I assume you will need to integrate Photon in the middle to send the recording data over the network to others players, as I mention by using RPC call as I shown you before.

    Regards,
    Don T.
  • https://drive.google.com/file/d/0BzdY5vC0Sj8XMm41TDFtTkhXd0U/view?usp=sharing I'm assuming this is what you mean, though to be honest I'm still completely confused about most of this. x_x
  • Fixed the link ^
    Also I've been studying a bit more of the basics, so hopefully I know enough to finally understand this, and get this done. x_x I hope.
  • yep the link was broken :). ok so good luck with this AkiraHiro. but from the link it still not clear what is this VoiceChat 3rd party solution you are using, is it on Unity Asset Store, if so what's the name of the product?

    thanks,
    Don T.
  • Oh! That's what you meant. Yeah it's from the Asset Store, and it's called Voice Chat. (That's literally the name)
  • I'm having the same problem, not sure how to implement VoiceChat with Photon. Voicechat's Documentation only gives a high level overview and I'm having problems trying to implement it with Photon. Here is the documentation:

    The second thing we want to do is to transmit our audio to the other clients, this is done by attaching
    an event listener to the VoiceChatRecorder.Instance.NewSample event, the event has one argument
    which is a struct of the type VoiceChatPacket, which looks like this:
    
    public struct VoiceChatPacket
    {
     public VoiceChatCompression Compression;
     public int Length;
     public byte[] Data;
     public int NetworkId;
    }
    
    This struct needs to be transmitted to all other players, how this is done is specific to your
    networking solution. All fields in this struct needs to be transmitted, the part of the Data byte array
    that needs to be sent is from index 0 and the amount of elements is the same as the Length property.


    Did anyone get this working with Photon? How do I setup the event listener and transmit the Struct VoiceChatPacket to other players? I've been through the tutorials and understand how to use RPC calls etc.

    Thanks for any help.
  • I wrote a custom serializer for VoiceChatPacket, which then can be used in RPC calls.

    VoiceChatPacketPhotonType.cs:
    using UnityEngine;
    using System;
    using System.IO;
    using ExitGames.Client.Photon;
    using VoiceChat;
    
    public class VoiceChatPacketPhotonType
    {
    	public static void Register()
    	{
    		PhotonPeer.RegisterType(typeof(VoiceChatPacket), (byte)'C', SerializeVoiceChatPacket, DeserializeVoiceChatPacket);
    	}
    
    	public static readonly byte[] memVoiceChatPacket = new byte[4 + 2 + 4];
    	private static short SerializeVoiceChatPacket(MemoryStream outStream, object customobject)
    	{
    		VoiceChatPacket vcp = (VoiceChatPacket)customobject;
    		int index = 0;
    		lock (memVoiceChatPacket)
    		{
    			byte[] bytes = memVoiceChatPacket;
    			Protocol.Serialize(vcp.NetworkId, bytes, ref index);
    			Protocol.Serialize((Int16)vcp.Compression, bytes, ref index);
    			Protocol.Serialize(vcp.Length, bytes, ref index);
    			outStream.Write(bytes, 0, 4 + 2 + 4);
    			outStream.Write(vcp.Data, 0, vcp.Length);
    		}
    		return (short)(4 + 2 + 4 + vcp.Length);
    	}
    
    	private static object DeserializeVoiceChatPacket(MemoryStream inStream, short length)
    	{
    		VoiceChatPacket vcp = new VoiceChatPacket();
    		lock (memVoiceChatPacket)
    		{
    			inStream.Read(memVoiceChatPacket, 0, 4 + 2 + 4);
    			int index = 0;
    			Protocol.Deserialize(out vcp.NetworkId, memVoiceChatPacket, ref index);
    			Int16 Compression;
    			Protocol.Deserialize(out Compression, memVoiceChatPacket, ref index);
    			vcp.Compression = (VoiceChatCompression)Compression;
    			Protocol.Deserialize(out vcp.Length, memVoiceChatPacket, ref index);
    			byte[] bytes = new byte[vcp.Length];
    			inStream.Read(bytes, 0, vcp.Length);
    			vcp.Data = bytes;
    		}
    		return vcp;
    	}
    
    }
    
    Note: Just make sure to call VoiceChatPacketPhotonType.Register() during initialization before you use it.

    Good luck!

    Peter