視頻協議解析 流媒體轉發與推流 前端自行挑選一個js player

H264行車記錄儀 視頻解析 用於監控

class Program
    {
        static void Main(string[] args)
        {
            try
            {

                Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = IPAddress.Any;
                IPEndPoint point = new IPEndPoint(ip, 3687);
                socketServer.Bind(point);
                socketServer.Listen(10);

                while (true)
                {
                    try
                    {
                        Socket socketClient = socketServer.Accept();
                        ThreadPool.QueueUserWorkItem(Receive, socketClient);

                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
            }
            catch (Exception e)
            {
            }
        }
        /// <summary>
        /// 截取包
        /// </summary>
        /// <param name="state"></param>
        public static void SubPack(EndPoint NowPoint)
        {
            try
            {
                //認爲存在完整包體
                int nowSub1078Index = dicSub[NowPoint].ToString().IndexOf("30316364");
                while (nowSub1078Index > -1)
                {
                    MsgModel m = new MsgModel();
                    m.imei = dicSub[NowPoint].ToString().Substring(nowSub1078Index + 16, 12);//卡號
                    m.channel = Convert.ToInt32(dicSub[NowPoint].ToString().Substring(nowSub1078Index + 28, 2), 16);//通道
                    m.dataType = Convert.ToInt32(dicSub[NowPoint].ToString().Substring(nowSub1078Index + 30, 1), 16);//數據類型
                    m.packMark = Convert.ToInt32(dicSub[NowPoint].ToString().Substring(nowSub1078Index + 31, 1), 16);//分包標識
                    string time = dicSub[NowPoint].ToString().Substring(nowSub1078Index + 32, 16);//時間戳
                    m.OfLastGJTime = Convert.ToInt32(dicSub[NowPoint].ToString().Substring(nowSub1078Index + 48, 4), 16);
                    m.OfLastTime = Convert.ToInt32(dicSub[NowPoint].ToString().Substring(nowSub1078Index + 52, 4), 16);
                    m.dataLength = Convert.ToInt32(dicSub[NowPoint].ToString().Substring(nowSub1078Index + 56, 4), 16);//包長度
                    m.data = dicSub[NowPoint].ToString().Substring(nowSub1078Index + 60, m.dataLength * 2);//H264數據

                    byte[] buffer = Comm.strToToHexByte(m.data);
                    if (!dicSubFFmpegPort.Keys.Contains(NowPoint))
                    {
                        int tempPort = new Random().Next(13688, 23688);
                        while (GetNextNoUsePort(tempPort))
                        {
                            tempPort = new Random().Next(13688, 23688);
                        }
                        Socket socketFFmpegServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        IPAddress ip = IPAddress.Any;
                        IPEndPoint point = new IPEndPoint(ip, tempPort);
                        socketFFmpegServer.Bind(point);
                        socketFFmpegServer.Listen(10);
                        ThreadPool.QueueUserWorkItem(Start, " -re -i tcp://192.168.0.19:" + tempPort + " -r 15 -an -f flv rtmp://192.168.0.19:1935/hls/" + m.imei + m.channel);
                        Socket socketClient = socketFFmpegServer.Accept();
                        dicSubFFmpegPort[NowPoint] = socketClient;
                    }
                    dicSubFFmpegPort[NowPoint].Send(buffer);
                    dicSub[NowPoint].Remove(0, nowSub1078Index + 60 + (m.dataLength * 2));
                    dicSubLastTime[NowPoint] = DateTime.Now;
                    nowSub1078Index = dicSub[NowPoint].ToString().IndexOf("30316364");
                }

                //檢查超時鏈接
                foreach (KeyValuePair<EndPoint, DateTime> temp in dicSubLastTime)
                {
                    if (temp.Value < DateTime.Now.AddMinutes(-10))
                    {
                        dicSub.Remove(temp.Key);
                        dicSubFFmpegPort.Remove(temp.Key);
                    }
                }
            }
            catch (Exception e)
            {
                //Console.WriteLine("SubPackError:" + e.Message);
            }
        }
        /// <summary>
        /// 端口是否佔用
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        private static bool GetNextNoUsePort(int port)
        {
            bool inUse = false;

            IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
            IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();

            foreach (IPEndPoint endPoint in ipEndPoints)
            {
                if (endPoint.Port == port)
                {
                    inUse = true;
                    break;
                }
            }
            return inUse;
        }
        static Dictionary<EndPoint, StringBuilder> dicSub = new Dictionary<EndPoint, StringBuilder>();
        static Dictionary<EndPoint, DateTime> dicSubLastTime = new Dictionary<EndPoint, DateTime>();
        static Dictionary<EndPoint, Socket> dicSubFFmpegPort = new Dictionary<EndPoint, Socket>();
        /// <summary>
        /// 接收單設備
        /// </summary>
        /// <param name="state"></param>
        public static void Receive(object state)
        {
            using (Socket socketClient = state as Socket)
            {
                try
                {
                    while (true)
                    {
                        byte[] buffer = new byte[1024];
                        int len = socketClient.Receive(buffer);
                        try
                        {

                            string msg = BitConverter.ToString(buffer).Replace("-", string.Empty).ToUpper();
                            if (dicSub.Keys.Contains(socketClient.RemoteEndPoint))
                            {
                                dicSub[socketClient.RemoteEndPoint].Append(msg);
                            }
                            else
                            {
                                int msg1078Index = msg.IndexOf("30316364");
                                if (msg1078Index > -1)
                                {
                                    dicSub[socketClient.RemoteEndPoint] = new StringBuilder(msg.Substring(msg1078Index));
                                }
                            }
                            if (dicSub[socketClient.RemoteEndPoint].ToString().IndexOf("30316364") > -1)
                            {
                                dicSubLastTime[socketClient.RemoteEndPoint] = DateTime.Now;
                                SubPack(socketClient.RemoteEndPoint);
                            }

                        }
                        catch (Exception e)
                        {
                            //Console.WriteLine(e.Message);
                        }
                    }
                }
                catch (Exception e)
                {

                }
                finally
                {
                    socketClient.Close();
                    socketClient.Dispose();
                }
            }
        }
        #region 直推所需
        // ffmpeg進程
        static Process process = new Process();
        // ffmpeg路徑
        const string FFmpegPath = @"D:\StreamData\ffmpeg-3.4.2-win64-static\bin\ffmpeg.exe";
        /// <summary>
        /// 開始
        /// </summary>
        public static void Start(object auguments)
        {
            Console.WriteLine(FFmpegPath + auguments);
            ProcessStartInfo startInfo = new ProcessStartInfo(FFmpegPath, auguments + "");
            startInfo.UseShellExecute = false;//必須不使用操作系統shell
            startInfo.RedirectStandardInput = true;//可能接受來自調用程序的輸入信息
            startInfo.RedirectStandardOutput = true;//由調用程序獲取輸出信息
            startInfo.CreateNoWindow = false;//不顯示程序窗口
            process.StartInfo = startInfo;
            process.Start();
        }

        /// <summary>
        /// 停止
        /// </summary>
        public static void Stop()
        {
            AttachConsole(process.Id);
            SetConsoleCtrlHandler(IntPtr.Zero, true);
            GenerateConsoleCtrlEvent(0, 0);
            FreeConsole();
            try
            {
                Process.GetProcessById(process.Id).Kill();
            }
            catch (Exception) { }
            
        }

        #region 模擬控制檯信號
        /// <summary>
        /// 附加到目標進程的console
        /// </summary>
        /// <param name="dwProcessId"></param>
        /// <returns></returns>
        [DllImport("kernel32.dll")]
        static extern bool AttachConsole(int dwProcessId);
        /// <summary>
        /// 設置自己的ctrl+c處理,防止自己被終止
        /// </summary>
        /// <param name="handlerRoutine"></param>
        /// <param name="add"></param>
        /// <returns></returns>
        [DllImport("kernel32.dll")]
        static extern bool SetConsoleCtrlHandler(IntPtr handlerRoutine, bool add);
        /// <summary>
        /// 發送ctrl+c(注意:這是向所有共享該console的進程發送)
        /// </summary>
        /// <param name="dwCtrlEvent"></param>
        /// <param name="dwProcessGroupId"></param>
        /// <returns></returns>
        [DllImport("kernel32.dll")]
        static extern bool GenerateConsoleCtrlEvent(int dwCtrlEvent, int dwProcessGroupId);
        /// <summary>
        /// 脫離目標console
        /// </summary>
        /// <returns></returns>
        [DllImport("kernel32.dll")]
        static extern bool FreeConsole();
        // 使用時
        //AttachConsole(processId); 
        //SetConsoleCtrlHandler(IntPtr.Zero, true); 
        //GenerateConsoleCtrlEvent(0, 0); 
        //FreeConsole(); 
        #endregion
        #endregion
        /// <summary>
        /// 記錄日誌
        /// </summary>
        /// <param name="msg"></param>
        public static void log(string name, string msg)
        {
            try
            {
                name = name.Replace("/", "").Replace("\\", "").Replace(":", "").Replace("*", "").Replace("\"", "").Replace("<", "").Replace(">", "").Replace("|", "").Replace("?", "").Replace("?", "");
                using (StreamWriter sw = new StreamWriter(name + DateTime.Now.ToString("yyyyMMdd HH") + ".log", true))
                {
                    sw.WriteLine(msg);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章