首先,我会说我已经厌倦了对此的搜索,最后决定提出这个问题。
好的,首先背景知识
我曾经团结一致地工作,不得不进行视频通话这个应用程序,并在暑假中度过了大部分时间,这些简单的事情很简单,例如网络摄像头和麦克风课,因此不必担心,但由于线程化不是统一的理想选择。错误开始像DLL问题一样出现,并在Texture2D(2D图像)上崩溃,UI的工作使我感到无聊,所以我决定挂断它,并考虑迁移到xamarin,然后才想在Winforms上制作该应用程序,因为毕竟服务器应用将在Windows上,客户端将在移动设备上。不是P2P。
我到目前为止所做的事情
我猜是C#没有WebCam类,
统一
问题/我想要什么
TLDR; :如何获取网络摄像头以及如何完全像对图像进行编码并发送一样?图书馆?我发现的大多数编码器都是C ++的,因此,特别是在发送网络摄像头图像时没有用。
代码 我不了解的部分(SendToServer();方法是我的):
/// <summary>
/// Formula : Sample Rate / 1000 * FrameSize
/// </summary>
int _segmentFrames;
byte[] soundBuffer = new byte[e.BytesRecorded + _notEncodedBuffer.Length];
for (int i = 0; i < _notEncodedBuffer.Length; i++)
soundBuffer[i] = _notEncodedBuffer[i];
for (int i = 0; i < e.BytesRecorded; i++)
soundBuffer[i + _notEncodedBuffer.Length] = e.Buffer[i];
int byteCap = _bytesPerSegment;
int segmentCount = (int)Math.Floor((decimal)soundBuffer.Length / byteCap);
int segmentsEnd = segmentCount * byteCap;
int notEncodedCount = soundBuffer.Length - segmentsEnd;
_notEncodedBuffer = new byte[notEncodedCount];
for (int i = 0; i < notEncodedCount; i++)
{
_notEncodedBuffer[i] = soundBuffer[segmentsEnd + i];
}
for (int i = 0; i < segmentCount; i++)
{
byte[] segment = new byte[byteCap];
for (int j = 0; j < segment.Length; j++)
segment[j] = soundBuffer[(i * byteCap) + j];
int len;
byte[] buff = _encoder.Encode(segment, segment.Length, out len);
_bytesSent += (ulong)len;
SendToServer(buff, len);
}
发送/接收两者几乎相同,如果统一,则在更新方法中。如果在接收线程中,则在true循环中将return
和continue
替换为//Receive
//if signaled to stop then stop
if (_resetEvent.WaitOne(1)) return;
//if not connected to the server then wait
if (!_socketReady) return;
//if no data is available to receive then wait
if (!_stream.DataAvailable) return;
//get message type
byte[] messageType = new byte[sizeof(int)];
int recv = _stream.Read(messageType, 0, messageType.Length);
Message type = MessageTypes.FindType(messageType);
//if we do not expect more data then our work here is done
if (!type.HasCustomData) { ReceivedDataReplyHandler(type); return; }
//Get the length of the message we expect
byte[] lenBuff = new byte[sizeof(int)];
recv = _stream.Read(lenBuff, 0, lenBuff.Length);
//Get the length in integer
int messagelen = BitConverter.ToInt32(lenBuff, 0);
//Gte the message we expected
byte[] messageBuff = new byte[messagelen];
recv = _stream.Read(messageBuff, 0, messageBuff.Length);
//bind the received data
type.MessageData = messageBuff;
//handle with the received Data
ReceivedDataReplyHandler(type);
public void Send(MessageNames messageName, byte[] data)
{
Message type = MessageTypes.FindType(messageName);
if (!type.HasCustomData) { print("This type do not have custom data plz use the other method!"); }
byte[] message = data;
byte[] length = BitConverter.GetBytes(message.Length);
byte[] buffer = new byte[sizeof(int) + message.Length + sizeof(int)];
//Copy the length of the data
Array.Copy(BitConverter.GetBytes(type.Value), 0, buffer, 0, sizeof(int));
//Copy the length of the data
Array.Copy(length, 0, buffer, sizeof(int), sizeof(int));
//Copy the data
Array.Copy(message, 0, buffer, sizeof(int) + sizeof(int), message.Length);
//Send the data to the server
_stream.Write(buffer, 0, buffer.Length);
}
主要。
Message
public bool HasCustomData { get; private set; }
public int Value { get; private set; }
public MessageNames Name { get; private set; }
//Only for Client (When receiving message from Server), gets the actual bytes data
public byte[] MessageData { get; set; }
// ONLY FOR SERVER (When receiving message from Client), gets the client from whome the message is received
public ServerClient SentFromClient { get; set; }
public Message(bool HasCustomData, int Value, MessageNames Name)
{
this.HasCustomData = HasCustomData;
this.Value = Value;
this.Name = Name;
}
类
MessageTypes
private static List<Message> TypesofMessages = new List<Message>()
{
new Message(true, 1,MessageNames.Microphone),
new Message(true, 2,MessageNames.Webcam),
new Message(true, 3,MessageNames.Connection),
new Message(true, 4,MessageNames.Message),
new Message(true, 5,MessageNames.PlayerAddition),
new Message(false, 6,MessageNames.HangUp),
new Message(false, 7,MessageNames.Confirm),
new Message(true, 8,MessageNames.VideoCall),
new Message(true, 9,MessageNames.VoiceCall)
};
public static bool Compare(Message x, Message y)
{
return x.Value == y.Value && x.Name == y.Name;
}
public static Message FindType(byte[] value)
{
return TypesofMessages.First(m => m.Value == BitConverter.ToInt32(value, 0));
}
public static Message FindType(MessageNames name)
{
return TypesofMessages.First(m => m.Name == name);
}
结构(可能会更好):
nav { position: sticky; top: 0px; }