[solved] GUI Toggle Watched Event (1 Viewer)

popy

MP Donator
  • Premium Supporter
  • July 3, 2011
    617
    141
    Hey guys.

    i want to extend the WatchedSynronizer Plugin and looking for a toggle watched event for moving pictures.
    In mptvseries it like that:

    Code:
    using WindowPlugins.GUITVSeries;
    
    ...
    
    TVSeriesPlugin.ToggleWatched += new TVSeriesPlugin.ToggleWatchedEventDelegate(OnTVSeriesToggledWatched);
    
    ....
    
    private void OnTVSeriesToggledWatched(DBSeries objSeries, List<DBEpisode> lstDBEpisodes, bool bolWatched)
    {
    
    }

    is there anything similar in MovingPictures?

    thx
    pOpY
     

    popy

    MP Donator
  • Premium Supporter
  • July 3, 2011
    617
    141
    Hey.

    have searched throught the source code and didnt found any event like there is one in mptvseries.
    Tried to implement it and built v1.8 from svn tag. I can compile it but when ir loads in Mediaportal there is an error:

    Code:
    [2015-02-01 21:49:37,833] [Log    ] [MPMain   ] [INFO ] - PluginManager: 'C:\Program Files (x86)\Team MediaPortal\MediaPortal\Plugins\windows\MovingPictures.dll' file version: 1.8.0.1613
    [2015-02-01 21:49:37,843] [Log    ] [MPMain   ] [INFO ] - PluginManager: Plugin file MovingPictures.dll is broken or incompatible with the current MediaPortal version and won't be loaded!
    [2015-02-01 21:49:37,844] [Log    ] [MPMain   ] [INFO ] - PluginManager: Exception: System.IO.FileNotFoundException: Die Datei oder Assembly "CookComputing.XmlRpcV2, Version=2.4.0.0, Culture=neutral, PublicKeyToken=a7d6e17aa302004d" oder eine Abhängigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht finden.
    Dateiname: "CookComputing.XmlRpcV2, Version=2.4.0.0, Culture=neutral, PublicKeyToken=a7d6e17aa302004d"
       bei System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes)
       bei System.Reflection.RuntimeAssembly.GetExportedTypes()
       bei MediaPortal.GUI.Library.PluginManager.LoadWindowPlugin(String strFile)
    
    WRN: Protokollierung der Assemblybindung ist AUS.
    Sie können die Protokollierung der Assemblybindungsfehler aktivieren, indem Sie den Registrierungswert [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) auf 1 festlegen.
    Hinweis: Die Protokollierung der Assemblybindungsfehler führt zu einer gewissen Leistungseinbuße.
    Sie können dieses Feature deaktivieren, indem Sie den Registrierungswert [HKLM\Software\Microsoft\Fusion!EnableLog] entfernen.
    
    [2015-02-01 21:49:37,844] [Log    ] [MPMain   ] [DEBUG] - PluginManager: End loading '\windows\MovingPictures.dll' (16,0149 ms running time)

    i have attached my patch for the needed event.
    Can anybody please provide me an test build with the patch merged?

    thx
    pOpY
     

    Attachments

    • MovingPicturesGUI.cs.patch
      1.1 KB

    popy

    MP Donator
  • Premium Supporter
  • July 3, 2011
    617
    141
    Update:
    It works now. I had to run "merge.bat" in the output directory.
    Now my MovingPictures.dll is running and the event is working ;)
    My development version of WatchedSyncronizer receives the toggle watchedstate event from the MovingPictures GUI.

    Code:
    [2015-02-01 22:24:26,021] [Log    ] [MPMain   ] [DEBUG] - WatchedSynchronizer: OnMovingPicturesToggledWatched: The Watched Status for file '\\MEDIASERVER\Videos\Movies\xxxxxxxxxxxxxxxxxxx.mkv' was toggled to 'True',

    @ltfearme: Is it possible that my patch from the previous post wil be merged into the next MovingPictures Version?

    thx
    pOpY

    PS: Attached a patched MovingPictures.dll version 1.8.0.1613.
     

    Attachments

    • MovingPictures_1.8.0.1613_watchedToggle_event.zip
      497.2 KB
    Last edited:

    ltfearme

    Community Plugin Dev
  • Premium Supporter
  • June 10, 2007
    6,751
    7,196
    Sydney
    Home Country
    Australia Australia
    It already has support for this:
    Code:
    MovingPicturesCore.DatabaseManager.ObjectUpdatedEx += new DatabaseManager.ObjectUpdatedDelegate(DatabaseManager_ObjectUpdatedEx);
     

    popy

    MP Donator
  • Premium Supporter
  • July 3, 2011
    617
    141
    Hey, another question regarding the resumedata in the event.
    My code currently is:

    Code:
        //ByteArrayToString, helper function for converting byte array to string
        private string ByteArrayToString(byte[] ba)
        {
            if (ba == null) return "null";
            StringBuilder hex = new StringBuilder(ba.Length * 2);
            foreach (byte b in ba)
                hex.AppendFormat("{0:x2}", b);
            return hex.ToString();
        }
    
        /// <summary>
        /// Fired when an object is updated in the Moving Pictures Database
        /// </summary>
        /// <param name="obj"></param>
        private void DatabaseManager_ObjectUpdatedEx(DatabaseTable dbObject, TableUpdateInfo ui)
        {
            WatchedStateEvent curEvent = new WatchedStateEvent();
            string strDebug;
    
            // If it is user settings for a movie
            if (dbObject.GetType() != typeof(DBUserMovieSettings))
            {
                Log.Debug("WatchedSynchronizer: DatabaseManager_ObjectUpdatedEx: dbObject.GetType != DBUserMovieSettings");
                return;
            }
    
            DBUserMovieSettings userMovieSettings = (DBUserMovieSettings)dbObject;
            DBMovieInfo movie = userMovieSettings.AttachedMovies[0];
    
            //Debug
            strDebug = "WatchedSynchronizer: DatabaseManager_ObjectUpdatedEx: userMovieSettings:" +
                                                                "ID: " + userMovieSettings.ID.ToString() + ", " +
                                                                "User: " + userMovieSettings.User.ToString() + ", " +
                                                                "UserRating: " + userMovieSettings.UserRating.ToString() + ", " +
                                                                "WatchedCount: " + userMovieSettings.WatchedCount.ToString() + ", " +
                                                                "ResumePart: " + userMovieSettings.ResumePart.ToString() + ", " +
                                                                "ResumeTime: " + userMovieSettings.ResumeTime.ToString() + ", " +
                                                                "ResumeTitleBD: " + userMovieSettings.ResumeTitleBD.ToString();
            if (userMovieSettings.ResumeData.Data == null)
            {
                strDebug = strDebug + ", " + "ResumeData: null";
            }
            else
            {
                strDebug = strDebug + ", " + "ResumeData: " + ByteArrayToString(userMovieSettings.ResumeData.Data);
            }
            Log.Debug(strDebug);

    I am always getting exception:

    Code:
    [2015-02-03 13:04:08,132] [Log    ] [MPMain   ] [DEBUG] - GUIVideoFiles: OnPlayBackStopped store resume time
    [2015-02-03 13:04:08,157] [Log    ] [MPMain   ] [ERROR] - Exception: System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
       bei Cornerstone.Database.CustomTypes.ByteArray.get_Data()
       bei WatchedSynchronizer.WatchedSynchronizer.DatabaseManager_ObjectUpdatedEx(DatabaseTable dbObject, TableUpdateInfo ui)
       bei Cornerstone.Database.DatabaseManager.update(DatabaseTable dbObject)
       bei Cornerstone.Database.DatabaseManager.Commit(DatabaseTable dbObject)
       bei Cornerstone.Database.Tables.DatabaseTable.Commit()
       bei MediaPortal.Plugins.MovingPictures.Database.MovingPicturesDBTable.Commit()
       bei MediaPortal.Plugins.MovingPictures.MainUI.MoviePlayer.updateMovieResumeState(DBMovieInfo movie, Int32 part, Int32 timePlayed, Byte[] resumeData, Int32 titleBD)
       bei MediaPortal.Plugins.MovingPictures.MainUI.MoviePlayer.onPlayBackStoppedOrChanged(MediaType type, Int32 timeMovieStopped, String filename)
       bei MediaPortal.Player.g_Player.StoppedHandler.Invoke(MediaType type, Int32 stoptime, String filename)
       bei MediaPortal.Player.g_Player.OnStopped()
       bei MediaPortal.Player.g_Player.doStop(Boolean keepTimeShifting, Boolean keepExclusiveModeOn)
       bei MediaPortal.Player.g_Player.Stop()
       bei MediaPortalApp.OnAction(Action action)  Message: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.  Site   : Byte[] get_Data()  Source : Cornerstone  Stack Trace:     bei Cornerstone.Database.CustomTypes.ByteArray.get_Data()
       bei WatchedSynchronizer.WatchedSynchronizer.DatabaseManager_ObjectUpdatedEx(DatabaseTable dbObject, TableUpdateInfo ui)
       bei Cornerstone.Database.DatabaseManager.update(DatabaseTable dbObject)
       bei Cornerstone.Database.DatabaseManager.Commit(DatabaseTable dbObject)
       bei Cornerstone.Database.Tables.DatabaseTable.Commit()
       bei MediaPortal.Plugins.MovingPictures.Database.MovingPicturesDBTable.Commit()
       bei MediaPortal.Plugins.MovingPictures.MainUI.MoviePlayer.updateMovieResumeState(DBMovieInfo movie, Int32 part, Int32 timePlayed, Byte[] resumeData, Int32 titleBD)
       bei MediaPortal.Plugins.MovingPictures.MainUI.MoviePlayer.onPlayBackStoppedOrChanged(MediaType type, Int32 timeMovieStopped, String filename)
       bei MediaPortal.Player.g_Player.StoppedHandler.Invoke(MediaType type, Int32 stoptime, String filename)
       bei MediaPortal.Player.g_Player.OnStopped()
       bei MediaPortal.Player.g_Player.doStop(Boolean keepTimeShifting, Boolean keepExclusiveModeOn)
       bei MediaPortal.Player.g_Player.Stop()
       bei MediaPortalApp.OnAction(Action action)
    [2015-02-03 13:04:08,170] [Error  ] [MPMain   ] [ERROR] - Exception: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt. Cornerstone    bei Cornerstone.Database.CustomTypes.ByteArray.get_Data()
       bei WatchedSynchronizer.WatchedSynchronizer.DatabaseManager_ObjectUpdatedEx(DatabaseTable dbObject, TableUpdateInfo ui)
       bei Cornerstone.Database.DatabaseManager.update(DatabaseTable dbObject)
       bei Cornerstone.Database.DatabaseManager.Commit(DatabaseTable dbObject)
       bei Cornerstone.Database.Tables.DatabaseTable.Commit()
       bei MediaPortal.Plugins.MovingPictures.Database.MovingPicturesDBTable.Commit()
       bei MediaPortal.Plugins.MovingPictures.MainUI.MoviePlayer.updateMovieResumeState(DBMovieInfo movie, Int32 part, Int32 timePlayed, Byte[] resumeData, Int32 titleBD)
       bei MediaPortal.Plugins.MovingPictures.MainUI.MoviePlayer.onPlayBackStoppedOrChanged(MediaType type, Int32 timeMovieStopped, String filename)
       bei MediaPortal.Player.g_Player.StoppedHandler.Invoke(MediaType type, Int32 stoptime, String filename)
       bei MediaPortal.Player.g_Player.OnStopped()
       bei MediaPortal.Player.g_Player.doStop(Boolean keepTimeShifting, Boolean keepExclusiveModeOn)
       bei MediaPortal.Player.g_Player.Stop()
       bei MediaPortalApp.OnAction(Action action)
    [2015-02-03 13:04:08,175] [Log    ] [MPMain   ] [ERROR] - Exception: System.Exception: exception occurred ---> System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
       bei Cornerstone.Database.CustomTypes.ByteArray.get_Data()
       bei WatchedSynchronizer.WatchedSynchronizer.DatabaseManager_ObjectUpdatedEx(DatabaseTable dbObject, TableUpdateInfo ui)
       bei Cornerstone.Database.DatabaseManager.update(DatabaseTable dbObject)
       bei Cornerstone.Database.DatabaseManager.Commit(DatabaseTable dbObject)
       bei Cornerstone.Database.Tables.DatabaseTable.Commit()
       bei MediaPortal.Plugins.MovingPictures.Database.MovingPicturesDBTable.Commit()
       bei MediaPortal.Plugins.MovingPictures.MainUI.MoviePlayer.updateMovieResumeState(DBMovieInfo movie, Int32 part, Int32 timePlayed, Byte[] resumeData, Int32 titleBD)
       bei MediaPortal.Plugins.MovingPictures.MainUI.MoviePlayer.onPlayBackStoppedOrChanged(MediaType type, Int32 timeMovieStopped, String filename)
       bei MediaPortal.Player.g_Player.StoppedHandler.Invoke(MediaType type, Int32 stoptime, String filename)
       bei MediaPortal.Player.g_Player.OnStopped()
       bei MediaPortal.Player.g_Player.doStop(Boolean keepTimeShifting, Boolean keepExclusiveModeOn)
       bei MediaPortal.Player.g_Player.Stop()
       bei MediaPortalApp.OnAction(Action action)
       --- Ende der internen Ausnahmestapelüberwachung ---
       bei MediaPortalApp.OnAction(Action action)
       bei MediaPortal.GUI.Library.OnActionHandler.Invoke(Action action)
       bei MediaPortal.GUI.Library.GUIWindowManager.DispatchThreadMessages()
       bei MediaPortalApp.FrameMove()  Message: exception occurred  Site   : Void OnAction(MediaPortal.GUI.Library.Action)  Source : MediaPortal  Inner Exception(s):  -> exception occurred  -> Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.  Stack Trace:     bei MediaPortalApp.OnAction(Action action)
       bei MediaPortal.GUI.Library.OnActionHandler.Invoke(Action action)
       bei MediaPortal.GUI.Library.GUIWindowManager.DispatchThreadMessages()
       bei MediaPortalApp.FrameMove()
    [2015-02-03 13:04:08,282] [Log    ] [MPMain   ] [DEBUG] - D3D: Showing mouse cursor

    When ill remove the Debug print of the Resumpart variable the code runs fine.
    What i have understanded is that the resumepart is needed for gplayer to resume settings for BD/DVD playback.

    how can ill print it correctly to the debug log (best is hex string formated)??

    how can ill update Resumepart with Update sql statement within c#.
    Currently my code is:

    Code:
                string strSQL = String.Format("UPDATE user_movie_settings SET watched = {0}, resume_part = {1}, resume_time = {2}, resume_data = NULL, resume_titlebd = {3} WHERE id = '{4}'", strWatchedStatus, intResumePart.ToString(), intResumeTime.ToString(), intResumeTitleBD.ToString(), strUserMovieSettingsId);
                Log.Debug("WatchedSynchronizer: (SetEpisodeWatchedStatus) SQL statement '" + strSQL + "' is going to be executed in database '" + mDatabase.DatabaseName + "'.");
                mDatabase.Execute(strSQL);

    thx
    pOpY
     

    popy

    MP Donator
  • Premium Supporter
  • July 3, 2011
    617
    141
    Update: I have solved it.

    The issue is in the ByteArray.cs of CornerStone.
    Old Code:

    Code:
            public byte[] Data {
                get {
                    if (_data.Length == 0)
                        return null;
                    else
                        return _data;
                }
                set { _data = value; }
            }
            private byte[] _data = null;
    
            public ByteArray() {
            }
    
            public ByteArray(byte[] data) {
                _data = data;
            }

    Ill think it happens that when an new ByteArray is instanced with no given "data" and "Data" is accessed, the code access "_data.Length" (bold above) and there the exception is thrown!

    Fixed Code:

    Code:
            public byte[] Data {
                get {
                    if ((_data == null) || (_data.Length == 0))
                        return null;
                    else
                        return _data;
                }
                set { _data = value; }
            }
            private byte[] _data = null;
    
            public ByteArray() {
            }
    
            public ByteArray(byte[] data) {
                _data = data;
            }

    My workaround in my current code of WatchedSyncronizer:

    Code:
        private void OnMovingPicturesDatabaseUpdated(DatabaseTable dbObject, TableUpdateInfo ui)
        {
            WatchedStateEvent curEvent = new WatchedStateEvent();
            byte[] bteTmpResumeData = new byte[] { };
    
            // If it is user settings for a movie
            if (dbObject.GetType() != typeof(DBUserMovieSettings))
            {
                Log.Debug("WatchedSynchronizer: OnMovingPicturesDatabaseUpdated: unknown object type: '" + dbObject.GetType().ToString() + "', event dropped!");
                return;
            }
    
            //Cast to DBUserMovieSettings object and get movie details
            DBUserMovieSettings userMovieSettings = (DBUserMovieSettings)dbObject;
            DBMovieInfo movie = userMovieSettings.AttachedMovies[0];
    
            //check if userMovieSettings.ResumeData is null or empty string
            //if that is the case reinitialize userMovieSettings.ResumeData with an empty byte array to prevent null exception when accessing userMovieSettings.ResumeData.Data
            //this should be fixed in ByteArray.cs of Cornerstone. There is access to _data.length and NO null check before!
            if ((userMovieSettings.ResumeData == null) || (userMovieSettings.ResumeData.ToString() == ""))
            {
                userMovieSettings.ResumeData = new ByteArray(bteTmpResumeData);
            }

    pOpY
     

    Users who are viewing this thread

    Top Bottom