如何视频会议/呼叫C#TCP

时间:2018-09-08 15:06:11

标签: c# winforms audio tcp video-streaming

首先,我会说我已经厌倦了对此的搜索,最后决定提出这个问题。
好的,首先背景知识
我曾经团结一致地工作,不得不进行视频通话这个应用程序,并在暑假中度过了大部分时间,这些简单的事情很简单,例如网络摄像头和麦克风课,因此不必担心,但由于线程化不是统一的理想选择。错误开始像DLL问题一样出现,并在Texture2D(2D图像)上崩溃,UI的工作使我感到无聊,所以我决定挂断它,并考虑迁移到xamarin,然后才想在Winforms上制作该应用程序,因为毕竟服务器应用将在Windows上,客户端将在移动设备上。不是P2P。

我到目前为止所做的事情
我猜是C#没有WebCam类,
统一

  • 使用Opus.net(github)编码NAudio的音频并通过网络发送而没有任何缓冲区(最大字节大小限制为350),无需了解任何部分,因此如果我无法学习,无论如何如果有人的话,都没有用决定解释然后发表评论。
  • 每10秒钟左右获取网络摄像头的图像,然后不进行编码就从Texture2D类获取该图像的JPG并将其发送到服务器。
  • 最好的发送和接收方法之一(将在下面发布代码)
  • 音频停止缓冲并且网络摄像头的框架还可以。
  • 即使线程并不是最好的套件,但我在接收和发送字节时几乎完美地使用了线程(服务器为每个客户端启动新线程除外)。

问题/我想要什么

  • 使用C#winforms可获得更好的结果,现在我可以更自由地使用DLL了。
  • 服务器在处理客户端方面不是最好的(现在不是此问题的优先级)。
  • 需要有人向我解释我听不懂的音频部分。
  • 由于图像大小太大(例如超过1500个左右,最多30000个),
  • ,如何获得网络摄像头以及将数据传输到电线另一端的有效方法>

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循环中将returncontinue替换为//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; }

0 个答案:

没有答案