feat: add optional Laya engine mode for grouping and language detection (#12)

Add a languageDetectionMode setting (algo | laya | laya+algo) exposed
in Settings with three engine choices. When Laya is enabled, a laya
service (Dockerfile.laya, optional compose profile, models stored
outside the repo under ./data/models/laya) can be started, with model
download and deletion from the UI via /laya routes to manage disk
space. Add a channelLanguageFusion service combining Laya results
with the existing algorithm, and wire detection mode through
grouping, channel list and player. Cover engine selection, fusion
and laya service behavior with tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
blomios
2026-10-02 11:13:34 +02:00
parent 9e80655fd9
commit ce11ecc757
19 changed files with 780 additions and 13 deletions

View File

@ -59,3 +59,19 @@ test('favorites group updates are disabled for flat lists', () => {
assert.equal(grouping.shouldUseFavoritesGroup('flat'), false);
assert.equal(grouping.shouldUseFavoritesGroup('grouped'), true);
});
test('Laya language results participate in variant selection', () => {
const lowQualityFrench = channel('1', 'Sports One SD');
const highQualityEnglish = channel('2', 'Sports One 4K');
const languageResults = new Map([
[grouping.getVariantKey(lowQualityFrench), { language: 'fr', confidence: 0.92 }],
[grouping.getVariantKey(highQualityEnglish), { language: 'en', confidence: 0.94 }]
]);
const logical = grouping.groupChannels([lowQualityFrench, highQualityEnglish], {
languageMode: 'laya',
languageResults,
preferredLanguage: 'fr'
})[0];
assert.equal(logical.preferredVariant.id, '1');
assert.deepEqual(logical.availableLanguages.map(item => item.code), ['fr', 'en']);
});