Jump to content

Plugin: EmbyIcons release.


Recommended Posts

yocker
Posted (edited)

Here is a beta release if any one want to test it.
Basically added a scheduled task option to refresh the icons.
This should fix the problem of some icons not being added or removed when language changes in files. When for example  subtitles are added.

The plugin isn't magic ( ;) ) so Emby needs to scan the files it self before it knowns anything has changed.
The plugin goes on not knowing about this as there for needs a scheduled task for it to look for changes.

I haven't found a way to make it reacts to changes in Emby for that yet. Either it's not possible or i'm just dumb.

TLDR: Play around with the scheduled task and see if it works for refreshing and adding/removing icons.

BETA! BETA! BETA! BETA! BETA! BETA! 
Please use in a test environment!

@Neminem
I hate to keep asking you but, you are usually willing to test. ;)

EmbyIcons.dll

Edited by yocker
Neminem
Posted

@yockerI will see if I get the time today.

Otherwise I will give it a go tomorrow.

mickle026
Posted
5 hours ago, yocker said:

Here is a beta release if any one want to test it.
Basically added a scheduled task option to refresh the icons.
This should fix the problem of some icons not being added or removed when language changes in files. When for example  subtitles are added.

The plugin isn't magic ( ;) ) so Emby needs to scan the files it self before it knowns anything has changed.
The plugin goes on not knowing about this as there for needs a scheduled task for it to look for changes.

I haven't found a way to make it reacts to changes in Emby for that yet. Either it's not possible or i'm just dumb.

TLDR: Play around with the scheduled task and see if it works for refreshing and adding/removing icons.

BETA! BETA! BETA! BETA! BETA! BETA! 
Please use in a test environment!

@Neminem
I hate to keep asking you but, you are usually willing to test. ;)

EmbyIcons.dll 1.54 MB · 0 downloads

Its a bit of a hack, but I use IMetadata saver for anything like that,  basically an adaption of the nfo writer that's triggered when anything changes to the metadata, you can of course trigger it for other things instead.  I think there is probably something else that triggers, but don't know what so I use this, it gets triggered every time there's a library scan or an individual item scan or metadata refresh etc.  The only down side is that it appears in library options as a saver and has to be turned on.

Screenshot_23-5-2025_15280_localhost.jpeg.32832abd56cfe2ba23068d8ca462ea44.jpeg

Where it goes into a save just use that to trigger something else

public static string SaverName
{
    // here is the name that appears in the Emby Library
    get
    {
        return "Local Moviedata Saver";
    }
}

public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
{
    // return true, it is enabled for BaseItem and is Movie

    if (item is Movie)
    {
        return true;
    }
    return false;
}

