Jump to content

ICustomMetadataProvider empty input


h.buckle

Recommended Posts

h.buckle

After reading about custom metadata providers here I wanted to add a small one to do a bit of post-processing after the remote providers have run.

I've added this class

 

using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;

namespace JsonMetadata.Providers {
  public sealed class PersonNormalisationProvider : ICustomMetadataProvider<Person>, IMetadataProvider<Person>, ICustomMetadataProvider, IMetadataProvider, IForcedProvider {
    private readonly ILogger _logger;
    private readonly IJsonSerializer _jsonSerializer;
    public PersonNormalisationProvider(ILogger logger, IJsonSerializer jsonSerializer) {
      _logger = logger;
      _jsonSerializer = jsonSerializer;
    }
    public string Name => "PersonNormalisationProvider";

    public Task<ItemUpdateType> FetchAsync(MetadataResult<Person> metadataResult, MetadataRefreshOptions options, LibraryOptions libraryOptions, CancellationToken cancellationToken) {
      if (metadataResult.HasMetadata) {
        Person item = metadataResult.Item;
        // do things
        return Task.FromResult(ItemUpdateType.MetadataEdit);
      }
      else {
        return Task.FromResult(ItemUpdateType.None);
      }
    }
  }
}

 

However the metadataResult object seems to always be empty - it always comes out like this if I log it using jsonSerializer

 

{
  "Item": {
    "ImportedCollections": null
  },
  "BaseItem": {
    "ImportedCollections": null
  },
  "Images": [],
  "SearchImageUrl": null,
  "UserDataList": null,
  "People": null,
  "ListItems": null,
  "MediaStreams": null,
  "Chapters": null,
  "HasMetadata": false,
  "ResultLanguage": "en",
  "Provider": null,
  "QueriedById": false
}
 
Any idea what I need to do to get the actual item passed in?
Link to comment
Share on other sites

Set up debugging as explained here: https://betadev.emby.media/doc/plugins/dev/index.html#debugging

The metadata result properties are not populated because custom metadata providers are run after the remote provider metadata has already been applied to the items.

Yet, the .Item property is not null - it has at least serialized the ImportedCollections property, but all other properties are disabled for serialization, that's why you don't see them when serializing.

 

Link to comment
Share on other sites

h.buckle

OK I think that makes sense now - I was thinking the complete item would be passed in. Is the correct workflow then to get the complete item with LibraryManager and then update the MetadataResult with any changed properties?

Link to comment
Share on other sites

1 minute ago, h.buckle said:

OK I think that makes sense now - I was thinking the complete item would be passed in

1. No
2. Yes, the complete item is passed in

2 minutes ago, h.buckle said:

Is the correct workflow then to get the complete item with LibraryManager and then update the MetadataResult with any changed properties?

No. The workflow is correct exactly like in your code snippet.

Link to comment
Share on other sites

h.buckle

Mmmm, that doesn't seem to match what I'm seeing. If I change to this

 

public Task<ItemUpdateType> FetchAsync(MetadataResult<Person> metadataResult, MetadataRefreshOptions options, LibraryOptions libraryOptions, CancellationToken cancellationToken) {
  Person item = metadataResult.Item;
  _logger.Log(LogSeverity.Info, $"JsonMetadata: {item.Overview}");
  return Task.FromResult(ItemUpdateType.MetadataEdit);
}

This is what I see in the log

 

Quote
2023-03-27 09:57:57.875 Debug SqliteItemRepository: GetitemById Person 1377783 Taraji P. Henson
2023-03-27 09:57:57.896 Debug DataExplorerService: Running TheMovieDb (MovieDbPersonProvider) for Taraji P. Henson
2023-03-27 09:57:57.926 Debug DataExplorerService: >>>>>> TheMovieDb returned metadata for Taraji P. Henson
2023-03-27 09:57:57.926 Debug DataExplorerService: Running PersonNormalisationProvider (PersonNormalisationProvider) for Taraji P. Henson
2023-03-27 09:57:57.927 Info App: JsonMetadata: 
2023-03-27 09:57:57.928 Debug DataExplorerService: >>>>>> PersonNormalisationProvider returned metadata for Taraji P. Henson

 

The Overview property should be present, as it is populated from the TmdbProvider, which runs previously?

Link to comment
Share on other sites

The Data Explorer Service is not normal Emby operation. It works differently and runs all providers in an isolated way. Not even the remote metadata providers are seeing the results from other remote providers. This is for being able to clearly show which data is coming from which provider.

Also it never saves any data to the items.

You need to use the context menu on the item and choose "Refresh Metadata".

Link to comment
Share on other sites

h.buckle

Ahh you are right, I was using the data explorer as a quicker way to test without refreshing all the time.

I guess it means data explorer can't really test custom providers then, if they don't get the full item passed in that way?

Link to comment
Share on other sites

38 minutes ago, h.buckle said:

Ahh you are right, I was using the data explorer as a quicker way to test without refreshing all the time.

I guess it means data explorer can't really test custom providers then, if they don't get the full item passed in that way?

Metadata providers are actually meant to provide metadata rather than to modify existing data and data explorer can really test such providers.

As said above, data explorer executes every provider in an isolated way - as if it was the only available provider. For custom metadata providers, it creates an empty item object with nothing else but the path of the item.

Example: The ffprobe provider is a custom metadata provider. After executing it, the DataExplorer is able to show you in the UI exactly the data that came from the ffprobe provider (because the item it supplies didn't have any other data before).

 

Custom providers which do not provide but modify existing data are an accepted edge case. But if such provider does not add any data but just modifies existing data, the Data Explorer will always show that provider with all data empty - because it doesn't actually "provide" any data.

Data Explorer can be useful for testing providers as it eliminates the influence of other providers - I've used that myself. But it can't and shouldn't be used a replacement for testing behavior in the actual context of provider execution. And in your specific case (modifying existing data), it's not useful at all.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...