Jump to content

Aperture - AI-Powered Recommendations for Emby


Recommended Posts

TheGru
Posted
13 minutes ago, Jdiesel said:

Is it as simple as just having the option in Emby to exclude an entire library from "continued watching"? Or is there still a linkage with the "Display in secondary home screen sections such as latest media and continue watching" setting? Aperture is everything I wanted with the smart playlists functionality but even better, this little bug with Emby is a pretty significant showstopper though. I can't roll it out to users as it currently stands because I don't want to deal with the questions about duplicate entries.

Β 

I really hope Emby can provide a solution.Β 

Β 

You and me both! Most support is about Continue Watching dupes!!

TheGru
Posted (edited)

Upside is you can resume either dupe in continue watching, it's just cosmetically strange

Edited by TheGru
TheGru
Posted

Aperture v0.5.3 Release Notes

Hey everyone! πŸ‘‹

This release adds OpenRouter support as a new AI provider, along with custom model persistence and provider logo improvements.


πŸ€– OpenRouter Provider Support - @akacharosI didn't forget about you!

You can now use OpenRouter as your AI provider! OpenRouter gives you access to hundreds of models from different providers through a single API.

How to Use

  • Go to Admin β†’ Settings β†’ AI / LLM
  • Select OpenRouter from the provider dropdown
  • Enter your API key from openrouter.ai/keys
  • Click Add Custom Model... to enter any model name
  • Test the connection and save

I HAVE NOT TESTED THIS AS I DO NOT HAVE AN OPENROUTER ACCOUNT. PLEASE PROVIDE FEEDBACK!

Custom Models Only

OpenRouter doesn't have a prebuilt model list β€” you enter the exact model ID you want to use:

  • anthropic/claude-3.5-sonnet
  • openai/gpt-4o
  • google/gemini-2.0-flash
  • meta-llama/llama-3.3-70b-instruct

Find available models at openrouter.ai/models.

Be advised, it is entirely possible that your model selection will be problematic with Aperture.
Please understand I will not be providing support for every LLM permutation in the world.

If you get it to work well feel free to PM me with your Provider and Model selection settings and I will put together a Google Sheet of what does and does not work.

image.png.fa2048cefc8746457dd73d8d85fb4a25.png


πŸ’Ύ Custom Model Persistence - ThanksΒ @GoldSpacerΒ for reporting the issue.

Custom models for Ollama, OpenAI-Compatible, and OpenRouter providers are now saved to the database.

What This Means

  • Before β€” Custom models were lost when you refreshed the page
  • After β€” Custom models persist across sessions and server restarts

Test Before Save

Custom models now require a successful connection test before they can be added. This prevents typos and ensures the model actually works.

Β image.png.6a42809c2c9de9e61085aa94cf0c09b3.png

image.png.9d010aacd90992105c798208b793b63d.png


🎨 Provider Logos

The AI provider dropdown now shows actual provider logos instead of generic cloud icons.

Provider Logo
OpenAI βœ“
Anthropic βœ“
Ollama βœ“
OpenRouter βœ“
Groq βœ“
DeepSeek βœ“
Google AI βœ“

image.png.2e3c6dd80b1eb8e6bd3ef2517cd11343.png


🧠 Anthropic Model Updates

Added all current Claude models:

Model Description
Claude Opus 4.5 Most capable. Extended thinking, web search, tool search, wildly expensive
Claude Sonnet 4.5 Best balance of speed and intelligence
Claude Haiku 4.5 Fast and efficient for high-volume tasks
Claude Opus 4.1 Previous generation flagship
Claude Sonnet 4 Balanced performance with tool use
Claude 3.7 Sonnet Extended thinking support
Claude 3.5 Sonnet Excellent for coding and analysis
Claude 3.5 Haiku Fast and cost-effective

Docker SESSION_SECRET Fix

Fixed potential YAML parsing issues with SESSION_SECRET in docker-compose files by properly quoting the value.


πŸš€ Update Instructions

For Docker Users

# Pull the latest image
docker compose pull

# Restart with new version
docker compose up -d

Database Migration

The update includes a database migration (0090_openrouter_provider.sql) that runs automatically on startup.

