Backport pull request #18037 from jellyfin/release-12.z

Enforce channel mediasource id

Original-merge: 941e419a2c

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Cody Robibero <cody@robibe.ro>
This commit is contained in:
Shadowghost authored and Cody Robibero committed 2026-09-15 11:17:08 -04:00
1 parent cdd2b3e047
commit 8cd2293ff9
1 file changed
+30 -9
+30 -9
View File
@@ -372,9 +372,7 @@ namespace Jellyfin.LiveTv.Channels
{
IEnumerable<MediaSourceInfo> results = GetSavedMediaSources(item);
return results
.Select(i => NormalizeMediaSource(item, i))
.ToList();
return NormalizeMediaSources(item, results);
}
/// <summary>
@@ -400,9 +398,7 @@ namespace Jellyfin.LiveTv.Channels
results = Enumerable.Empty<MediaSourceInfo>();
}
return results
.Select(i => NormalizeMediaSource(item, i))
.ToList();
return NormalizeMediaSources(item, results);
}
private async Task<IEnumerable<MediaSourceInfo>> GetChannelItemMediaSourcesInternal(IRequiresMediaInfoCallback channel, string id, CancellationToken cancellationToken)
@@ -420,11 +416,36 @@ namespace Jellyfin.LiveTv.Channels
return list;
}
private static MediaSourceInfo NormalizeMediaSource(BaseItem item, MediaSourceInfo info)
private static IReadOnlyList<MediaSourceInfo> NormalizeMediaSources(BaseItem item, IEnumerable<MediaSourceInfo> infos)
{
info.RunTimeTicks ??= item.RunTimeTicks;
var list = infos.ToList();
var itemId = item.Id.ToString("N", CultureInfo.InvariantCulture);
var hasDefaultSource = list.Any(i => string.Equals(i.Id, itemId, StringComparison.OrdinalIgnoreCase));
return info;
for (var index = 0; index < list.Count; index++)
{
var info = list[index];
info.RunTimeTicks ??= item.RunTimeTicks;
if (!string.IsNullOrEmpty(info.Id))
{
continue;
}
if (!hasDefaultSource)
{
// The source carrying the item id sorts first and becomes the client's default.
info.Id = itemId;
hasDefaultSource = true;
continue;
}
// Remaining sources need ids that are distinct but stable, as clients send them back to request playback.
var key = string.IsNullOrEmpty(info.Path) ? index.ToString(CultureInfo.InvariantCulture) : info.Path;
info.Id = (itemId + key).GetMD5().ToString("N", CultureInfo.InvariantCulture);
}
return list;
}
private async Task<Channel> GetChannel(IChannel channelInfo, CancellationToken cancellationToken)