有没有任何方法可以使用Photon Pun2或Photon Chat发送或接收图像、音频和视频



我在应用程序中同时使用Photon Pun2和Photon Chat两个包。但我找不到任何方式通过私人信息发送或接收图像、音频或视频。

是的。。。然而,它是相当有限的。

你要寄的东西到底有多大?


聊天

光子聊天消息的有效载荷限制在400000到5000000字节之间。我没有更详细地测试它,但如果你的消息大小达到一定的限制,你会立即断开连接,没有适当的反馈,原因是^^

参见Photon聊天介绍

示例

public class MyChatListner : IChatClientListener
{
public event Action<byte[]> OnReceived;
private ChatClient cient;
public void Initialize()
{
client = new ChatClient(this);

client.ChatRegion = ...;
client.Connect(....);
}

// Sicne you already work with the chat you should know but anyway
// This has to be called continuously (who knows in what intervals)
public void Heartbeat()
{
client.Service();
}
public void SendData(string recipient, byte[] data)
{
client.SendPrivateMessage(recipient, data);
}
public void OnPrivateMessage(string sender, object message, string channelName)
{
OnReceived?.Invoke((byte[])message);
}

// also will have to implement the other methods from IChatClientListener ...
}

PUN2

在Pun2中,我不知道是否存在这样的限制,但它肯定会延迟其他一切,直到文件完全收到。在这里,您可以通过PhotonNetwork.RaiseEventOnEvent(通过接口IOnEventCallback(直接发送和接收byte[]

示例

// doesn't even have to be monobehaviour necessarily
public class FileTransmitter : IOnEventCallback
{
private const byte eventID = 42;
public event Action<byte[]> OnReceived;
public void Enable()
{
PhotonNetwork.AddCallbackTarget(this);
}
public void Disable()
{
PhotonNetwork.RemoveCallbackTarget(this);
}
public void SendData(byte[] data, SendOptions sendoptions, RaiseEventOptions raiseEventOptions = null)
{
PhotonNetwork.RaiseEvent(eventID, data, raiseEventOptions, sendoptions);
}
public void OnEvent(EventData photonEvent)
{
if(photonEvent.Code != eventID) return;
var data = (byte[]) photonEvent.CustomData;
OnReceived?.Invoke(data);
}
}

或者,您当然也可以直接使用RPC,并使用例如

public class FileTransfer : MonoBehaviourPun
{
[PunRPC]
void ChatMessage(string fileName, byte[] content)
{
// e.g.
File.WriteAllBytes(Path.Combine(Application.persistentDataPath, fileName), content);
}
public void SendFile(string fileName, byte[] content, PhotonPlayer targetPlayer)
{
photonView.RPC(nameof(ChatMessage), targetPlayer, fileName, content);
}
}

无论哪种方式,我个人所做的都是只使用一个byte[],并将所有所需信息编码到其中。Photon无论如何都会使用所有参数来完成这项工作,但如果你已经确切地知道你发送了什么数据以及如何反序列化它,那么自己完成这项任务会更高效,例如在线程/任务中。然后在接收方,我再次将这些信息反序列化为单独的信息。

这是可能的,而且工作得很好(尽管你应该像@derHugo所说的那样注意极限(。我的实现使用RPC使用Texture2D.EncodeToPNG发送一个字节数组,然后在收到后在客户端上对其进行解码。

要将字节数组转换回图像,可以使用Texture2D.LoadImage方法。

发送其他多媒体类型的方法类似,只是编码/解码方法不同。

PhotonStream允许您通过网络流式传输任何byte[]数据。理论上,任何数据类型都可以转换为byte[],并在接收器端对其进行解码。


下面的示例脚本只是一个设置最少的示例。参考来源:https://frozenmist.com/docs/apis/fmetp-stream/pun2-example/

还可以使用流行的第三方插件(如FMETP stream(实时流式传输视频、音频和远程命令,该插件具有本地快速编码器,可实时捕捉游戏视图和桌面视图,甚至与移动和VR设备兼容。

using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// ref: https://frozenmist.com/docs/apis/fmetp-stream/pun2-example/
public class FMStreamPUN : Photon.Pun.MonoBehaviourPun, IPunObservable {
private Queue<byte[]> appendQueueSendData = new Queue<byte[]>();
public int appendQueueSendDataCount { get { return appendQueueSendData.Count; } }
public UnityEventByteArray OnDataByteReadyEvent = new UnityEventByteArray();
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) {
if (stream.IsWriting) {
//Send the meta data of the byte[] queue length
stream.SendNext(appendQueueSendDataCount);
//Sending the queued byte[]
while(appendQueueSendDataCount > 0) {
byte[] sentData = appendQueueSendData.Dequeue();
stream.SendNext(sentData);
}
}
if (stream.IsReading) {
if (!photonView.IsMine) {
//Get the queue length
int streamCount = (int)stream.ReceiveNext();
for (int i = 0; i < streamCount; i++) {
//reading stream one by one
byte[] receivedData = (byte[])stream.ReceiveNext();
OnDataByteReadyEvent.Invoke(receivedData);
}
}
}
}
public void Action_SendData(byte[] inputData) {
//inputData(byte[]) is the encoded byte[] from your encoder
//doesn't require any stream, when there is only one player in the room
if(PhotonNetwork.CurrentRoom.PlayerCount > 1) appendQueueSendData.Enqueue(inputData);
}
}

最新更新