public Task Save(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
{

I don't know if this info will help or fit your needs, but I mention it because its an alternative.

yocker
Posted (edited)

New version up.

IMPORTANT!!!!
Please use this one instead of the last version (1.21) as a possible crash might happen in that.

Also:
Added: Button in settings made only to refresh the overlays. Move the number up or down and press save.
Note: I'm looking into making this a scheduled task.

Edited by yocker
yocker
Posted (edited)

For those that want to test:

Here is another beta.
Want to be sure it's stable before releasing it.

Whats changed:
Moved over to fully using Emby own detection for audio and subtitles. - Used to use ffprobe for external subtitles as it was a fast way of getting it to work.
Added a schedule task for refreshing icons. - This might be needed when files have changed, added or removed for icons to reflect any changes.
 

 

EmbyIcons.dll

Code.zip

Edited by yocker
yocker
Posted (edited)
7 hours ago, mickle026 said:

Its a bit of a hack, but I use IMetadata saver for anything like that,  basically an adaption of the nfo writer that's triggered when anything changes to the metadata, you can of course trigger it for other things instead.  I think there is probably something else that triggers, but don't know what so I use this, it gets triggered every time there's a library scan or an individual item scan or metadata refresh etc.  The only down side is that it appears in library options as a saver and has to be turned on.

Screenshot_23-5-2025_15280_localhost.jpeg.32832abd56cfe2ba23068d8ca462ea44.jpeg

Where it goes into a save just use that to trigger something else

public static string SaverName
{
    // here is the name that appears in the Emby Library
    get
    {
        return "Local Moviedata Saver";
    }
}

public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
{
    // return true, it is enabled for BaseItem and is Movie

    if (item is Movie)
    {
        return true;
    }
    return false;
}

public Task Save(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
{

I don't know if this info will help or fit your needs, but I mention it because its an alternative.

That looks awesome!
I really, really appreciate it!! but i must admit i think i'm starting to get out of my debts here.
This was meant as a way to learn to code and oh boy what a project to start with! :)

tried a fast and dirty version with your suggestion but couldn't get it to work with my cache clearing.
Basically as it is now i can only get icons to refresh when new settings are written and the old old made void. I have made a "band aid" fix for that with a scheduled task and it works.

If you are willing you are more than welcome to see if you can make it work better.
I would be in eternal debt and would do anything to thank you if you did! ;)

All i want now is just a fully working plugin that people will be happy about using!

Sorry.. That ended up a little like a rant but i really needed to vent my frustrations after smashing my head againts this problem i have encountered. Turns out showing overlays is easy, the rest is f'ing hard for me. :D

Edited by yocker
keitaro26
Posted
48 minutes ago, yocker said:

For those that want to test:

Here is another beta.
Want to be sure it's stable before releasing it.

Whats changed:
Moved over to fully using Emby own detection for audio and subtitles. - Used to use ffprobe for external subtitles as it was a fast way of getting it to work.
Added a schedule task for refreshing icons. - This might be needed when files have changed, added or removed for icons to reflect any changes.
 

 

EmbyIcons.dll 1.54 MB · 0 downloads

Code.zip 1.51 MB · 0 downloads

I can confirm that the beta loads images much faster for me than the current version!

  • Thanks 1
Neminem
Posted

@yockerI will have to push testing your plugin, in to the future.

I'm seeing some issues with my Beta server install, where it's keeps using more and more RAM.

I have removed you plugin and all other plugins that are not on by default, to see if its something in Beta, that's eating my memory.

 

  • Thanks 1
mickle026
Posted

A solution for you, not perfect but will work fine in your app.

@yockerAdd memory pressure at the start of your loops using parallel functions and release it at the end (or any List type loops and Linq Where(f => f) )  
(for a test you can add it at the start of your main program entry and release it when you leave, although I would only add it where you have loops or incrementing lists)


This is not a perfect solution but will limit memory usage, and heavy consumption of List Type objects (Dictionary's, Hash sets and Lists),The best way is to empty them, dispose of them, reduce the size as you go.  For your application, I very much doubt it will cause any significant speed impact just to force its usage into a managed limit..

What this does is it will allocate a certain size of memory for the objects that use a lot and keep it limited by telling the memory manager to watch this function (quite aggressively) and keep its memory usage cleaned up and reuse the space, rather that let it build up and up and up cleaning it periodically, probably after the function has finished and a huge amount has been consumed already..

long memoryUsed = GC.GetTotalMemory(false);
GC.AddMemoryPressure(memoryUsed);
Stopwatch memoryTest = Stopwatch.StartNew();
  .
  .
  .
    <you code in here>
Your logger  --  periodically log memory useage by itterations or time
  .
  .
  .
Your logger  --  "Total execution time: {stopwatch.ElapsedMilliseconds} ms"
memoryTest.Stop();
GC.RemoveMemoryPressure(memoryUsed);     

You can see how much your app is using via logging it.
 

Memory used: {memoryUsed / 1024 / 1024} MB

I suggest you test it, run it with it on, then run it with it off, Add a stopwatch and test the speed difference.

Hope this helps :) 

yocker
Posted (edited)

I think it's official now.
Emby was no made with the idea of having the TV show posters overlayed with icons.

The only thing i can do that works is simply to refresh the whole cache.

So either the clear as a schedule task stays or i will have to remove the TV show poster feature. 😕

Edited by yocker
bakes82
Posted
2 hours ago, yocker said:

Emby was no made with the idea of having the TV show posters overlayed with icons.

I dont think emby cares, at the end of the day its just an image file.... I dont understand what your issue is, why and what are you caching?

 

Also why not just hook into the LibraryManager ItemUpdated/ItemAdded events in the ServerEntryPoint. Id assume you can then trigger your logic from there?
 

private void LibraryItemAdded(object sender, ItemChangeEventArgs e)
    {
        throw new NotImplementedException();
    }

 

yocker
Posted
21 minutes ago, bakes82 said:

I dont think emby cares, at the end of the day its just an image file.... I dont understand what your issue is, why and what are you caching?

 

Also why not just hook into the LibraryManager ItemUpdated/ItemAdded events in the ServerEntryPoint. Id assume you can then trigger your logic from there?
 

private void LibraryItemAdded(object sender, ItemChangeEventArgs e)
    {
        throw new NotImplementedException();
    }

 

I'm trying to get TV show posters to get redrawn when a changes has happened to TV episodes so that the icons on the TV show poster will reflect what  audio and subtitles are available.
I might be totally wrong on this (beginner at programming.) but TV Show posters seems to be aggressively cashed by Emby so can't be singled out and have them redrawn.

Think i already tried that, can't remember at this point.
Might as well try again. :)

bakes82
Posted

Are you triggering that you updated the metadata?

 

await baseItem.RefreshMetadata(metadataOptions, CancellationToken.None);  //You can call this to pull fresh data but not replace images in the options
_libraryManager.UpdateItem(baseItem, baseItem.Parent, ItemUpdateType.ImageUpdate);
akacharos
Posted (edited)

I feel kinda dumb as I can't get the flag icons to appear in my library (running EmbyIcons 1.19.0.0).
Settings are like this:
image.thumb.png.d11ee17c11775ff2a65e84132ad08dfe.png

I've put the icons filename that I want (gre,eng) both in 2 letter and 3 letter filename format -just to be on the same side.
image.png.5355cf745dd3ae918d7e21cbc662cc37.png

I run the task in scheduler, I waited, check the log and it's processing the subtitles and audio streams fine.
Tried to refresh the metadata on these libraries just to make sure....no subtitle flag icon overlay anywhere.
What am I missing here?
 

Edited by akacharos
  • Like 1
akacharos
Posted

one suggestion for the logging by the way: Add the itemID for each log entry if possible. Currently is not helping much in troubleshooting without it as we can't check which item is being parsed:
 

[2025-05-25 03:31:24] [Embedded] Audio stream: eng => eng
[2025-05-25 03:31:24] [Embedded] Subtitle stream: eng => eng
[2025-05-25 03:31:24] [Embedded] Audio stream: und => und
[2025-05-25 03:31:24] [Embedded] Subtitle stream: el => gre

 

  • Agree 1
GrimReaper
Posted (edited)
11 minutes ago, akacharos said:

no subtitle flag icon overlay anywhere.
What am I missing here?

You're using naming convention for audio languages while having audio icons disabled. If you want subtitle flags, you need to rename those files. 

From Github link:

Quote

Important:
Icons must me named "eng.png" for audio tracks and "srt.eng.png" for subtitles, change eng with the language code you want like dan or jpn.

Edit: @yocker, maybe the above should be denoted in plugin settings? 

Edited by GrimReaper
Append
  • Agree 1
akacharos
Posted

ooops, I missed that bit. thanks so much @GrimReaper, I was going crazy with this,

  • Like 1
bakes82
Posted

@yocker I was taking a quick pass at your code to make some tweaks and Im not sure what youre even doing... Why are you calling ffprobe, this is most like what most of youre issues are.  All the information you are looking for exists in the database. I was confused as to why you cared what the file/sub extensions where in the settings as I was making them dynamic and regrouping them, and then I found this ffprobe stuff.

image.thumb.png.3e0ca88acd22ed8d05fb9571bfedf2b7.png


Every baseItem has a GetMediaStreams options where you can determine if it has audio streams or subtitles, from there you can pull out the language, not sure why you would care about the file extension

public List<EditorSelectOption> GetLanguageOptions(MediaStreamType type = MediaStreamType.Audio)
    {
        var result = new List<EditorSelectOption>();

        var items = _libraryManager.GetItemList(new InternalItemsQuery
                                                {
                                                    IsVirtualItem = false,
                                                    Recursive     = true,
                                                    HasSubtitles = true,
                                                    IncludeItemTypes = new[]
                                                                       {
                                                                           nameof(Episode),
                                                                           nameof(Movie)
                                                                       }
                                                });

        var languages = items.SelectMany(e => e.GetMediaStreams().Where(x => x.Type == type).Select(x => x.Language)).Distinct().ToList();

        foreach (var language in languages)
        {
            var option = new EditorSelectOption
                         {
                             Value     = language,
                             Name      = language,
                             IsEnabled = true
                         };
            result.Add(option);
        }

        return result.OrderBy(x => x.Name).ToList();
    }


from the rest api you can call the items endpoint and get results like this, which is what the libraymanager code above is doing
 

{
      "Name": "RuPaul-A-Palooza!",
      "ServerId": "4ddd813384cf4b87bd7ea070dd03e2ca",
      "Id": "520021",
      "Container": "mkv",
      "MediaSources": [
        {
          "Chapters": [],
          "Protocol": "File",
          "Id": "mediasource_520021",
          "Path": "/home/plex/media/TVShowsCurrent/RuPaul's Secret Celebrity Drag Race (2020)/Season 02/RuPaul's Secret Celebrity Drag Race (2020) - S02E06 - RuPaul-A-Palooza! - 371278 - x264 AAC2.0 SLAG WEBDL-1080p.mkv",
          "Type": "Default",
          "Container": "mkv",
          "Size": 1660689998,
          "Name": "RuPaul's Secret Celebrity Drag Race (2020) - S02E06 - RuPaul-A-Palooza! - 371278 - x264 AAC2.0 SLAG WEBDL-1080p",
          "IsRemote": false,
          "HasMixedProtocols": false,
          "RunTimeTicks": 25017320000,
          "SupportsTranscoding": true,
          "SupportsDirectStream": true,
          "SupportsDirectPlay": true,
          "IsInfiniteStream": false,
          "RequiresOpening": false,
          "RequiresClosing": false,
          "RequiresLooping": false,
          "SupportsProbing": false,
          "MediaStreams": [
            {
              "Codec": "h264",
              "ColorTransfer": "bt709",
              "ColorPrimaries": "bt709",
              "ColorSpace": "bt709",
              "TimeBase": "1/1000",
              "VideoRange": "SDR",
              "DisplayTitle": "1080p H264",
              "NalLengthSize": "4",
              "IsInterlaced": false,
              "BitRate": 5310528,
              "BitDepth": 8,
              "RefFrames": 1,
              "IsDefault": true,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Height": 1080,
              "Width": 1920,
              "AverageFrameRate": 29.97003,
              "RealFrameRate": 29.97003,
              "Profile": "High",
              "Type": "Video",
              "AspectRatio": "16:9",
              "Index": 0,
              "IsExternal": false,
              "IsTextSubtitleStream": false,
              "SupportsExternalStream": false,
              "Protocol": "File",
              "PixelFormat": "yuv420p",
              "Level": 40,
              "IsAnamorphic": false,
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0
            },
            {
              "Codec": "aac",
              "Language": "eng",
              "TimeBase": "1/1000",
              "DisplayTitle": "English AAC stereo (Default)",
              "DisplayLanguage": "English",
              "IsInterlaced": false,
              "ChannelLayout": "stereo",
              "BitRate": 192000,
              "Channels": 2,
              "SampleRate": 48000,
              "IsDefault": true,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Profile": "LC",
              "Type": "Audio",
              "Index": 1,
              "IsExternal": false,
              "IsTextSubtitleStream": false,
              "SupportsExternalStream": false,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0
            },
            {
              "Codec": "subrip",
              "Language": "ger",
              "TimeBase": "1/1000",
              "Title": "Deutsch",
              "DisplayTitle": "German (SUBRIP)",
              "DisplayLanguage": "German",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 2,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "eng",
              "TimeBase": "1/1000",
              "Title": "English",
              "DisplayTitle": "English (SUBRIP)",
              "DisplayLanguage": "English",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 3,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "spa",
              "TimeBase": "1/1000",
              "Title": "Español",
              "DisplayTitle": "Spanish (SUBRIP)",
              "DisplayLanguage": "Spanish",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 4,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "fre",
              "TimeBase": "1/1000",
              "Title": "Français",
              "DisplayTitle": "French (SUBRIP)",
              "DisplayLanguage": "French",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 5,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "ind",
              "TimeBase": "1/1000",
              "Title": "Indonesia",
              "DisplayTitle": "Indonesian (SUBRIP)",
              "DisplayLanguage": "Indonesian",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 6,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "ita",
              "TimeBase": "1/1000",
              "Title": "Italiano",
              "DisplayTitle": "Italian (SUBRIP)",
              "DisplayLanguage": "Italian",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 7,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "dut",
              "TimeBase": "1/1000",
              "Title": "Nederlands",
              "DisplayTitle": "Dutch (SUBRIP)",
              "DisplayLanguage": "Dutch",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 8,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "por",
              "TimeBase": "1/1000",
              "Title": "Português",
              "DisplayTitle": "Portuguese (SUBRIP)",
              "DisplayLanguage": "Portuguese",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 9,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "ara",
              "TimeBase": "1/1000",
              "Title": "العربية",
              "DisplayTitle": "Arabic (SUBRIP)",
              "DisplayLanguage": "Arabic",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 10,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "chi",
              "TimeBase": "1/1000",
              "Title": "中文",
              "DisplayTitle": "Chinese Simplified (SUBRIP)",
              "DisplayLanguage": "Chinese Simplified",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 11,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "jpn",
              "TimeBase": "1/1000",
              "Title": "日本語",
              "DisplayTitle": "Japanese (SUBRIP)",
              "DisplayLanguage": "Japanese",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 12,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "kor",
              "TimeBase": "1/1000",
              "Title": "한국어",
              "DisplayTitle": "Korean (SUBRIP)",
              "DisplayLanguage": "Korean",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 13,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            }
          ],
          "Formats": [],
          "Bitrate": 5310528,
          "RequiredHttpHeaders": {},
          "AddApiKeyToDirectStreamUrl": false,
          "ReadAtNativeFramerate": false,
          "ItemId": "520021"
        }
      ],
      "RunTimeTicks": 25017320000,
      "Size": 1660689998,
      "Bitrate": 5310528,
      "IndexNumber": 6,
      "ParentIndexNumber": 2,
      "IsFolder": false,
      "Type": "Episode",
      "ParentLogoItemId": "395792",
      "ParentBackdropItemId": "395792",
      "ParentBackdropImageTags": [
        "3d176bdab8ad47c88676035e1943c24f"
      ],
      "SeriesName": "RuPaul's Secret Celebrity Drag Race",
      "SeriesId": "395792",
      "SeasonId": "520018",
      "SeriesPrimaryImageTag": "c092746ee53f9e574ed8bf334501aad9",
      "SeasonName": "Season 2",
      "MediaStreams": [
        {
          "Codec": "h264",
          "ColorTransfer": "bt709",
          "ColorPrimaries": "bt709",
          "ColorSpace": "bt709",
          "TimeBase": "1/1000",
          "VideoRange": "SDR",
          "DisplayTitle": "1080p H264",
          "NalLengthSize": "4",
          "IsInterlaced": false,
          "BitRate": 5310528,
          "BitDepth": 8,
          "RefFrames": 1,
          "IsDefault": true,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Height": 1080,
          "Width": 1920,
          "AverageFrameRate": 29.97003,
          "RealFrameRate": 29.97003,
          "Profile": "High",
          "Type": "Video",
          "AspectRatio": "16:9",
          "Index": 0,
          "IsExternal": false,
          "IsTextSubtitleStream": false,
          "SupportsExternalStream": false,
          "Protocol": "File",
          "PixelFormat": "yuv420p",
          "Level": 40,
          "IsAnamorphic": false,
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0
        },
        {
          "Codec": "aac",
          "Language": "eng",
          "TimeBase": "1/1000",
          "DisplayTitle": "English AAC stereo (Default)",
          "DisplayLanguage": "English",
          "IsInterlaced": false,
          "ChannelLayout": "stereo",
          "BitRate": 192000,
          "Channels": 2,
          "SampleRate": 48000,
          "IsDefault": true,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Profile": "LC",
          "Type": "Audio",
          "Index": 1,
          "IsExternal": false,
          "IsTextSubtitleStream": false,
          "SupportsExternalStream": false,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0
        },
        {
          "Codec": "subrip",
          "Language": "ger",
          "TimeBase": "1/1000",
          "Title": "Deutsch",
          "DisplayTitle": "German (SUBRIP)",
          "DisplayLanguage": "German",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 2,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "eng",
          "TimeBase": "1/1000",
          "Title": "English",
          "DisplayTitle": "English (SUBRIP)",
          "DisplayLanguage": "English",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 3,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "spa",
          "TimeBase": "1/1000",
          "Title": "Español",
          "DisplayTitle": "Spanish (SUBRIP)",
          "DisplayLanguage": "Spanish",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 4,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "fre",
          "TimeBase": "1/1000",
          "Title": "Français",
          "DisplayTitle": "French (SUBRIP)",
          "DisplayLanguage": "French",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 5,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "ind",
          "TimeBase": "1/1000",
          "Title": "Indonesia",
          "DisplayTitle": "Indonesian (SUBRIP)",
          "DisplayLanguage": "Indonesian",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 6,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "ita",
          "TimeBase": "1/1000",
          "Title": "Italiano",
          "DisplayTitle": "Italian (SUBRIP)",
          "DisplayLanguage": "Italian",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 7,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "dut",
          "TimeBase": "1/1000",
          "Title": "Nederlands",
          "DisplayTitle": "Dutch (SUBRIP)",
          "DisplayLanguage": "Dutch",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 8,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "por",
          "TimeBase": "1/1000",
          "Title": "Português",
          "DisplayTitle": "Portuguese (SUBRIP)",
          "DisplayLanguage": "Portuguese",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 9,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "ara",
          "TimeBase": "1/1000",
          "Title": "العربية",
          "DisplayTitle": "Arabic (SUBRIP)",
          "DisplayLanguage": "Arabic",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 10,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "chi",
          "TimeBase": "1/1000",
          "Title": "中文",
          "DisplayTitle": "Chinese Simplified (SUBRIP)",
          "DisplayLanguage": "Chinese Simplified",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 11,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "jpn",
          "TimeBase": "1/1000",
          "Title": "日本語",
          "DisplayTitle": "Japanese (SUBRIP)",
          "DisplayLanguage": "Japanese",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 12,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "kor",
          "TimeBase": "1/1000",
          "Title": "한국어",
          "DisplayTitle": "Korean (SUBRIP)",
          "DisplayLanguage": "Korean",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 13,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        }
      ],
      "ImageTags": {
        "Primary": "b660265328f5bcd291a0cd393cfa58d2"
      },
      "BackdropImageTags": [],
      "ParentLogoImageTag": "df2abf6a4cf32b008b4852dba98b6c91",
      "MediaType": "Video"
    },
    

 

yocker
Posted
4 minutes ago, bakes82 said:

@yocker I was taking a quick pass at your code to make some tweaks and Im not sure what youre even doing... Why are you calling ffprobe, this is most like what most of youre issues are.  All the information you are looking for exists in the database. I was confused as to why you cared what the file/sub extensions where in the settings as I was making them dynamic and regrouping them, and then I found this ffprobe stuff.

image.thumb.png.3e0ca88acd22ed8d05fb9571bfedf2b7.png


Every baseItem has a GetMediaStreams options where you can determine if it has audio streams or subtitles, from there you can pull out the language, not sure why you would care about the file extension

public List<EditorSelectOption> GetLanguageOptions(MediaStreamType type = MediaStreamType.Audio)
    {
        var result = new List<EditorSelectOption>();

        var items = _libraryManager.GetItemList(new InternalItemsQuery
                                                {
                                                    IsVirtualItem = false,
                                                    Recursive     = true,
                                                    HasSubtitles = true,
                                                    IncludeItemTypes = new[]
                                                                       {
                                                                           nameof(Episode),
                                                                           nameof(Movie)
                                                                       }
                                                });

        var languages = items.SelectMany(e => e.GetMediaStreams().Where(x => x.Type == type).Select(x => x.Language)).Distinct().ToList();

        foreach (var language in languages)
        {
            var option = new EditorSelectOption
                         {
                             Value     = language,
                             Name      = language,
                             IsEnabled = true
                         };
            result.Add(option);
        }

        return result.OrderBy(x => x.Name).ToList();
    }


from the rest api you can call the items endpoint and get results like this, which is what the libraymanager code above is doing
 

{
      "Name": "RuPaul-A-Palooza!",
      "ServerId": "4ddd813384cf4b87bd7ea070dd03e2ca",
      "Id": "520021",
      "Container": "mkv",
      "MediaSources": [
        {
          "Chapters": [],
          "Protocol": "File",
          "Id": "mediasource_520021",
          "Path": "/home/plex/media/TVShowsCurrent/RuPaul's Secret Celebrity Drag Race (2020)/Season 02/RuPaul's Secret Celebrity Drag Race (2020) - S02E06 - RuPaul-A-Palooza! - 371278 - x264 AAC2.0 SLAG WEBDL-1080p.mkv",
          "Type": "Default",
          "Container": "mkv",
          "Size": 1660689998,
          "Name": "RuPaul's Secret Celebrity Drag Race (2020) - S02E06 - RuPaul-A-Palooza! - 371278 - x264 AAC2.0 SLAG WEBDL-1080p",
          "IsRemote": false,
          "HasMixedProtocols": false,
          "RunTimeTicks": 25017320000,
          "SupportsTranscoding": true,
          "SupportsDirectStream": true,
          "SupportsDirectPlay": true,
          "IsInfiniteStream": false,
          "RequiresOpening": false,
          "RequiresClosing": false,
          "RequiresLooping": false,
          "SupportsProbing": false,
          "MediaStreams": [
            {
              "Codec": "h264",
              "ColorTransfer": "bt709",
              "ColorPrimaries": "bt709",
              "ColorSpace": "bt709",
              "TimeBase": "1/1000",
              "VideoRange": "SDR",
              "DisplayTitle": "1080p H264",
              "NalLengthSize": "4",
              "IsInterlaced": false,
              "BitRate": 5310528,
              "BitDepth": 8,
              "RefFrames": 1,
              "IsDefault": true,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Height": 1080,
              "Width": 1920,
              "AverageFrameRate": 29.97003,
              "RealFrameRate": 29.97003,
              "Profile": "High",
              "Type": "Video",
              "AspectRatio": "16:9",
              "Index": 0,
              "IsExternal": false,
              "IsTextSubtitleStream": false,
              "SupportsExternalStream": false,
              "Protocol": "File",
              "PixelFormat": "yuv420p",
              "Level": 40,
              "IsAnamorphic": false,
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0
            },
            {
              "Codec": "aac",
              "Language": "eng",
              "TimeBase": "1/1000",
              "DisplayTitle": "English AAC stereo (Default)",
              "DisplayLanguage": "English",
              "IsInterlaced": false,
              "ChannelLayout": "stereo",
              "BitRate": 192000,
              "Channels": 2,
              "SampleRate": 48000,
              "IsDefault": true,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Profile": "LC",
              "Type": "Audio",
              "Index": 1,
              "IsExternal": false,
              "IsTextSubtitleStream": false,
              "SupportsExternalStream": false,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0
            },
            {
              "Codec": "subrip",
              "Language": "ger",
              "TimeBase": "1/1000",
              "Title": "Deutsch",
              "DisplayTitle": "German (SUBRIP)",
              "DisplayLanguage": "German",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 2,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "eng",
              "TimeBase": "1/1000",
              "Title": "English",
              "DisplayTitle": "English (SUBRIP)",
              "DisplayLanguage": "English",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 3,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "spa",
              "TimeBase": "1/1000",
              "Title": "Español",
              "DisplayTitle": "Spanish (SUBRIP)",
              "DisplayLanguage": "Spanish",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 4,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "fre",
              "TimeBase": "1/1000",
              "Title": "Français",
              "DisplayTitle": "French (SUBRIP)",
              "DisplayLanguage": "French",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 5,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "ind",
              "TimeBase": "1/1000",
              "Title": "Indonesia",
              "DisplayTitle": "Indonesian (SUBRIP)",
              "DisplayLanguage": "Indonesian",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 6,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "ita",
              "TimeBase": "1/1000",
              "Title": "Italiano",
              "DisplayTitle": "Italian (SUBRIP)",
              "DisplayLanguage": "Italian",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 7,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "dut",
              "TimeBase": "1/1000",
              "Title": "Nederlands",
              "DisplayTitle": "Dutch (SUBRIP)",
              "DisplayLanguage": "Dutch",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 8,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "por",
              "TimeBase": "1/1000",
              "Title": "Português",
              "DisplayTitle": "Portuguese (SUBRIP)",
              "DisplayLanguage": "Portuguese",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 9,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "ara",
              "TimeBase": "1/1000",
              "Title": "العربية",
              "DisplayTitle": "Arabic (SUBRIP)",
              "DisplayLanguage": "Arabic",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 10,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "chi",
              "TimeBase": "1/1000",
              "Title": "中文",
              "DisplayTitle": "Chinese Simplified (SUBRIP)",
              "DisplayLanguage": "Chinese Simplified",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 11,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "jpn",
              "TimeBase": "1/1000",
              "Title": "日本語",
              "DisplayTitle": "Japanese (SUBRIP)",
              "DisplayLanguage": "Japanese",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 12,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            },
            {
              "Codec": "subrip",
              "Language": "kor",
              "TimeBase": "1/1000",
              "Title": "한국어",
              "DisplayTitle": "Korean (SUBRIP)",
              "DisplayLanguage": "Korean",
              "IsInterlaced": false,
              "IsDefault": false,
              "IsForced": false,
              "IsHearingImpaired": false,
              "Type": "Subtitle",
              "Index": 13,
              "IsExternal": false,
              "IsTextSubtitleStream": true,
              "SupportsExternalStream": true,
              "Protocol": "File",
              "ExtendedVideoType": "None",
              "ExtendedVideoSubType": "None",
              "ExtendedVideoSubTypeDescription": "None",
              "AttachmentSize": 0,
              "SubtitleLocationType": "InternalStream"
            }
          ],
          "Formats": [],
          "Bitrate": 5310528,
          "RequiredHttpHeaders": {},
          "AddApiKeyToDirectStreamUrl": false,
          "ReadAtNativeFramerate": false,
          "ItemId": "520021"
        }
      ],
      "RunTimeTicks": 25017320000,
      "Size": 1660689998,
      "Bitrate": 5310528,
      "IndexNumber": 6,
      "ParentIndexNumber": 2,
      "IsFolder": false,
      "Type": "Episode",
      "ParentLogoItemId": "395792",
      "ParentBackdropItemId": "395792",
      "ParentBackdropImageTags": [
        "3d176bdab8ad47c88676035e1943c24f"
      ],
      "SeriesName": "RuPaul's Secret Celebrity Drag Race",
      "SeriesId": "395792",
      "SeasonId": "520018",
      "SeriesPrimaryImageTag": "c092746ee53f9e574ed8bf334501aad9",
      "SeasonName": "Season 2",
      "MediaStreams": [
        {
          "Codec": "h264",
          "ColorTransfer": "bt709",
          "ColorPrimaries": "bt709",
          "ColorSpace": "bt709",
          "TimeBase": "1/1000",
          "VideoRange": "SDR",
          "DisplayTitle": "1080p H264",
          "NalLengthSize": "4",
          "IsInterlaced": false,
          "BitRate": 5310528,
          "BitDepth": 8,
          "RefFrames": 1,
          "IsDefault": true,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Height": 1080,
          "Width": 1920,
          "AverageFrameRate": 29.97003,
          "RealFrameRate": 29.97003,
          "Profile": "High",
          "Type": "Video",
          "AspectRatio": "16:9",
          "Index": 0,
          "IsExternal": false,
          "IsTextSubtitleStream": false,
          "SupportsExternalStream": false,
          "Protocol": "File",
          "PixelFormat": "yuv420p",
          "Level": 40,
          "IsAnamorphic": false,
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0
        },
        {
          "Codec": "aac",
          "Language": "eng",
          "TimeBase": "1/1000",
          "DisplayTitle": "English AAC stereo (Default)",
          "DisplayLanguage": "English",
          "IsInterlaced": false,
          "ChannelLayout": "stereo",
          "BitRate": 192000,
          "Channels": 2,
          "SampleRate": 48000,
          "IsDefault": true,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Profile": "LC",
          "Type": "Audio",
          "Index": 1,
          "IsExternal": false,
          "IsTextSubtitleStream": false,
          "SupportsExternalStream": false,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0
        },
        {
          "Codec": "subrip",
          "Language": "ger",
          "TimeBase": "1/1000",
          "Title": "Deutsch",
          "DisplayTitle": "German (SUBRIP)",
          "DisplayLanguage": "German",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 2,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "eng",
          "TimeBase": "1/1000",
          "Title": "English",
          "DisplayTitle": "English (SUBRIP)",
          "DisplayLanguage": "English",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 3,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "spa",
          "TimeBase": "1/1000",
          "Title": "Español",
          "DisplayTitle": "Spanish (SUBRIP)",
          "DisplayLanguage": "Spanish",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 4,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "fre",
          "TimeBase": "1/1000",
          "Title": "Français",
          "DisplayTitle": "French (SUBRIP)",
          "DisplayLanguage": "French",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 5,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "ind",
          "TimeBase": "1/1000",
          "Title": "Indonesia",
          "DisplayTitle": "Indonesian (SUBRIP)",
          "DisplayLanguage": "Indonesian",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 6,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "ita",
          "TimeBase": "1/1000",
          "Title": "Italiano",
          "DisplayTitle": "Italian (SUBRIP)",
          "DisplayLanguage": "Italian",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 7,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "dut",
          "TimeBase": "1/1000",
          "Title": "Nederlands",
          "DisplayTitle": "Dutch (SUBRIP)",
          "DisplayLanguage": "Dutch",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 8,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "por",
          "TimeBase": "1/1000",
          "Title": "Português",
          "DisplayTitle": "Portuguese (SUBRIP)",
          "DisplayLanguage": "Portuguese",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 9,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "ara",
          "TimeBase": "1/1000",
          "Title": "العربية",
          "DisplayTitle": "Arabic (SUBRIP)",
          "DisplayLanguage": "Arabic",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 10,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "chi",
          "TimeBase": "1/1000",
          "Title": "中文",
          "DisplayTitle": "Chinese Simplified (SUBRIP)",
          "DisplayLanguage": "Chinese Simplified",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 11,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "jpn",
          "TimeBase": "1/1000",
          "Title": "日本語",
          "DisplayTitle": "Japanese (SUBRIP)",
          "DisplayLanguage": "Japanese",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 12,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
        {
          "Codec": "subrip",
          "Language": "kor",
          "TimeBase": "1/1000",
          "Title": "한국어",
          "DisplayTitle": "Korean (SUBRIP)",
          "DisplayLanguage": "Korean",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 13,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        }
      ],
      "ImageTags": {
        "Primary": "b660265328f5bcd291a0cd393cfa58d2"
      },
      "BackdropImageTags": [],
      "ParentLogoImageTag": "df2abf6a4cf32b008b4852dba98b6c91",
      "MediaType": "Video"
    },
    

 

Because i had problems with getting it to recognize when subtitles had chanced so as a temporary fix i used ffprobe.
It had no noticeable performance impact so was of low priority to change while i got other things to work.
It doesn't use that any more and solely relies on Emby.

The file extensions setting for were just meant for my own testing purposes.
It hasn't been part of my internal version for a while now.

Something else though.
I finally got it working as it should. I'm no people person and i usually don't like most contact but i could kiss you for this :) 

await baseItem.RefreshMetadata(metadataOptions, CancellationToken.None); //You can call this to pull fresh data but not replace images in the options _libraryManager.UpdateItem(baseItem, baseItem.Parent, ItemUpdateType.ImageUpdate);

I might have been an idiot for missing that but as said i'm new at all this. ;)

yocker
Posted (edited)

Here is a version i would like people to test for a couple of days.

It now reacts solely on Emby own internals workings, the posters should auto update now (thank you Bakes82) as they should and it should run smoother than before.

The delay setting in the settings menus are for slower systems as to not bog them down when scanning files or refreshing metadata.
Don't set it to low, 2-3 seconds should be fine.
This setting is more or a "just in case", i will most likely remove it later when i'm absolutely sure that all systems can handle this.

Lastly:
BETA! BETA! BETA! BETA! BETA! BETA! 
The plugin should be 100% safe but it just haven't been tested yet and is fresh of the presses.
Use at your own risk!
 

 

Edited by yocker
  • Like 1
bakes82
Posted

@yockerHere is an updated framework that I usually use for all my plugins, it uses more the the Emby UI tooling and not just the "easy" option you were.

https://github.com/bakes82/EmbyIcons

Look at EmbyIconsConfigPluginPageView as it will have all the logic you need, from there you should be able to back track, I also included some samples. I tend to keep everything in emby so I also put the sample for writing activities, and drop down examples, you should just need to update the "RunJob" section with your logic, all the drop downs if they are multi pick are CSV stored.

 

  • Like 1
yocker
Posted

Uploaded the wrong file by mistake before, it was an old middle of the road version.
Very sorry about that.

This is the one to test.

EmbyIcons.dll

yocker
Posted
46 minutes ago, bakes82 said:

@yockerHere is an updated framework that I usually use for all my plugins, it uses more the the Emby UI tooling and not just the "easy" option you were.

https://github.com/bakes82/EmbyIcons

Look at EmbyIconsConfigPluginPageView as it will have all the logic you need, from there you should be able to back track, I also included some samples. I tend to keep everything in emby so I also put the sample for writing activities, and drop down examples, you should just need to update the "RunJob" section with your logic, all the drop downs if they are multi pick are CSV stored.

 

Many thanks, i will look it up first thing a when i have a little time!
Appreciate it!

keitaro26
Posted
3 minutes ago, yocker said:

Uploaded the wrong file by mistake before, it was an old middle of the road version.
Very sorry about that.

This is the one to test.

EmbyIcons.dll 1.54 MB · 0 downloads

When I try to turn on the auto-refresh, I get this error:

image.thumb.png.438b09ee7ea6a4103f199d136d20f301.png

  • Thanks 1
yocker
Posted
3 minutes ago, keitaro26 said:

When I try to turn on the auto-refresh, I get this error:

image.thumb.png.438b09ee7ea6a4103f199d136d20f301.png

I thought something like this would happen for some.
Just disable it for now. Emby has it's own filewatcher, i just wanted to see if i could do a better job than it and make sure icons got drawn all the time

Thanks for testing!

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...