IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
švrčajs
Člen
Avatar
švrčajs:21.7.2017 16:58

Zdravím, řeším jeden problém a už jsem v koncích. Jedná se o příjem videa pomocí tcp protokolu a jeho následné zobrazení. Video přijímám po jednotlivých snímcích, metoda starající se o příjem běží ve vláknu a jednotlivé snímky ukládá do proměnné, která má implementováno OnPropertyChange (pro binding)... Tuto proměnnou mám nabidndingovanou do Image boxu, ale pro spuštění vlákna se připojím k serveru, ale jak dojde k přijímání videa spadne mi to s chybovou hláškou:

System.Argumen­tException: 'Nutno vytvořit závislý zdroj DependencySource ve stejném vlákně jako závislý objekt DependencyObject.'

řekl bych, že problém bude zapisování do proměnné obsahující jednotlivé framy pomocí vlákna.. Když tak nekoukl by na to někdo a neporadil ? Přikládám zdrojové kódy přehrávače... Předem děkuji.

Pro spuštění přijmu videa slouží metoda StartRead()

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Accord.Video.FFMPEG;
using System.Drawing;
using System.Threading;
using System.Windows.Media.Imaging;
using System.IO;
using System.Windows;

namespace Bak.Model
{
    public class PlayerViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        private BitmapImage Convert(Bitmap src)
        {
            MemoryStream ms = new MemoryStream();
            ((System.Drawing.Bitmap)src).Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
            BitmapImage image = new BitmapImage();
            image.BeginInit();
            ms.Seek(0, SeekOrigin.Begin);
            image.StreamSource = ms;
            image.EndInit();
            return image;
        }

        private BitmapImage _imgFrame;
        public BitmapImage ImgFrame
        {
            get { return _imgFrame; }
            set
            {
                _imgFrame = value;
                OnPropertyChanged();
            }
        }
        public PlayerViewModel(string path)
        {
            ImgFrame = new BitmapImage();
            videoReader = new VideoFileReader();
            videoWriter = new VideoFileWriter();
            this.path = path;
        }


        #region GlobalValues
        private Bitmap _frame;
        private Bitmap Frame
        {
            get { return _frame; }
            set
            {
                _frame = value;
                ImgFrame = Convert(value);
            }
        }
        private VideoFileReader videoReader;
        private VideoFileWriter videoWriter;
        private string path;
        private bool stop = false;
        private object stopLock = new object();
        #endregion

        public void Read()
        {
            videoReader.Open("tcp://192.168.0.1:2222");
            if (!videoReader.IsOpen)
                MessageBox.Show("ahoj");

            //label1.Text = reader.CodecName;
            //label2.Text = reader.Width.ToString();
            //label3.Text = reader.Height.ToString();
            //label4.Text = reader.FrameRate.ToString();
           // videoWriter.Open("C:\\Users\\CaptainMorgan\\Desktop\\" + DateTime.Now.ToString() + ".avi", 640, 480, 25, VideoCodec.Default);

            while ((Frame = videoReader.ReadVideoFrame()) != null)
            {
                lock (stopLock)
                {
                    if (stop)
                    {
                        break;
                    }
                    ImgFrame = Convert(Frame);
                }
                //videoWriter.WriteVideoFrame(Frame);
                Frame.Dispose();
            }
            lock (stopLock) stop = false;
            videoWriter.Close();
            videoReader.Close();
        }

        public void StartRead()
        {
            Thread t = new Thread(Read);
            //t.IsBackground = true;
            t.Start();
        }

        public void StopRead()
        {
            lock (stopLock)
            {
                stop = true;
            }
        }
    }
}
 
Odpovědět
21.7.2017 16:58
Avatar
Odpovídá na švrčajs
David Podeszwa:21.7.2017 17:48

Na kterém řádku to přesně vyhodí tu chybu ?

 
Nahoru Odpovědět
21.7.2017 17:48
Avatar
švrčajs
Člen
Avatar
Odpovídá na David Podeszwa
švrčajs:21.7.2017 17:55

ImgFrame = Convert(Frame);

 
Nahoru Odpovědět
21.7.2017 17:55
Avatar
Odpovídá na švrčajs
David Podeszwa:21.7.2017 17:59

Ok, asi vím jak to vyřešit. Jak máš to:

image.StreamSource = ms;
image.EndInit();

tak za to dej ještě tohle:

image.Freeze();

Potom, ve chvíli kdy nastavuješ ten obrázek do toho ImgFrame tak použij Dispatcher aby ti to potom neházelo ještě cross thread exception.

Dispatcher.CurrentDispatcher.Invoke(() => ImgFrame = Convert(Frame););

Tohle by mělo fungovat ale sepsal jsem to jen tak z informací na googlu a nemám k dispozici žádný tvůj streamovací server abych to vyzkoušel.

 
Nahoru Odpovědět
21.7.2017 17:59
Avatar
Shade
Člen
Avatar
Shade:21.7.2017 18:02

Možná to bude problém s Invokováním.

if(InvokeRequired)
                    this.Invoke((MethodInvoker)(() => ImgFrame = Convert(Frame)));
Nahoru Odpovědět
21.7.2017 18:02
Talk is cheap. Show me the code.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.