using EC.Entity.Video; using EC.FFmpegAutoGen; using EC.Utils.Config; using ECMonitor.Code; using ECMonitor.Code.Config; using ECMonitor.Manager; using FFmpeg.AutoGen; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using NetMQ.Sockets; using NetMQ; using EC.Utils.ImageHelpers; using EC.Utils; namespace ECMonitor.UC.Videos { /// /// UCFFmpegPlayer.xaml 的交互逻辑 /// public partial class UCFFmpegAIBoxPlayer : UserControl, IUCPlayer { /// /// 视频播放器序号 /// int _videoIndex = 0; private string Message { get; set; } private string UcName { get; set; } public MonitorCamera Camera { get; set; } public int VideoType { get; set; } /// /// 更新时间 /// private DateTime upDateTime; public event EventHandler OnFromClose; /// /// /// double NormaWidth { get; set; } = 0; double NormaHeight { get; set; } = 0; /// /// 最大化 /// bool WindowStateMax { get; set; } = false; string inputpath = ConfigHelper.AIInputPath(); string outpath = ConfigHelper.AIOutPath(); string _aiServer = ConfigHelper.AISvrServer(); public UCFFmpegAIBoxPlayer(double width, double height, int videoIndex, bool showCloseButton = true, string aspectRatio = "4:3") { this.Width = width; this.Height = height; InitializeComponent(); this.Name = "UCPlayer" + videoIndex; UcName = this.Name; this.btnClose.Visibility = showCloseButton ? Visibility.Visible : Visibility.Hidden; ReSetSize(width, height); ShowMsg("没有视频"); _videoIndex = videoIndex; } /// /// 设置窗体大小 /// /// /// public void ReSetSize(double width, double height) { Width = width; Height = height; //显示内容 //double messageWidht = 40; //double left = width / 2 - messageWidht / 2; //double top = height / 2 - 20; ////double right = width-(left + messageWidht); ////double bottom = height / 2 - 10; //this.txtShow.Margin = new Thickness(left, top, right, bottom); this.imgPlayer.Height = height; SetSelected(false); } public bool Play(MonitorCamera camera, bool replay = false) { if (IsPlaying()) { if (replay == false) { if (camera.Ip == Camera.Ip) { return true; } } Stop(); } Camera = camera; if (Camera == null) { return false; } return Play(); } public void Stop() { try { if (_playing == false) { return; } _playing = false; Camera = null; MemoryStream ms = null; Task.Factory.StartNew(() => { Thread.Sleep(1000); SetImageSource(ms); _playingSuccess = false; }); ShowMsg("视频已经关闭"); OnFromClose?.Invoke(this, null); } catch (Exception ex) { LogFactory.GetLogger().Error(ex); } } public void UPDateTime() { upDateTime = DateTime.Now; } /// /// 判断预警是否接触 /// /// public bool IsTimeOut() { DateTime now = DateTime.Now; double difSeconds = DateUnit.DateDiffSeconds(upDateTime, now); return difSeconds > 6; } public string GetCameraIp() { if (Camera != null) { return Camera.Ip; } return ""; } /// /// 播放器类型 /// /// public int GetPlayerType() { return VideoType; } /// /// 相机 /// /// public MonitorCamera GetCamera() { return Camera; } public UserControl GetControl() { return this; } public string GetMessage() { return Message; } public string GetName() { return UcName; } /// /// 是否是空播放器 /// /// public bool IsNullPlay() { return Camera == null; } /// /// 是否播放 /// bool _playing = false; /// /// 播放成功 /// bool _playingSuccess = false; /// /// 是否正在播放 /// /// public bool IsPlaying() { if (Camera == null) { return false; } return _playing;//&& _playingSuccess; } private int listIndex = 0; public int GetIndex() { return listIndex; } public void SetIndex(int index) { listIndex = index; } /// /// 是否显示 /// private bool IsShow = false; public bool GetIsShow() { return IsShow; } public void SetIsShow(bool isShow) { IsShow = isShow; } private void btnClose_Click(object sender, RoutedEventArgs e) { Stop(); OnFromClose?.Invoke(sender, e); } #region FFmpeg public delegate void dlgtSetImage(MemoryStream ms); public delegate void dlgtSetImageByte(byte[] ms); void SetImageSource(MemoryStream ms) { this.imgPlayer.Dispatcher.Invoke(new dlgtSetImage(SetImage), ms); } void SetImage(MemoryStream ms) { //if (this.imgPlayer.Dispatcher.CheckAccess()) //{ // this.imgPlayer.Dispatcher.Invoke(new dlgtSetImage(setImage), ms); // return; //} ShowMsg(""); if (ms == null) { imgPlayer.Source = null; // done! return; } BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.StreamSource = new MemoryStream(ms.ToArray()); // 不要直接使用 ms bi.EndInit(); // Guid photoID = System.Guid.NewGuid(); //string photolocation = $"img//" + DateTime.Now.ToString("MMddHHmmssfff") + ".jpg"; //file name //FileStream filestream = new FileStream(photolocation, FileMode.Create); //JpegBitmapEncoder encoder = new JpegBitmapEncoder(); //encoder.Frames.Add(BitmapFrame.Create(bi)); //encoder.Save(filestream); imgPlayer.Source = bi; // done! // ms.Close(); //} } void SetImageSource(byte[] ms) { this.imgPlayer.Dispatcher.Invoke(new dlgtSetImageByte(SetImage), ms); } void SetImage(byte[] ms) { ShowMsg(""); if (ms == null) { imgPlayer.Source = null; // done! return; } BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.StreamSource = new MemoryStream(ms); // 不要直接使用 ms bi.EndInit(); //// Guid photoID = System.Guid.NewGuid(); //string photolocation = $"img//" + DateTime.Now.ToString("MMddHHmmssfff") + ".jpg"; //file name //FileStream filestream = new FileStream(photolocation, FileMode.Create); //JpegBitmapEncoder encoder = new JpegBitmapEncoder(); //encoder.Frames.Add(BitmapFrame.Create(bi)); //encoder.Save(filestream); imgPlayer.Source = bi; // done! // ms.Close(); //} } public bool Play() { Message = ""; try { Task.Factory.StartNew(() => PlayThread()); CheckPlaySuccessed(); } catch (System.Exception ex) { ShowMsg(ex.Message); } finally { } return true; } public bool PlayThread() { if (Camera == null) { return false; } _playing = true; UPDateTime(); //string url = "rtsp://admin:hk123456@192.168.1.108:554/cam/realmonitor?channel=1&subtype=1&unicast=true&proto=Onvif"; // string url = "rtsp://admin:hk123456@192.168.1.65:554/Streaming/Channels/102?transportmode=unicast&profile=Profile_2"; string url = Camera.RtspURL(); FFmpegBinariesHelper.RegisterFFmpegBinaries(); // Console.WriteLine($"FFmpeg version info: {ffmpeg.av_version_info()}"); SetupLogging(); // ConfigureHWDecoder(out var deviceType); var deviceType = AVHWDeviceType.AV_HWDEVICE_TYPE_DXVA2; DecodeAllFramesToImages(deviceType, url); return true; } /// /// 判断是否播放成功,因为播放没有返回,只能从有没有图片返回判断 /// public void CheckPlaySuccessed() { Task.Factory.StartNew(() => { Thread.Sleep(5000); if (_playingSuccess == false) { _playing = false; if (Camera != null) { ShowMsg(Camera.Ip + "播放失败"); } } }); } private unsafe void SetupLogging() { ffmpeg.av_log_set_level(ffmpeg.AV_LOG_VERBOSE); // do not convert to local function av_log_set_callback_callback logCallback = (p0, level, format, vl) => { if (level > ffmpeg.av_log_get_level()) return; var lineSize = 1024; var lineBuffer = stackalloc byte[lineSize]; var printPrefix = 1; ffmpeg.av_log_format_line(p0, level, format, vl, lineBuffer, lineSize, &printPrefix); var line = Marshal.PtrToStringAnsi((IntPtr)lineBuffer); LogFactory.GetLogger().Debug(line); }; ffmpeg.av_log_set_callback(logCallback); } private unsafe void DecodeAllFramesToImages(AVHWDeviceType HWDevice, string url) { // decode all frames from url, please not it might local resorce, e.g. string url = "../../sample_mpeg4.mp4"; //*var url = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4*/"; // be advised this file holds 1440 frames using var vsd = new VideoStreamDecoder(url, HWDevice); Console.WriteLine($"codec name: {vsd.CodecName}"); var info = vsd.GetContextInfo(); info.ToList().ForEach(x => Console.WriteLine($"{x.Key} = {x.Value}")); var sourceSize = vsd.FrameSize; var sourcePixelFormat = HWDevice == AVHWDeviceType.AV_HWDEVICE_TYPE_NONE ? vsd.PixelFormat : FFmpegHelper.GetHWPixelFormat(HWDevice); var destinationSize = sourceSize; var destinationPixelFormat = AVPixelFormat.AV_PIX_FMT_BGR24; using var vfc = new VideoFrameConverter(sourceSize, sourcePixelFormat, destinationSize, destinationPixelFormat); var frameNumber = 0; int imageNumber = 0; while (_playing && vsd.TryDecodeNextFrame(out var frame)) { var convertedFrame = vfc.Convert(frame); var bitmap = new Bitmap(convertedFrame.width, convertedFrame.height, convertedFrame.linesize[0], System.Drawing.Imaging.PixelFormat.Format24bppRgb, (IntPtr)convertedFrame.data[0]); //IntPtr hBitmap = bitmap.GetHbitmap(); //System.Windows.Media.ImageSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, //BitmapSizeOptions.FromEmptyOptions()); // bitmapSource.Freeze(); _playingSuccess = true; imageNumber++; imageNumber = imageNumber % 100; var x = imageNumber % 3; if (x == 0) { continue; } //if (x==2) //{ // string filename = imageNumber + ".jpg"; // string fullfileName = inputpath + filename; // bitmap.Save(fullfileName, ImageFormat.Jpeg); // bitmap.Dispose(); // PubToAI(filename); //} if (x == 2) { PubToAI(bitmap); //PubToAI(filename); } else { //MemoryStream stream = new MemoryStream(); //bitmap.Save(stream, ImageFormat.Bmp); //SetImageSource(stream); //bitmap.Dispose(); } Console.WriteLine($"frame: {frameNumber}"); frameNumber++; } } //将Bitmap对象转换成bitmapImage对象 //public BitmapImage ConvertBitmapToBitmapImage(Bitmap bitmap) //{ // MemoryStream stream = new MemoryStream(); // bitmap.Save(stream, ImageFormat.Bmp); // BitmapImage image = new BitmapImage(); // image.BeginInit(); // image.StreamSource = stream; // image.EndInit(); // return image; //} #endregion public void ShowMsg(string message) { this.txtShow.Dispatcher.Invoke(new Action(() => { this.txtShow.Text = message; })); } private void Log(string message, bool isErr = false) { ShowMsg(message); } public void SetSelected(bool selected) { Thickness thickness = new Thickness(0); if (selected) { thickness = new Thickness(1); } this.playerBorder.Dispatcher.Invoke(new Action(() => { playerBorder.BorderThickness = thickness; })); } #region 事件 public event EventHandler PlayerMouseDown; public event EventHandler PlayerMouseDoubleClick; private void UserControl_MouseDown(object sender, MouseButtonEventArgs e) { PlayerMouseDown?.Invoke(this, _videoIndex); } private void UserControl_MouseDoubleClick(object sender, MouseButtonEventArgs e) { PlayerMouseDoubleClick?.Invoke(this, _videoIndex); } /// /// 设置最大化 /// /// /// /// public bool SetMaximized(double width, double height) { if (WindowStateMax == false) { NormaWidth = this.Width; NormaHeight = this.Height; WindowStateMax = true; ReSetSize(width, height); } else { WindowStateMax = false; ReSetSize(NormaWidth, NormaHeight); } return WindowStateMax; } #endregion #region ZMQ private void PubToAI(Bitmap inbitmap) { Task.Factory.StartNew(() => { try { if (_playing == false) { return; } byte[] data = ImageHelper.ImageToByteArray(inbitmap); inbitmap.Dispose(); if (data == null) return; using (var requestSocket = new RequestSocket(_aiServer)) { requestSocket.SendFrame(data); var timeout = new TimeSpan(0, 0, 1); byte[] recdata = new byte[0]; bool recSuccess = requestSocket.TryReceiveFrameBytes(timeout, out recdata); // byte[] recdata = requestSocket.ReceiveFrameBytes(); if (recSuccess) { SetImageSource(recdata); } } } catch (Exception ex) { ShowMsg(ex.Message); LogFactory.GetLogger().Error(ex); } }); } //private void PubToAI(string fileName) //{ // Task.Factory.StartNew(() => // { // try // { // using (var requestSocket = new RequestSocket(_aiServer)) // { // requestSocket.SendFrame(fileName); // var recfileName = requestSocket.ReceiveFrameString(); // string fullFileName = outpath + recfileName; // System.Drawing.Image bitmap = System.Drawing.Bitmap.FromFile(fullFileName); // MemoryStream stream = new MemoryStream(); // bitmap.Save(stream, ImageFormat.Bmp); // SetImageSource(stream); // } // } // catch (Exception ex) // { // ShowMsg(ex.Message); // LogFactory.GetLogger().Error(ex); // } // }); // } #endregion } }