基于TCP协议实现视频采集与通信

一、系统架构设计

graph TD A[摄像头硬件] --> B[视频采集模块] B --> C[视频编码模块] C --> D[TCP服务器模块] D --> E[网络传输层] E --> F[客户端管理模块] F --> G[视频解码模块] G --> H[显示与控制终端]

二、核心模块实现

1. 视频采集模块(C# + OpenCV)

using OpenCvSharp;

public class VideoCaptureManager : IDisposable
{
    private VideoCapture _capture;
    private Mat _frameBuffer = new Mat();

    public VideoCaptureManager(int cameraIndex = 0)
    {
        _capture = new VideoCapture(cameraIndex);
        if (!_capture.IsOpened())
            throw new InvalidOperationException("无法打开摄像头");
        
        _capture.FrameWidth = 1280;
        _capture.FrameHeight = 720;
        _capture.FPS = 30;
    }

    public bool ReadFrame(out Mat frame)
    {
        return _capture.Read(out frame) && !frame.Empty();
    }

    public void Dispose()
    {
        _capture?.Release();
    }
}

2. 视频编码模块(H.264压缩)

using Accord.Video.FFMPEG;

public class VideoEncoder
{
    private AVCodecContext _encoder;
    private AVFrame _frame;
    private AVPacket _packet;

    public VideoEncoder(int width, int height, int fps)
    {
        _encoder = new AVCodecContext();
        _encoder.CodecId = AVCodecID.AV_CODEC_ID_H264;
        _encoder.Width = width;
        _encoder.Height = height;
        _encoder.TimeBase = new AVRational { Num = 1, Den = fps };
        _encoder.Framerate = new AVRational { Num = fps, Den = 1 };
        
        avcodec_open2(_encoder, avcodec_find_encoder(_encoder.CodecId), null);
        
        _frame = av_frame_alloc();
        _packet = av_packet_alloc();
    }

    public byte[] Encode(Mat frame)
    {
        // YUV420P格式转换
        var yuvFrame = new Mat();
        Cv2.CvtColor(frame, yuvFrame, ColorConversionCodes.BGR2YUV_I420);

        // 填充AVFrame数据
        unsafe
        {
            fixed (byte* src = yuvFrame.DataPointer)
            {
                _frame.Data[0] = src;
                _frame.Data[1] = src + (int)(yuvFrame.Height * yuvFrame.Width);
                _frame.Data[2] = src + (int)(yuvFrame.Height * yuvFrame.Width * 5 / 4);
            }
        }

        // 编码处理
        avcodec_send_frame(_encoder, _frame);
        avcodec_receive_packet(_encoder, _packet);

        byte[] encodedData = new byte[_packet.Size];
        Marshal.Copy(_packet.Data, encodedData, 0, _packet.Size);

        av_packet_unref(_packet);
        return encodedData;
    }
}

3. TCP服务器模块(支持多客户端)

using System.Net.Sockets;
using System.Threading.Tasks;

public class TcpVideoServer
{
    private TcpListener _listener;
    private ConcurrentDictionary<TcpClient, ClientSession> _clients = new();

    public async Task StartAsync(string ipAddress, int port)
    {
        _listener = new TcpListener(IPAddress.Parse(ipAddress), port);
        _listener.Start();
        
        while (true)
        {
            var client = await _listener.AcceptTcpClientAsync();
            _ = HandleClientAsync(client);
        }
    }

    private async Task HandleClientAsync(TcpClient client)
    {
        var session = new ClientSession(client);
        _clients.TryAdd(client, session);

        try
        {
            await session.ProcessVideoStreamAsync();
        }
        finally
        {
            _clients.TryRemove(client, out _);
            client.Close();
        }
    }
}

public class ClientSession
{
    private TcpClient _client;
    private NetworkStream _stream;
    private byte[] _buffer = new byte[1024 * 1024];

    public ClientSession(TcpClient client)
    {
        _client = client;
        _stream = client.GetStream();
    }

    public async Task ProcessVideoStreamAsync()
    {
        while (_client.Connected)
        {
            int bytesRead = await _stream.ReadAsync(_buffer, 0, _buffer.Length);
            if (bytesRead == 0) break;

            // 处理接收到的视频数据
            await HandleVideoData(_buffer, bytesRead);
        }
    }
}

三、关键技术创新

1. 自适应码率控制

public class RateController
{
    private int _targetBitrate = 2000; // kbps
    private int _currentBitrate = 2000;
    
    public void AdjustBitrate(double networkQuality)
    {
        _currentBitrate = (int)(_targetBitrate * networkQuality);
        _encoder.SetBitRate(_currentBitrate * 1000);
    }
}

2. 帧同步机制

public class FrameSync
{
    private long _lastPts = 0;
    
    public bool CheckFrameSync(long pts)
    {
        if (Math.Abs(pts - _lastPts - 33333) > 10000) // 30fps对应33ms间隔
            return false;
        
        _lastPts = pts;
        return true;
    }
}

四、客户端实现方案

1. 视频接收与解码

public class VideoPlayer
{
    private AVCodecContext _decoder;
    private AVFrame _frame;
    
    public VideoPlayer()
    {
        _decoder = avcodec_find_decoder(AVCodecID.AV_CODEC_ID_H264);
        avcodec_open2(_decoder, null, null);
        _frame = av_frame_alloc();
    }

    public Mat Decode(byte[] encodedData)
    {
        unsafe
        {
            fixed (byte* src = encodedData)
            {
                _decoder.SendPacket(new AVPacket { Data = src, Size = encodedData.Length });
                avcodec_receive_frame(_decoder, _frame);
            }
        }

        Mat mat = new Mat(_frame.Height, _frame.Width, MatType.CV_8UC3);
        unsafe
        {
            byte* dst = (byte*)mat.DataPointer;
            for (int y = 0; y < _frame.Height; y++)
            {
                System.Runtime.InteropServices.Marshal.Copy(
                    (IntPtr)(_frame.Data[0] + y * _frame.Width),
                    dst,
                    0,
                    _frame.Width);
                dst += _frame.Width;
            }
        }
        return mat;
    }
}

2. 播放控制界面

public partial class VideoForm : Form
{
    private VideoPlayer _player;
    private Timer _renderTimer = new Timer(33); // ~30fps

    public VideoForm()
    {
        InitializeComponent();
        _player = new VideoPlayer();
        _renderTimer.Tick += RenderFrame;
    }

    private void RenderFrame(object sender, EventArgs e)
    {
        if (_latestFrame != null)
        {
            pictureBox1.Image = _latestFrame.ToBitmap();
            _latestFrame.Dispose();
        }
    }

    public async Task ReceiveVideoAsync(TcpClient client)
    {
        using (var stream = client.GetStream())
        {
            while (client.Connected)
            {
                byte[] buffer = new byte[1024 * 1024];
                int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
                if (bytesRead > 0)
                {
                    _latestFrame = _player.Decode(buffer);
                }
            }
        }
    }
}

五、性能优化

  1. 零拷贝技术

    // 使用MemoryMappedFile实现零拷贝传输
    using (var mmf = MemoryMappedFile.CreateFromFile("video.dat", FileMode.Open))
    {
        var accessor = mmf.CreateViewAccessor();
        unsafe
        {
            byte* src = (byte*)accessor.SafeMemoryMappedViewHandle.DangerousGetHandle();
            avcodec_send_frame(_decoder, new AVFrame { Data = src });
        }
    }
    
  2. 多线程渲染

    private void StartRenderThread()
    {
        _renderThread = new Thread(() =>
        {
            while (!_stopFlag)
            {
                if (_frameQueue.TryDequeue(out var frame))
                {
                    pictureBox1.Invoke((Action)(() => pictureBox1.Image = frame.ToBitmap()));
                }
            }
        });
        _renderThread.Start();
    }
    

参考代码 采用TCP协议实现视频采集和通信 开发平台 www.youwenfan.com/contentcnr/112706.html

六、完整部署方案

组件 推荐配置 说明
摄像头 Basler ace2 4K 支持1080p@60fps
网络设备 千兆工业交换机 支持组播/广播
服务器 i7-12700K/32GB/SSD 支持10路1080p视频流
客户端 i5-10400/8GB/WiFi6 支持4路视频同步解码

七、测试与调试工具

  1. 网络抓包分析

    # 使用Wireshark过滤TCP视频流
    tcp.port == 554 || tcp.port == 8554
    
  2. 性能监控仪表盘

    public class PerformanceMonitor
    {
        private PerformanceCounter _cpuCounter = new PerformanceCounter("Processor", "% Processor Time");
        private PerformanceCounter _netCounter = new PerformanceCounter("Network Interface", "Bytes Received");
    
        public void UpdateMetrics()
        {
            float cpuUsage = _cpuCounter.NextValue();
            long networkTraffic = (long)_netCounter.NextValue();
    
            Console.WriteLine($"CPU: {cpuUsage:F1}% | 网络流量: {networkTraffic / 1024} KB/s");
        }
    }
    

八、扩展功能实现

  1. 动态分辨率切换

    public void SwitchResolution(int width, int height)
    {
        _capture.FrameWidth = width;
        _capture.FrameHeight = height;
        _encoder.Reset(new AVCodecContext {
            Width = width,
            Height = height
        });
    }
    
  2. 安全传输增强

    // 使用AES加密视频流
    public byte[] EncryptFrame(byte[] data, byte[] key)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.GenerateIV();
    
            using (CryptoStream cs = new CryptoStream(
                new MemoryStream(), 
                aes.CreateEncryptor(), 
                CryptoStreamMode.Write))
            {
                cs.Write(data, 0, data.Length);
                cs.FlushFinalBlock();
                return cs.ToArray();
            }
        }
    }
    
posted @ 2026-02-10 11:26  小前端攻城狮  阅读(0)  评论(0)    收藏  举报