Need a little help with plugin development (1 Viewer)

Kasimir9735

Portal Pro
July 19, 2010
36
30
53
Wetter (Ruhr)
Home Country
Germany Germany
Hello,

i'm currently writing a plugin for the tv engine. i've written this plugin already for mp1 and want to update it so it can run in mp2 too.

After a successful recording the plugin should determine if the recorded series episode is already in my collection of series. If this is true, it simply deletes the recording. Otherwise the recording is moved to my series collection on the network. The old plugin for mp1 used the tvdbseries database. Now in MP2 these informations are stored in different tables in the Datastore.

My question now is: Whats the right way to access the series informations in the datastore.

- How do i query for the series items
- Why has the tabel M_SERIESITEM no information about the episode number?
- Where are the path and filenames of the series items stored?

Hope i find help here.

Thanks
 

HTPCSourcer

Retired Team Member
  • Premium Supporter
  • May 16, 2008
    11,418
    2,335
    Home Country
    Germany Germany
    Interesting.

    We are always looking for people who support our projects and develop new solutions. I trust that @morpheus_xx will reply to your question.

    With respect to automatic deletion: how do/would you handle the following situation? I do record a lot of series and movies on Sky, which I then cut with VideoReDo. Sometimes the recorded show contains glitches, can be audio or video, a lot or just a little bit, as reported by VideoReDo. In that case I move the cut file to my collection, but may record it again until I get the desired quality. Running your plugin would simply delete the new recording.
     

    mm1352000

    Retired Team Member
  • Premium Supporter
  • September 1, 2008
    21,577
    8,224
    Home Country
    New Zealand New Zealand
    ...and a further question: would it not be more optimal to avoid recording in the first place? That way you leave tuner(s) available for live TV or additional recordings.
     

    Lehmden

    Retired Team Member
  • Premium Supporter
  • December 17, 2010
    12,553
    3,934
    Lehmden
    Home Country
    Germany Germany
    Hi.
    I can answer a few of your questions..
    How do i query for the series items
    I've done it in my AutoIt tool this way (it's working):
    "SELECT * FROM M_MEDIAITEM INNER JOIN M_SERIESITEM ON M_MEDIAITEM.MEDIA_ITEM_ID = M_SERIESITEM.MEDIA_ITEM_ID INNER JOIN NM_EPISODE ON NM_EPISODE.MEDIA_ITEM_ID = M_SERIESITEM.MEDIA_ITEM_ID INNER JOIN V_EPISODE ON NM_EPISODE.ID = V_EPISODE.ID ;"

    Why has the tabel M_SERIESITEM no information about the episode number?
    Good question, next question... ;) I never understand why the episodes numbers are in an extra table and encrypted to a GUID... Makes queries much more complicated and I can't see any advantage in this approach. But I can imagine this will change with the MIA rework within the next weeks (also I'm not sure about this)...

    Where are the path and filenames of the series items stored?
    In table M_PROVIDERRESOURCE...

    And now forget all that I've written above:p
    because of:
    Whats the right way to access the series informations in the datastore.
    The right and only way is to ask MP2 server. Never access the database directly... This may lead to crashes and/or corrupted databases... We don't want to copy bad coding styles from other applications...;)
    If you need guidance for this you may ask some devs...
     

    Kasimir9735

    Portal Pro
    July 19, 2010
    36
    30
    53
    Wetter (Ruhr)
    Home Country
    Germany Germany
    With respect to automatic deletion: how do/would you handle the following situation? I do record a lot of series and movies on Sky, which I then cut with VideoReDo. Sometimes the recorded show contains glitches, can be audio or video, a lot or just a little bit, as reported by VideoReDo. In that case I move the cut file to my collection, but may record it again until I get the desired quality. Running your plugin would simply delete the new recording.


    That's funny. I'm currently working on anlyzing the recorded ts file before deleting the recording. My idea is to store informations about the quality of the recording and compare it with newer recordings. If the quality is better the second recording is also stored and a notification is sent. If a next recording is finished and the quality is better, only the best duplicate is also held. Until the recording is manually acknowledged this game goes on and on.

    ...and a further question: would it not be more optimal to avoid recording in the first place? That way you leave tuner(s) available for live TV or additional recordings.


    ... and thats the reason for not to avoiding upcoming recordings. Another reason for this is, that i was not able to cancel upcoming recordings for the same episode (tvserver code is a little bit messy for me ... :) )

    The right and only way is to ask MP2 server. Never access the database directly... This may lead to crashes and/or corrupted databases... We don't want to copy bad coding styles from other applications...;)
    If you need guidance for this you may ask some devs...


    Yes, that was my Idea. Accessing the database directly is easy (not easy to understand that uncommon structure), but i want to do it the right way. Should i send a message directly, or do they answer here?
    Thank you very much for your informations.
     

    morpheus_xx

    Retired Team Member
  • Team MediaPortal
  • March 24, 2007
    12,073
    7,459
    Home Country
    Germany Germany
    My question now is: Whats the right way to access the series informations in the datastore.
    I suggest to use a higher level approach to load items from the media library:
    While you could do raw SQL commands, you would have to consider many inbuilt concepts. An important information: the table names are not fixed: if a so called MediaAspect gets extended (and thus a new AspectID), a new database table will be created.

    What you should do is to add a reference to MP2 core components (MediaLibrary) and then do a query like:
    https://github.com/MediaPortal/Medi...nArt/FanArtService/MediaItemThumbs.cs#L54-L80

    This example loads thumbnail data, but you can easily include the SeriesAspect for loading (which contains Series and Episode infos).
    - Why has the tabel M_SERIESITEM no information about the episode number?
    The reason is, that the Episode information is a 1:n entry. One single file can have multiple episodes (often done by TV broadcasters, combining episodes). When loading data by IMediaLibrary, you don't need to manually take care about this.

    Where are the path and filenames of the series items stored?
    This is included in ProviderResourceAspect.

    Please take a look at the linked example above, I'm happy to provide further assistance :)
     

    Kasimir9735

    Portal Pro
    July 19, 2010
    36
    30
    53
    Wetter (Ruhr)
    Home Country
    Germany Germany
    I suggest to use a higher level approach to load items from the media library:
    While you could do raw SQL commands, you would have to consider many inbuilt concepts. An important information: the table names are not fixed: if a so called MediaAspect gets extended (and thus a new AspectID), a new database table will be created.


    You're right. Thats a good idea...

    What you should do is to add a reference to MP2 core components (MediaLibrary) and then do a query like:
    https://github.com/MediaPortal/Medi...nArt/FanArtService/MediaItemThumbs.cs#L54-L80
    https://github.com/MediaPortal/Medi...nArt/FanArtService/MediaItemThumbs.cs#L54-L80


    Ok. I tried this, but have no luck. Do you really think this could work in a plugin of the TVEngine?
    I've finished the code to get the data with this method. Then i just added a Test button in the SetupTV to test if it works.

    First Problem: Cannot load assembly Mediaportal.Backend.dll (Needed the reference because of MediaLibrary). Ok. Fixed it quick with a copy of the dll in the SlimTv.Service3 directory. The loibrary could load then. What's the best approach for this? Could load the assembly dynamicly via refelection later...

    Next problem:

    Code:
                var mediaLibrary = ServiceRegistration.Get<IMediaLibrary>(false);
                if (mediaLibrary == null)
                    throw new Exception("Unable to get reference to IMediaLibary");

    mediaLibrary is always null. So i cannot continue. Do you have an idea what to do?

    I'm happy to provide further assistance :)


    Thank you for this.
     

    morpheus_xx

    Retired Team Member
  • Team MediaPortal
  • March 24, 2007
    12,073
    7,459
    Home Country
    Germany Germany
    I was afraid that there are dependency problems with this approach. All the required assemblies should be loaded already in the AppDomain, because the MP2-Server is the master process. Then the TVE3 (SlimTv.Service3) is loaded as plugin of MP2-Server, which then in next step loads its TV plugins.

    How do you try to test your plugin? From within the MP2-Server solution?

    Can you share the current source code so that I can setup the same setup here?
     

    Kasimir9735

    Portal Pro
    July 19, 2010
    36
    30
    53
    Wetter (Ruhr)
    Home Country
    Germany Germany
    I was afraid that there are dependency problems with this approach. All the required assemblies should be loaded already in the AppDomain, because the MP2-Server is the master process. Then the TVE3 (SlimTv.Service3) is loaded as plugin of MP2-Server, which then in next step loads its TV plugins.

    How do you try to test your plugin? From within the MP2-Server solution?

    Can you share the current source code so that I can setup the same setup here?


    Hey morpheus... Finally i've got it. The Problem was, that i had my test in the tvsetup program. You cannot use references to infrastructure of MP2 Server because it's standalone. For my case it's ok, but maybe should be analyzed i the future. Now i've done my tests in MP2 Server and did a debug attached to it. That works, but in my eyes the resulting code is terrible. Maybe i've understand the framework in the wrong way. So maybe you can take a look at the following and comment it:

    First get access to the MediaLibrary:
    Code:
    var mediaLibrary = ServiceRegistration.Get<IMediaLibrary>(false);
    if (mediaLibrary == null)
        throw new Exception("Unable to get reference to IMediaLibary");

    I want to query MediaItems with SeriesAspect (is this interpretation right?)
    Code:
    var serieGuids = new List<Guid> {SeriesAspect.ASPECT_ID};

    Prepare the query and add a filter
    Code:
    var combinationFilter = new BooleanCombinationFilter(BooleanOperator.And, _queryFilters);
    
    var query = new MediaItemQuery(serieGuids, combinationFilter);
    // where _queryFilters is a List of Filters like in this case
    // new RelationalFilter(SeriesAspect.ATTR_SERIESNAME, RelationalOperator.EQ, "The Name");

    Now execute the query, iterate through the results and create new objects of my SeriesType and add it to a list. Finally return the list:
    Code:
    var items = mediaLibrary.Search(query, false).ToList();
    if (!items.Any())
        return null;
    
    var result = new List<MediaportalSeriesEpisode>();
    items.ForEach(item =>
    {
        var resultItem = new MediaportalSeriesEpisode()
        {
            EpisodeName = (string)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_EPISODENAME),
            Episode = (IEnumerable<int>)((HashSet<object>)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_EPISODE))?.Cast<int>(),
            Season = (int?)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_SEASON),
            DvdEpisode = (IEnumerable<double>)((HashSet<object>)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_DVDEPISODE))?.Cast<double>(),
            FirstAired = (DateTime?)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_FIRSTAIRED),
            ImdbId = (string)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_IMDB_ID),
            RatingCount = (int?)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_RATING_COUNT),
            SeriesName = (string)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_SERIESNAME),
            SeriesSeasonName = (string)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_SERIES_SEASON),
            TvDbId = (int?)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_TVDB_ID),
            TotalRating = (double?)PossiblyGetMediaItemAspectAttributeValue(item, SeriesAspect.ATTR_TOTAL_RATING)
        };
        result.Add(resultItem);
    });

    PossiblyGetMediaItemAspectAttribute is simply a wrapper around "MediaItemAspect.TryGetAttribute(mediaItem.Aspects, seriesAspect, out result);" and returns the result.

    As you can see there are many casts and check for null values required. For Example results for ATTR_EPISODE are of type HashSet<object>, so i have to use the method .Cast<int> to it. But yes, result could be null, so there's also a null value check required.

    Do you suggest another approach here? I'm not a fan of such a code :)

    One last question: The results i'm getting are ok, but i was wondering why some fields are empty. Especially the TvDbID. It is always null, and that is in my case the query argument :-(
    But i think there is something wrong, because Mediaportal has imported these episodes and if i take a look in the local directories, i can see what it has downloaded from thetvdb, and there are folders with the TvDbIds, but they are missing in the database. Is this a bug in MP2 ? If so, i can try to fix that.
     

    Users who are viewing this thread

    Top Bottom