mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-07-04 13:22:52 +01:00
Enable nullable for more files
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -37,29 +35,20 @@ namespace MediaBrowser.Model.Dlna
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StreamBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">The <see cref="ILogger"/> object.</param>
|
||||
public StreamBuilder(ILogger<StreamBuilder> logger)
|
||||
: this(new FullTranscoderSupport(), logger)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the optimal audio stream.
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="MediaOptions"/> object to get the audio stream from.</param>
|
||||
/// <returns>The <see cref="StreamInfo"/> of the optimal audio stream.</returns>
|
||||
public StreamInfo GetOptimalAudioStream(MediaOptions options)
|
||||
public StreamInfo? GetOptimalAudioStream(MediaOptions options)
|
||||
{
|
||||
ValidateMediaOptions(options, false);
|
||||
|
||||
var mediaSources = new List<MediaSourceInfo>();
|
||||
foreach (var mediaSource in options.MediaSources)
|
||||
{
|
||||
if (string.IsNullOrEmpty(options.MediaSourceId) ||
|
||||
string.Equals(mediaSource.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
|
||||
if (string.IsNullOrEmpty(options.MediaSourceId)
|
||||
|| string.Equals(mediaSource.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mediaSources.Add(mediaSource);
|
||||
}
|
||||
@@ -68,7 +57,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
var streams = new List<StreamInfo>();
|
||||
foreach (var mediaSourceInfo in mediaSources)
|
||||
{
|
||||
StreamInfo streamInfo = GetOptimalAudioStream(mediaSourceInfo, options);
|
||||
StreamInfo? streamInfo = GetOptimalAudioStream(mediaSourceInfo, options);
|
||||
if (streamInfo is not null)
|
||||
{
|
||||
streams.Add(streamInfo);
|
||||
@@ -84,7 +73,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
return GetOptimalStream(streams, options.GetMaxBitrate(true) ?? 0);
|
||||
}
|
||||
|
||||
private StreamInfo GetOptimalAudioStream(MediaSourceInfo item, MediaOptions options)
|
||||
private StreamInfo? GetOptimalAudioStream(MediaSourceInfo item, MediaOptions options)
|
||||
{
|
||||
var playlistItem = new StreamInfo
|
||||
{
|
||||
@@ -138,7 +127,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
}
|
||||
}
|
||||
|
||||
TranscodingProfile transcodingProfile = null;
|
||||
TranscodingProfile? transcodingProfile = null;
|
||||
foreach (var tcProfile in options.Profile.TranscodingProfiles)
|
||||
{
|
||||
if (tcProfile.Type == playlistItem.MediaType
|
||||
@@ -190,15 +179,15 @@ namespace MediaBrowser.Model.Dlna
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="MediaOptions"/> object to get the video stream from.</param>
|
||||
/// <returns>The <see cref="StreamInfo"/> of the optimal video stream.</returns>
|
||||
public StreamInfo GetOptimalVideoStream(MediaOptions options)
|
||||
public StreamInfo? GetOptimalVideoStream(MediaOptions options)
|
||||
{
|
||||
ValidateMediaOptions(options, true);
|
||||
|
||||
var mediaSources = new List<MediaSourceInfo>();
|
||||
foreach (var mediaSourceInfo in options.MediaSources)
|
||||
{
|
||||
if (string.IsNullOrEmpty(options.MediaSourceId) ||
|
||||
string.Equals(mediaSourceInfo.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
|
||||
if (string.IsNullOrEmpty(options.MediaSourceId)
|
||||
|| string.Equals(mediaSourceInfo.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mediaSources.Add(mediaSourceInfo);
|
||||
}
|
||||
@@ -223,7 +212,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
return GetOptimalStream(streams, options.GetMaxBitrate(false) ?? 0);
|
||||
}
|
||||
|
||||
private static StreamInfo GetOptimalStream(List<StreamInfo> streams, long maxBitrate)
|
||||
private static StreamInfo? GetOptimalStream(List<StreamInfo> streams, long maxBitrate)
|
||||
=> SortMediaSources(streams, maxBitrate).FirstOrDefault();
|
||||
|
||||
private static IOrderedEnumerable<StreamInfo> SortMediaSources(List<StreamInfo> streams, long maxBitrate)
|
||||
@@ -366,7 +355,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
/// <param name="type">The <see cref="DlnaProfileType"/>.</param>
|
||||
/// <param name="playProfile">The <see cref="DirectPlayProfile"/> object to get the video stream from.</param>
|
||||
/// <returns>The the normalized input container.</returns>
|
||||
public static string NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, DeviceProfile profile, DlnaProfileType type, DirectPlayProfile playProfile = null)
|
||||
public static string? NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, DeviceProfile? profile, DlnaProfileType type, DirectPlayProfile? playProfile = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(inputContainer))
|
||||
{
|
||||
@@ -394,7 +383,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
return formats[0];
|
||||
}
|
||||
|
||||
private (DirectPlayProfile Profile, PlayMethod? PlayMethod, TranscodeReason TranscodeReasons) GetAudioDirectPlayProfile(MediaSourceInfo item, MediaStream audioStream, MediaOptions options)
|
||||
private (DirectPlayProfile? Profile, PlayMethod? PlayMethod, TranscodeReason TranscodeReasons) GetAudioDirectPlayProfile(MediaSourceInfo item, MediaStream audioStream, MediaOptions options)
|
||||
{
|
||||
var directPlayProfile = options.Profile.DirectPlayProfiles
|
||||
.FirstOrDefault(x => x.Type == DlnaProfileType.Audio && IsAudioDirectPlaySupported(x, item, audioStream));
|
||||
@@ -449,7 +438,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
return (directPlayProfile, null, transcodeReasons);
|
||||
}
|
||||
|
||||
private static TranscodeReason GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable<DirectPlayProfile> directPlayProfiles)
|
||||
private static TranscodeReason GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream? videoStream, MediaStream audioStream, IEnumerable<DirectPlayProfile> directPlayProfiles)
|
||||
{
|
||||
var mediaType = videoStream is null ? DlnaProfileType.Audio : DlnaProfileType.Video;
|
||||
|
||||
@@ -575,7 +564,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetStreamInfoOptionsFromDirectPlayProfile(MediaOptions options, MediaSourceInfo item, StreamInfo playlistItem, DirectPlayProfile directPlayProfile)
|
||||
private static void SetStreamInfoOptionsFromDirectPlayProfile(MediaOptions options, MediaSourceInfo item, StreamInfo playlistItem, DirectPlayProfile? directPlayProfile)
|
||||
{
|
||||
var container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Video, directPlayProfile);
|
||||
var protocol = "http";
|
||||
@@ -587,7 +576,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
playlistItem.SubProtocol = protocol;
|
||||
|
||||
playlistItem.VideoCodecs = new[] { item.VideoStream.Codec };
|
||||
playlistItem.AudioCodecs = ContainerProfile.SplitValue(directPlayProfile.AudioCodec);
|
||||
playlistItem.AudioCodecs = ContainerProfile.SplitValue(directPlayProfile?.AudioCodec);
|
||||
}
|
||||
|
||||
private StreamInfo BuildVideoItem(MediaSourceInfo item, MediaOptions options)
|
||||
@@ -646,7 +635,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
isEligibleForDirectPlay,
|
||||
isEligibleForDirectStream);
|
||||
|
||||
DirectPlayProfile directPlayProfile = null;
|
||||
DirectPlayProfile? directPlayProfile = null;
|
||||
if (isEligibleForDirectPlay || isEligibleForDirectStream)
|
||||
{
|
||||
// See if it can be direct played
|
||||
@@ -677,16 +666,16 @@ namespace MediaBrowser.Model.Dlna
|
||||
playlistItem.AudioStreamIndex = audioStream?.Index;
|
||||
if (audioStream is not null)
|
||||
{
|
||||
playlistItem.AudioCodecs = ContainerProfile.SplitValue(directPlayProfile.AudioCodec);
|
||||
playlistItem.AudioCodecs = ContainerProfile.SplitValue(directPlayProfile?.AudioCodec);
|
||||
}
|
||||
|
||||
SetStreamInfoOptionsFromDirectPlayProfile(options, item, playlistItem, directPlayProfile);
|
||||
BuildStreamVideoItem(playlistItem, options, item, videoStream, audioStream, candidateAudioStreams, directPlayProfile.Container, directPlayProfile.VideoCodec, directPlayProfile.AudioCodec);
|
||||
BuildStreamVideoItem(playlistItem, options, item, videoStream, audioStream, candidateAudioStreams, directPlayProfile?.Container, directPlayProfile?.VideoCodec, directPlayProfile?.AudioCodec);
|
||||
}
|
||||
|
||||
if (subtitleStream is not null)
|
||||
{
|
||||
var subtitleProfile = GetSubtitleProfile(item, subtitleStream, options.Profile.SubtitleProfiles, directPlay.Value, _transcoderSupport, directPlayProfile.Container, null);
|
||||
var subtitleProfile = GetSubtitleProfile(item, subtitleStream, options.Profile.SubtitleProfiles, directPlay.Value, _transcoderSupport, directPlayProfile?.Container, null);
|
||||
|
||||
playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method;
|
||||
playlistItem.SubtitleFormat = subtitleProfile.Format;
|
||||
@@ -748,7 +737,14 @@ namespace MediaBrowser.Model.Dlna
|
||||
return playlistItem;
|
||||
}
|
||||
|
||||
private TranscodingProfile GetVideoTranscodeProfile(MediaSourceInfo item, MediaOptions options, MediaStream videoStream, MediaStream audioStream, IEnumerable<MediaStream> candidateAudioStreams, MediaStream subtitleStream, StreamInfo playlistItem)
|
||||
private TranscodingProfile? GetVideoTranscodeProfile(
|
||||
MediaSourceInfo item,
|
||||
MediaOptions options,
|
||||
MediaStream? videoStream,
|
||||
MediaStream? audioStream,
|
||||
IEnumerable<MediaStream> candidateAudioStreams,
|
||||
MediaStream? subtitleStream,
|
||||
StreamInfo playlistItem)
|
||||
{
|
||||
if (!(item.SupportsTranscoding || item.SupportsDirectStream))
|
||||
{
|
||||
@@ -795,7 +791,16 @@ namespace MediaBrowser.Model.Dlna
|
||||
return transcodingProfiles.FirstOrDefault();
|
||||
}
|
||||
|
||||
private void BuildStreamVideoItem(StreamInfo playlistItem, MediaOptions options, MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable<MediaStream> candidateAudioStreams, string container, string videoCodec, string audioCodec)
|
||||
private void BuildStreamVideoItem(
|
||||
StreamInfo playlistItem,
|
||||
MediaOptions options,
|
||||
MediaSourceInfo item,
|
||||
MediaStream? videoStream,
|
||||
MediaStream? audioStream,
|
||||
IEnumerable<MediaStream> candidateAudioStreams,
|
||||
string? container,
|
||||
string? videoCodec,
|
||||
string? audioCodec)
|
||||
{
|
||||
// Prefer matching video codecs
|
||||
var videoCodecs = ContainerProfile.SplitValue(videoCodec);
|
||||
@@ -862,12 +867,12 @@ namespace MediaBrowser.Model.Dlna
|
||||
int? bitDepth = videoStream?.BitDepth;
|
||||
int? videoBitrate = videoStream?.BitRate;
|
||||
double? videoLevel = videoStream?.Level;
|
||||
string videoProfile = videoStream?.Profile;
|
||||
string videoRangeType = videoStream?.VideoRangeType;
|
||||
string? videoProfile = videoStream?.Profile;
|
||||
string? videoRangeType = videoStream?.VideoRangeType;
|
||||
float videoFramerate = videoStream is null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
|
||||
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
||||
bool? isInterlaced = videoStream?.IsInterlaced;
|
||||
string videoCodecTag = videoStream?.CodecTag;
|
||||
string? videoCodecTag = videoStream?.CodecTag;
|
||||
bool? isAvc = videoStream?.IsAVC;
|
||||
|
||||
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : item.Timestamp;
|
||||
@@ -903,11 +908,11 @@ namespace MediaBrowser.Model.Dlna
|
||||
playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate);
|
||||
|
||||
bool? isSecondaryAudio = audioStream is null ? null : item.IsSecondaryAudio(audioStream);
|
||||
int? inputAudioBitrate = audioStream is null ? null : audioStream.BitRate;
|
||||
int? audioChannels = audioStream is null ? null : audioStream.Channels;
|
||||
string audioProfile = audioStream is null ? null : audioStream.Profile;
|
||||
int? inputAudioSampleRate = audioStream is null ? null : audioStream.SampleRate;
|
||||
int? inputAudioBitDepth = audioStream is null ? null : audioStream.BitDepth;
|
||||
int? inputAudioBitrate = audioStream?.BitRate;
|
||||
int? audioChannels = audioStream?.Channels;
|
||||
string? audioProfile = audioStream?.Profile;
|
||||
int? inputAudioSampleRate = audioStream?.SampleRate;
|
||||
int? inputAudioBitDepth = audioStream?.BitDepth;
|
||||
|
||||
var appliedAudioConditions = options.Profile.CodecProfiles
|
||||
.Where(i => i.Type == CodecType.VideoAudio &&
|
||||
@@ -955,7 +960,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
playlistItem?.TranscodeReasons);
|
||||
}
|
||||
|
||||
private static int GetDefaultAudioBitrate(string audioCodec, int? audioChannels)
|
||||
private static int GetDefaultAudioBitrate(string? audioCodec, int? audioChannels)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(audioCodec))
|
||||
{
|
||||
@@ -988,9 +993,9 @@ namespace MediaBrowser.Model.Dlna
|
||||
return 192000;
|
||||
}
|
||||
|
||||
private static int GetAudioBitrate(long maxTotalBitrate, string[] targetAudioCodecs, MediaStream audioStream, StreamInfo item)
|
||||
private static int GetAudioBitrate(long maxTotalBitrate, string[] targetAudioCodecs, MediaStream? audioStream, StreamInfo item)
|
||||
{
|
||||
string targetAudioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0];
|
||||
string? targetAudioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0];
|
||||
|
||||
int? targetAudioChannels = item.GetTargetAudioChannels(targetAudioCodec);
|
||||
|
||||
@@ -1081,13 +1086,13 @@ namespace MediaBrowser.Model.Dlna
|
||||
return 7168000;
|
||||
}
|
||||
|
||||
private (DirectPlayProfile Profile, PlayMethod? PlayMethod, int? AudioStreamIndex, TranscodeReason TranscodeReasons) GetVideoDirectPlayProfile(
|
||||
private (DirectPlayProfile? Profile, PlayMethod? PlayMethod, int? AudioStreamIndex, TranscodeReason TranscodeReasons) GetVideoDirectPlayProfile(
|
||||
MediaOptions options,
|
||||
MediaSourceInfo mediaSource,
|
||||
MediaStream videoStream,
|
||||
MediaStream audioStream,
|
||||
MediaStream? videoStream,
|
||||
MediaStream? audioStream,
|
||||
ICollection<MediaStream> candidateAudioStreams,
|
||||
MediaStream subtitleStream,
|
||||
MediaStream? subtitleStream,
|
||||
bool isEligibleForDirectPlay,
|
||||
bool isEligibleForDirectStream)
|
||||
{
|
||||
@@ -1110,12 +1115,12 @@ namespace MediaBrowser.Model.Dlna
|
||||
int? bitDepth = videoStream?.BitDepth;
|
||||
int? videoBitrate = videoStream?.BitRate;
|
||||
double? videoLevel = videoStream?.Level;
|
||||
string videoProfile = videoStream?.Profile;
|
||||
string videoRangeType = videoStream?.VideoRangeType;
|
||||
string? videoProfile = videoStream?.Profile;
|
||||
string? videoRangeType = videoStream?.VideoRangeType;
|
||||
float videoFramerate = videoStream is null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
|
||||
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
||||
bool? isInterlaced = videoStream?.IsInterlaced;
|
||||
string videoCodecTag = videoStream?.CodecTag;
|
||||
string? videoCodecTag = videoStream?.CodecTag;
|
||||
bool? isAvc = videoStream?.IsAVC;
|
||||
|
||||
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : mediaSource.Timestamp;
|
||||
@@ -1203,14 +1208,14 @@ namespace MediaBrowser.Model.Dlna
|
||||
}
|
||||
|
||||
// Check video codec
|
||||
string videoCodec = videoStream?.Codec;
|
||||
string? videoCodec = videoStream?.Codec;
|
||||
if (!directPlayProfile.SupportsVideoCodec(videoCodec))
|
||||
{
|
||||
directPlayProfileReasons |= TranscodeReason.VideoCodecNotSupported;
|
||||
}
|
||||
|
||||
// Check audio codec
|
||||
MediaStream selectedAudioStream = null;
|
||||
MediaStream? selectedAudioStream = null;
|
||||
if (candidateAudioStreams.Any())
|
||||
{
|
||||
selectedAudioStream = candidateAudioStreams.FirstOrDefault(audioStream => directPlayProfile.SupportsAudioCodec(audioStream.Codec));
|
||||
@@ -1331,8 +1336,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
SubtitleProfile[] subtitleProfiles,
|
||||
PlayMethod playMethod,
|
||||
ITranscoderSupport transcoderSupport,
|
||||
string outputContainer,
|
||||
string transcodingSubProtocol)
|
||||
string? outputContainer,
|
||||
string? transcodingSubProtocol)
|
||||
{
|
||||
if (!subtitleStream.IsExternal && (playMethod != PlayMethod.Transcode || !string.Equals(transcodingSubProtocol, "hls", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
@@ -1405,7 +1410,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
};
|
||||
}
|
||||
|
||||
private static bool IsSubtitleEmbedSupported(string transcodingContainer)
|
||||
private static bool IsSubtitleEmbedSupported(string? transcodingContainer)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(transcodingContainer))
|
||||
{
|
||||
@@ -1427,7 +1432,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
return false;
|
||||
}
|
||||
|
||||
private static SubtitleProfile GetExternalSubtitleProfile(MediaSourceInfo mediaSource, MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, ITranscoderSupport transcoderSupport, bool allowConversion)
|
||||
private static SubtitleProfile? GetExternalSubtitleProfile(MediaSourceInfo mediaSource, MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, ITranscoderSupport transcoderSupport, bool allowConversion)
|
||||
{
|
||||
foreach (var profile in subtitleProfiles)
|
||||
{
|
||||
@@ -1560,7 +1565,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
private static IEnumerable<ProfileCondition> GetProfileConditionsForAudio(
|
||||
IEnumerable<CodecProfile> codecProfiles,
|
||||
string container,
|
||||
string codec,
|
||||
string? codec,
|
||||
int? audioChannels,
|
||||
int? audioBitrate,
|
||||
int? audioSampleRate,
|
||||
@@ -1580,7 +1585,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
return conditions.Where(condition => !ConditionProcessor.IsAudioConditionSatisfied(condition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth));
|
||||
}
|
||||
|
||||
private void ApplyTranscodingConditions(StreamInfo item, IEnumerable<ProfileCondition> conditions, string qualifier, bool enableQualifiedConditions, bool enableNonQualifiedConditions)
|
||||
private void ApplyTranscodingConditions(StreamInfo item, IEnumerable<ProfileCondition> conditions, string? qualifier, bool enableQualifiedConditions, bool enableNonQualifiedConditions)
|
||||
{
|
||||
foreach (ProfileCondition condition in conditions)
|
||||
{
|
||||
@@ -2056,7 +2061,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
}
|
||||
|
||||
// Check audio codec
|
||||
string audioCodec = audioStream?.Codec;
|
||||
string? audioCodec = audioStream?.Codec;
|
||||
if (!profile.SupportsAudioCodec(audioCodec))
|
||||
{
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user