mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-10-31 10:37:22 -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)) | ||||
|                 { | ||||
|                     source.DefaultAudioStreamIndex = index; | ||||
|                     source.DefaultAudioIndexSource = AudioIndexSource.User; | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
| @ -434,6 +435,15 @@ namespace Emby.Server.Implementations.Library | ||||
|             var preferredAudio = NormalizeLanguage(user.AudioLanguagePreference); | ||||
| 
 | ||||
|             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) | ||||
|  | ||||
| @ -129,6 +129,13 @@ public class MediaInfoHelper | ||||
|             var mediaSourcesClone = JsonSerializer.Deserialize<MediaSourceInfo[]>(JsonSerializer.SerializeToUtf8Bytes(mediaSources)); | ||||
|             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; | ||||
|             } | ||||
| 
 | ||||
|  | ||||
| @ -665,15 +665,39 @@ namespace MediaBrowser.Model.Dlna | ||||
| 
 | ||||
|             // Collect candidate audio streams | ||||
|             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(); | ||||
|                     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; | ||||
|             SupportsProbing = true; | ||||
|             UseMostCompatibleTranscodingProfile = false; | ||||
|             DefaultAudioIndexSource = AudioIndexSource.None; | ||||
|         } | ||||
| 
 | ||||
|         public MediaProtocol Protocol { get; set; } | ||||
| @ -118,6 +119,9 @@ namespace MediaBrowser.Model.Dto | ||||
|         [JsonIgnore] | ||||
|         public TranscodeReason TranscodeReasons { get; set; } | ||||
| 
 | ||||
|         [JsonIgnore] | ||||
|         public AudioIndexSource DefaultAudioIndexSource { get; set; } | ||||
| 
 | ||||
|         public int? DefaultAudioStreamIndex { 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