mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-10-31 02:27:18 -04:00 
			
		
		
		
	Only reselect audio streams when user preference is respected (#13832)
This commit is contained in:
		
							parent
							
								
									c152f610ce
								
							
						
					
					
						commit
						32fe92d8f5
					
				| @ -427,6 +427,7 @@ namespace Emby.Server.Implementations.Library | |||||||
|                 if (source.MediaStreams.Any(i => i.Type == MediaStreamType.Audio && i.Index == index)) |                 if (source.MediaStreams.Any(i => i.Type == MediaStreamType.Audio && i.Index == index)) | ||||||
|                 { |                 { | ||||||
|                     source.DefaultAudioStreamIndex = index; |                     source.DefaultAudioStreamIndex = index; | ||||||
|  |                     source.DefaultAudioIndexSource = AudioIndexSource.User; | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @ -434,6 +435,15 @@ namespace Emby.Server.Implementations.Library | |||||||
|             var preferredAudio = NormalizeLanguage(user.AudioLanguagePreference); |             var preferredAudio = NormalizeLanguage(user.AudioLanguagePreference); | ||||||
| 
 | 
 | ||||||
|             source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.PlayDefaultAudioTrack); |             source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.PlayDefaultAudioTrack); | ||||||
|  |             if (user.PlayDefaultAudioTrack) | ||||||
|  |             { | ||||||
|  |                 source.DefaultAudioIndexSource |= AudioIndexSource.Default; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (preferredAudio.Count > 0) | ||||||
|  |             { | ||||||
|  |                 source.DefaultAudioIndexSource |= AudioIndexSource.Language; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void SetDefaultAudioAndSubtitleStreamIndices(BaseItem item, MediaSourceInfo source, User user) |         public void SetDefaultAudioAndSubtitleStreamIndices(BaseItem item, MediaSourceInfo source, User user) | ||||||
|  | |||||||
| @ -129,6 +129,13 @@ public class MediaInfoHelper | |||||||
|             var mediaSourcesClone = JsonSerializer.Deserialize<MediaSourceInfo[]>(JsonSerializer.SerializeToUtf8Bytes(mediaSources)); |             var mediaSourcesClone = JsonSerializer.Deserialize<MediaSourceInfo[]>(JsonSerializer.SerializeToUtf8Bytes(mediaSources)); | ||||||
|             if (mediaSourcesClone is not null) |             if (mediaSourcesClone is not null) | ||||||
|             { |             { | ||||||
|  |                 // Carry over the default audio index source. | ||||||
|  |                 // This field is not intended to be exposed to API clients, but it is used internally by the server | ||||||
|  |                 for (int i = 0; i < mediaSourcesClone.Length && i < mediaSources.Length; i++) | ||||||
|  |                 { | ||||||
|  |                     mediaSourcesClone[i].DefaultAudioIndexSource = mediaSources[i].DefaultAudioIndexSource; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|                 result.MediaSources = mediaSourcesClone; |                 result.MediaSources = mediaSourcesClone; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -665,15 +665,39 @@ namespace MediaBrowser.Model.Dlna | |||||||
| 
 | 
 | ||||||
|             // Collect candidate audio streams |             // Collect candidate audio streams | ||||||
|             ICollection<MediaStream> candidateAudioStreams = audioStream is null ? [] : [audioStream]; |             ICollection<MediaStream> candidateAudioStreams = audioStream is null ? [] : [audioStream]; | ||||||
|             if (!options.AudioStreamIndex.HasValue || options.AudioStreamIndex < 0) |             // When the index is explicitly required by client or the default is specified by user, don't do any stream reselection. | ||||||
|  |             if (!item.DefaultAudioIndexSource.HasFlag(AudioIndexSource.User) && (options.AudioStreamIndex is null or < 0)) | ||||||
|             { |             { | ||||||
|                 if (audioStream?.IsDefault == true) |                 // When user has no preferences allow stream selection on all streams. | ||||||
|  |                 if (item.DefaultAudioIndexSource == AudioIndexSource.None && audioStream is not null) | ||||||
|                 { |                 { | ||||||
|                     candidateAudioStreams = item.MediaStreams.Where(stream => stream.Type == MediaStreamType.Audio && stream.IsDefault).ToArray(); |                     candidateAudioStreams = item.MediaStreams.Where(stream => stream.Type == MediaStreamType.Audio).ToArray(); | ||||||
|  |                     if (audioStream.IsDefault) | ||||||
|  |                     { | ||||||
|  |                         // If default is picked, only allow selection within default streams. | ||||||
|  |                         candidateAudioStreams = candidateAudioStreams.Where(stream => stream.IsDefault).ToArray(); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|                 else | 
 | ||||||
|  |                 if (item.DefaultAudioIndexSource.HasFlag(AudioIndexSource.Language)) | ||||||
|                 { |                 { | ||||||
|  |                     // If user has language preference, only allow stream selection within the same language. | ||||||
|                     candidateAudioStreams = item.MediaStreams.Where(stream => stream.Type == MediaStreamType.Audio && stream.Language == audioStream?.Language).ToArray(); |                     candidateAudioStreams = item.MediaStreams.Where(stream => stream.Type == MediaStreamType.Audio && stream.Language == audioStream?.Language).ToArray(); | ||||||
|  |                     if (item.DefaultAudioIndexSource.HasFlag(AudioIndexSource.Default)) | ||||||
|  |                     { | ||||||
|  |                         var defaultStreamsInPreferredLanguage = candidateAudioStreams.Where(stream => stream.IsDefault).ToArray(); | ||||||
|  | 
 | ||||||
|  |                         // If the user also prefers default streams, try limit selection within default tracks in the same language. | ||||||
|  |                         // If there is no default stream in the preferred language, allow selection on all default streams to match the "Play default audio track regardless of language" setting. | ||||||
|  |                         candidateAudioStreams = defaultStreamsInPreferredLanguage.Length > 0 | ||||||
|  |                             ? defaultStreamsInPreferredLanguage | ||||||
|  |                             : item.MediaStreams.Where(stream => stream.Type == MediaStreamType.Audio && stream.IsDefault).ToArray(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 else if (item.DefaultAudioIndexSource.HasFlag(AudioIndexSource.Default)) | ||||||
|  |                 { | ||||||
|  |                     // If user prefers default streams, only allow stream selection on default streams. | ||||||
|  |                     candidateAudioStreams = item.MediaStreams.Where(stream => stream.Type == MediaStreamType.Audio && stream.IsDefault).ToArray(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ namespace MediaBrowser.Model.Dto | |||||||
|             SupportsDirectPlay = true; |             SupportsDirectPlay = true; | ||||||
|             SupportsProbing = true; |             SupportsProbing = true; | ||||||
|             UseMostCompatibleTranscodingProfile = false; |             UseMostCompatibleTranscodingProfile = false; | ||||||
|  |             DefaultAudioIndexSource = AudioIndexSource.None; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public MediaProtocol Protocol { get; set; } |         public MediaProtocol Protocol { get; set; } | ||||||
| @ -118,6 +119,9 @@ namespace MediaBrowser.Model.Dto | |||||||
|         [JsonIgnore] |         [JsonIgnore] | ||||||
|         public TranscodeReason TranscodeReasons { get; set; } |         public TranscodeReason TranscodeReasons { get; set; } | ||||||
| 
 | 
 | ||||||
|  |         [JsonIgnore] | ||||||
|  |         public AudioIndexSource DefaultAudioIndexSource { get; set; } | ||||||
|  | 
 | ||||||
|         public int? DefaultAudioStreamIndex { get; set; } |         public int? DefaultAudioStreamIndex { get; set; } | ||||||
| 
 | 
 | ||||||
|         public int? DefaultSubtitleStreamIndex { get; set; } |         public int? DefaultSubtitleStreamIndex { get; set; } | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								MediaBrowser.Model/MediaInfo/AudioIndexSource.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								MediaBrowser.Model/MediaInfo/AudioIndexSource.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | using System; | ||||||
|  | 
 | ||||||
|  | namespace MediaBrowser.Model.MediaInfo; | ||||||
|  | 
 | ||||||
|  | /// <summary> | ||||||
|  | /// How is the audio index determined. | ||||||
|  | /// </summary> | ||||||
|  | [Flags] | ||||||
|  | public enum AudioIndexSource | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// The default index when no preference is specified. | ||||||
|  |     /// </summary> | ||||||
|  |     None = 0, | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// The index is calculated whether the track is marked as default or not. | ||||||
|  |     /// </summary> | ||||||
|  |     Default = 1 << 0, | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// The index is calculated whether the track is in preferred language or not. | ||||||
|  |     /// </summary> | ||||||
|  |     Language = 1 << 1, | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// The index is specified by the user. | ||||||
|  |     /// </summary> | ||||||
|  |     User = 1 << 2 | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user