wpf下基于opencv实现视频播放器

    最近wpf项目用到视频播放,首先想到的就是vlc了,简单方便,网上教程也很多,实现也很顺利,但是正在和项目结合时候发现问题了,项目需求要视频帧上画出目标对象。使用vlc时发现。vlc的播放事件时按秒来的,且播放事件取到的帧和帧率无法对应,最后结果就是画上去的目标对象存在延迟,且不准确。

   没办法,老老实实用opencv来实现把,比较opencv时可以取到每一帧图片的。

其效果如下:

wpf下基于opencv实现视频播放器_第1张图片

 

1、首先准备opencv的库,wpf当然用得到的就是emgu.cv。只应用emgu.cv肯定不行。opencv的依赖库也要放到可执行文件里面。

wpf下基于opencv实现视频播放器_第2张图片

以上这些都是必须的。不然会报错。

2、创建videocapture,并获取视频相关基本信息

       private bool StartPlay(string videoPath)
        {
            bool result = true;
            try
            {
                videoCapture = new VideoCapture(videoPath);
                if (videoCapture.IsOpened)
                {
                    videoInfo.Filename = fileName;
                    videoInfo.Width = (int)       videoCapture.GetCaptureProperty(CapProp.FrameWidth);
                    videoInfo.Height = (int) videoCapture.GetCaptureProperty(CapProp.FrameHeight);
                    videoInfo.FrameCount = (int) videoCapture.GetCaptureProperty(CapProp.FrameCount);
                    videoInfo.Fps = (int) videoCapture.GetCaptureProperty(CapProp.Fps);
                    videoInfo.CurrentFrame = 0;
                    myTimer.Interval = videoInfo.Fps == 0 ? 300 : 1000 / videoInfo.Fps;
                    IsStartPlay = true;
                    myTimer.Start();
                    totalTime = TimeSpan.FromSeconds(videoInfo.FrameCount / videoInfo.Fps);
                    this.tbTotalTimeLength.Text = $"{totalTime.Hours:00}:{totalTime.Minutes:00}:{totalTime.Seconds:00}";
                    this.process.Minimum = 0;
                    this.process.Maximum = totalTime.TotalSeconds;
                    this.process.SmallChange = 1;
                }
                else
                {
                    MessageBox.Show("视频源异常");
                    result = false;
                }
            }
            catch (Exception e)
            {
                result = false;
            }

            return result;
        }

3、通过定时器,根据帧率获取视频帧,并给界面显示。

        private void MyTimerElapsed(object sender, ElapsedEventArgs e)
        {
            if (IsStartPlay)
            {
                lock (LockHelper)
                {
                    var frame = videoCapture.QueryFrame();
                    if (frame != null)
                    {
                        videoInfo.CurrentFrame = (int)videoCapture.GetCaptureProperty(CapProp.PosFrames);
                        this.SetVideoCapture(frame);
                        videoInfo.PlaySate = PlaySate.Playing;
                    }
                }
            }
        }
        private void SetVideoCapture(Mat frame)
        {
            Application.Current?.Dispatcher.Invoke(() =>
            {
                currtenTime = TimeSpan.FromSeconds(videoInfo.CurrentFrame / videoInfo.Fps);
                if (videoInfo.CurrentFrame >= videoInfo.FrameCount)
                {
                    this.process.Value = totalTime.TotalSeconds;
                    this.StopPlay();
                    return;
                }

                var bitImage = frame.Clone();
                this.process.Value = currtenTime.TotalSeconds;
                this.VideoShow.Source = BitmapSourceConvert.ToBitmapSource(bitImage);
            });
        }

4、播放、暂停、停止通过定时器来控制,播放进度滑动通过videoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.PosFrames, value); 来控制。

 

详细的查看项目共工程。

https://download.csdn.net/download/esiangchioa/12434790

你可能感兴趣的:(wpf)