Post-Update Steps

  • Clear browser cache β€” Or hard refresh (Cmd+Shift+R / Ctrl+Shift+R)

Enjoy OpenRouter support! πŸš€

  • Thanks 1
TheGru
Posted

🎯 My Wild Idea For Preventing Duplicate "Continue Watching" Entries

Hey everyone,

I want to get your feedback on a proposed solution to a common annoyance before I build it.

The Problem

When you watch a movie or show from an Aperture recommendation library, you might see duplicate entries in "Continue Watching" - one for the original item in your library, and one for the Aperture copy.

Why this happens

This happens because Emby links items together by their IMDB/TMDB IDs. When both the original and the Aperture STRM file share the same IDs, the media server treats them as related and syncs playback state between them.

The ideal fix would be for Emby to add a "Hide from Continue Watching" option per-library, so we could exclude Aperture libraries from that home row entirely. But until the devs add that feature, we need a workaround.

The Proposed Workaround (It's Workarounds All The Way Down)

Part 1: Fix the duplicates with prefixed IDs

Instead of using real provider IDs:

IMDB: tt1234567
TMDB: 12345

Aperture would write "prefixed" IDs in NFO files:

IMDB: aperture-tt1234567
TMDB: aperture-12345

Why this fixes duplicates:

  • Emby sees aperture-tt1234567 and won't link it to the original tt1234567
  • No more duplicate Continue Watching entries

But this creates a NEW problem: Now when you watch something from an Aperture library, the watch history doesn't track back to the original. The original item in your real library won't show as "watched" because Emby can't match the prefixed ID to anything.


Part 2: Fix the watch history problem with attribution sync

So we need a workaround for the workaround. πŸ˜…

During the watch history sync job, Aperture would:

  • Detect items with aperture- prefixed IDs that were played
  • Strip the prefix to get the real IMDB/TMDB ID
  • Find the original item in your library by that ID
  • Mark the original as watched in Emby via API
  • Record the watch history in Aperture's database

This way, your original library stays accurate - items you watch via Aperture recommendations still show as "watched" in your real Movies/TV library. It just happens on a delay (every 30 minutes) rather than instantly.


Alternative: Webhooks (real-time, but more setup)

I could make the watch history attribution happen in real-time using Emby webhooks. When playback ends, the media server would immediately notify Aperture, which could then mark the original as watched right away.

But this would require server admins to:

  • Install the webhooks plugin (Emby)
  • Set up the webhook URL pointing to Aperture
  • Configure which events to send

That's a lot of extra work and configuration for users, and more stuff I do not want to provide support for, so I'm leaning toward the polling approach (30-minute sync) that works out of the box with zero additional setup.

Trade-offs

  • ~30 minute delay before originals get marked as watched (sync runs every 30 min, you can adjust to your liking but this is what I would make my default)
  • Requires Aperture library resync to Emby after enabling/disabling
  • It's a workaround for a workaround - not elegant, but functional
  • Would be an opt-in toggle in Admin Settings (disabled by default, labeled as "Experimental")

Questions for You

  • Is duplicate Continue Watching actually bothering you? Or is this a non-issue for most people?

  • Would you enable this feature? Even knowing it's a stack of workarounds with trade-offs?

  • Any concerns or edge cases I'm not thinking of?

  • Better ideas? If you know of a cleaner approach, I'm all ears.


Looking forward to your thoughts. If there's enough interest and no major red flags, I'll build it as an optional feature in an upcoming release.

Jdiesel
Posted (edited)
18 minutes ago, TheGru said:
  • Is duplicate Continue Watching actually bothering you? It bothers me but I'm a bit OCD. It also slightly bothers me that the Aperture library shows the filename instead of the "clean" name.

  • Would you enable this feature?Β I would possibly setup a webhook to sync this but I don't mind mucking around with a more complex setup. I imagine most users won't.

  • Any concerns or edge casesΒ Nothing jumps out

  • Better ideas?Β This is really a case of adding unneeded complexity for something that could (should) be addressed as a core Emby function. Not just for this app but for other uses cases like you previously mentions. Example: Having a separateΒ HD and a 4K library where there are duplicate entries

IMO this is an excellent opportunity for Emby devs to demonstrate that they are 3rd party Dev friendly. We all know this won't be an issue on Jellyfin and it will be yet another reason to switch over to Jellyfin.Β 

Edited by Jdiesel
  • Like 2
TheGru
Posted
8 minutes ago, Jdiesel said:

Is duplicate Continue Watching actually bothering you? It bothers me but I'm a bit OCD. It also slightly bothers me that the Aperture library shows the filename instead of the "clean" name.

What do you mean about FILENAME? can you send a screenshot? I am not experiencing that, nor should you be. I am literally ingesting 100% of the original metadata and outputting it in to the NFO files created by aperture.Β 

Jdiesel
Posted
4 minutes ago, TheGru said:

What do you mean about FILENAME? can you send a screenshot? I am not experiencing that, nor should you be. I am literally ingesting 100% of the original metadata and outputting it in to the NFO files created by aperture.Β 

Aperture library

Screenshot2026-01-175_04_12PM.thumb.png.faa72f6a07c6ffb5ea5869274f9b1e02.png

Screenshot2026-01-175_04_50PM.thumb.png.bb9d61035d423c921e742bc9b693535e.png

Β 

Emby library

Screenshot2026-01-175_06_17PM.thumb.png.cea9760c75b2254792a13954535b59d1.pngScreenshot2026-01-175_06_41PM.thumb.png.27367aaafe88cff6013b9673829b9031.png

Β 

TheGru
Posted (edited)

Got it... let me figure that one out.... but for the time being I am in mad scientist mode!!!

πŸ§ͺ Testing: Prevent Duplicate "Continue Watching" Entries

I've pushed a test build that addresses the duplicate "Continue Watching" problem. Looking for feedback before merging to main.

The Problem

When you partially watch a movie from your Aperture recommendations library, it can appear twice in your "Continue Watching" rowβ€”once for the original and once for the Aperture copy. This happens because both items share the same IMDB/TMDB IDs, and Emby/Jellyfin links them together.

The Solution

This build adds an optional toggle in Settings β†’ AI Recommendations β†’ Output called "Prevent Duplicate Continue Watching". When enabled:

  • Aperture prefixes provider IDs in NFO files (e.g., tt1234567 β†’ aperture-tt1234567)
  • This breaks the link between Aperture items and originalsβ€”no more duplicates
  • A background job runs every 30 minutes to sync watch history back to your original library items

Trade-offs

  • Up to 30-minute delay before the original is marked as watched
  • You must rebuild your AI recommendation libraries after enabling/disabling
  • This is a workaround, not a perfect solution

How to Test

image: ghcr.io/dgruhin-hrizn/aperture:continuewatching

After updating:

  • Go to Settings β†’ AI Recommendations β†’ Output
  • Enable "Prevent Duplicate Continue Watching"
  • Rebuild your movie/series recommendation libraries
  • Watch something partially and check your Continue Watching row

Feedback Wanted

  • Does it solve the duplicate issue for you?
  • Any unexpected behavior?
  • Is 30 minutes acceptable, or should it be configurable?

This will remain experimental until we get broader testing. Thanks! πŸ™

image.png.7d4275b6d96e47ec59803568c1ef3a4f.png

Β 


Edited by TheGru
  • Like 1
Jdiesel
Posted

I'm not seeing the option to rebuild the TV recommendations libraryΒ 

Screenshot2026-01-175_19_02PM.thumb.png.78717cdc4d1d1b525e6ac5120df5a673.png

Jdiesel
Posted
11 minutes ago, TheGru said:

Got it... let me figure that one out.... but for the time being I am in mad scientist mode!!!

πŸ§ͺ Testing: Prevent Duplicate "Continue Watching" Entries

I've pushed a test build that addresses the duplicate "Continue Watching" problem. Looking for feedback before merging to main.

The Problem

When you partially watch a movie from your Aperture recommendations library, it can appear twice in your "Continue Watching" rowβ€”once for the original and once for the Aperture copy. This happens because both items share the same IMDB/TMDB IDs, and Emby/Jellyfin links them together.

The Solution

This build adds an optional toggle in Settings β†’ AI Recommendations β†’ Output called "Prevent Duplicate Continue Watching". When enabled:

  • Aperture prefixes provider IDs in NFO files (e.g., tt1234567 β†’ aperture-tt1234567)
  • This breaks the link between Aperture items and originalsβ€”no more duplicates
  • A background job runs every 30 minutes to sync watch history back to your original library items

Trade-offs

  • Up to 30-minute delay before the original is marked as watched
  • You must rebuild your AI recommendation libraries after enabling/disabling
  • This is a workaround, not a perfect solution

How to Test

image: ghcr.io/dgruhin-hrizn/aperture:continuewatching

After updating:

  • Go to Settings β†’ AI Recommendations β†’ Output
  • Enable "Prevent Duplicate Continue Watching"
  • Rebuild your movie/series recommendation libraries
  • Watch something partially and check your Continue Watching row

Feedback Wanted

  • Does it solve the duplicate issue for you?
  • Any unexpected behavior?
  • Is 30 minutes acceptable, or should it be configurable?

This will remain experimental until we get broader testing. Thanks! πŸ™


I'm now seeing three entries after playing a movie from the recommendations list. I'll wait 30 minutes and see what happens

Β 

Screenshot2026-01-175_23_32PM.thumb.png.fc90217cbbd2fa735eae109ec9773747.png

GoldSpacer
Posted

I'll give this a try, configurable sync time would be cool, if it's not resource intensive I'd set mine to around 5 minutes.Β 

GoldSpacer
Posted

My experience so far with the continue watching is the AI movie picks don't have duplicates, but the AI show picks and top picks do have duplicates. This is after manually deleting all the movies and shows in the ApertureLibrary folder, regenerating the movie and show recommendations, and writing them back to the empty folders. Is the expected behavior for the Aperture library movie/show to be the only thing in continue watching until it is fully watched, then sync the fully watched status over to the emby library movie/show?

Β 

Also, custom models are sticking now but the custom embedding model isn't working still. The recommendation generation is working good though now with the custom model (qwen3:30b). This is the error I'm getting for the embedding generation:

6:42:27 PM❌ Job failed: No embedding model configured or dimensions unknown

I'm attempting to use qwen3-embedding:8b andΒ qwen3-embedding:4b for reference.

Β 

One other thing I noticed is the chapters and video preview thumbnails don't work on the aperture movies and shows. I have the video preview thumbnails set to not save in the media folders.

TheGru
Posted

What embedding size does it create? The issue I didn’t think of when I built that is to have you enter an embedding size to know which table to store the vectors in or it will fail.Β 

TheGru
Posted
2 hours ago, Jdiesel said:

I'm now seeing three entries after playing a movie from the recommendations list. I'll wait 30 minutes and see what happens

Β 

Screenshot2026-01-175_23_32PM.thumb.png.fc90217cbbd2fa735eae109ec9773747.png

I built it fast and had to leave for an event. I’ll actually test things when I get home and see what’s what. Like I said super workaround attempt to make this work.Β 
Β 

if no good switch batch to :latest and rerun the jobs to sync the ai libraries to Emby and the top picks

TeamB
Posted
2 hours ago, TheGru said:

The Problem

When you watch a movie or show from an Aperture recommendation library, you might see duplicate entries in "Continue Watching" - one for the original item in your library, and one for the Aperture copy.

This has always been a problem, if you add duplicate items in new "special" libraries (we have seen a few plugins that try to do this) then you will have duplicates.

The solution here is use playlists and have playlists better integrated into the dashboards of the clients so a playlist can be shown on home pages etc

TheGru
Posted
1 minute ago, TeamB said:

This has always been a problem, if you add duplicate items in new "special" libraries (we have seen a few plugins that try to do this) then you will have duplicates.

The solution here is use playlists and have playlists better integrated into the dashboards of the clients so a playlist can be shown on home pages etc

The answer is for the Emby devs to do the same thing they did to exclude libraries from global search, exclude from continue watching.Β 

  • Agree 1
GoldSpacer
Posted
9 minutes ago, TheGru said:

What embedding size does it create? The issue I didn’t think of when I built that is to have you enter an embedding size to know which table to store the vectors in or it will fail.Β 

Ollama library info says "Embedding Dimension: Up to 4096, supports user-defined output dimensions ranging from 32 to 4096". This is what I found on their blog here:Β https://qwenlm.github.io/blog/qwen3-embedding/

image.png.a170eaec10e63ccda7f81a1e2edb850a.png

TheGru
Posted
1 minute ago, GoldSpacer said:

Ollama library info says "Embedding Dimension: Up to 4096, supports user-defined output dimensions ranging from 32 to 4096". This is what I found on their blog here:Β https://qwenlm.github.io/blog/qwen3-embedding/

image.png.a170eaec10e63ccda7f81a1e2edb850a.png

I will add a dropdown selector to text embeddings custom model dialog with set sizes aperture supports. I will have to do a DB migration to support 4096 vectors.Β 

Jdiesel
Posted
20 minutes ago, TeamB said:

This has always been a problem, if you add duplicate items in new "special" libraries (we have seen a few plugins that try to do this) then you will have duplicates.

The solution here is use playlists and have playlists better integrated into the dashboards of the clients so a playlist can be shown on home pages etc

This is maybe coming with the Smart Playlist feature? We can only speculate because it hasn't been communicated.

TheGru
Posted
49 minutes ago, TheGru said:

I will add a dropdown selector to text embeddings custom model dialog with set sizes aperture supports. I will have to do a DB migration to support 4096 vectors.Β 

When I implement this users will have to match the exact model to its exact embedding size in the table you provided. If it doesn’t match it won’t work.Β 

TeamB
Posted (edited)
6 hours ago, TheGru said:

The answer is for the Emby devs to do the same thing they did to exclude libraries from global search, exclude from continue watching.Β 

I disagree, I don't think you should ever have to add a duplicate item to the system just so you can have it appear in a location or in a list you want.

the correct way would be to allow smart playlists, dynamic playlists or collections that can be added to home pages of client app to allow you to build a very dynamic customizable client platforms.

this has been talked about for literally years.

Edited by TeamB
  • Agree 1
TheGru
Posted (edited)
4 hours ago, TeamB said:

I disagree, I don't think you should ever have to add a duplicate item to the system just so you can have it appear in a location or in a list you want.

the correct way would be to allow smart playlists, dynamic playlists or collections that can be added to home pages of client app to allow you to build a very dynamic customizable client platforms.

this has been talked about for literally years.

Now I understand what you mean. Yes I agree. If this was something they would build out, I’d be more than happy to adapt Aperture to it!

Edited by TheGru
  • Like 2
Posted
15 hours ago, TheGru said:
  • Aperture prefixes provider IDs in NFO files (e.g., tt1234567 β†’ aperture-tt1234567)
  • This breaks the link between Aperture items and originalsβ€”no more duplicates
  • A background job runs every 30 minutes to sync watch history back to your original library items

IMO this is not really very useful unless it is in real time.Β  Also, this isn't just "watched".Β  The entire user-data object is involved (which includes resume points, watch count, favorite, etc.).Β  Have you covered that?

12 hours ago, TheGru said:

The answer is for the Emby devs to do the same thing they did to exclude libraries from global search, exclude from continue watching.Β 

We actually already have it but it is combined with "Latest" which is how you are getting your main lists onto the home page.

TheGru
Posted (edited)
22 minutes ago, ebr said:

IMO this is not really very useful unless it is in real time.Β  Also, this isn't just "watched".Β  The entire user-data object is involved (which includes resume points, watch count, favorite, etc.).Β  Have you covered that?

We actually already have it but it is combined with "Latest" which is how you are getting your main lists onto the home page.

I haven’t yet but I could, like I said I’m just trying to work around the current limitation of continue watching being tied to latest currentlyΒ 

Edited by TheGru
TheGru
Posted
1 hour ago, ebr said:

IMO this is not really very useful unless it is in real time.

I could make it realtime using webhooks, but the question I have about the Webhooks plugin is it seems to add a notifications section but it is tied to a user, it does not seem to be a server wide configuration. I am just not understanding that correctly?

Screenshot2026-01-18at11_07_04AM.png.89db3f21bbd8c8a294b93901619fccd9.png

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