mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-06-29 10:23:36 +02:00
Enable nullable for more files
This commit is contained in:
parent
1244502fa8
commit
dab75d35d2
|
@ -1,5 +1,3 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -66,7 +64,8 @@ namespace Emby.Dlna.PlayTo
|
||||||
IUserDataManager userDataManager,
|
IUserDataManager userDataManager,
|
||||||
ILocalizationManager localization,
|
ILocalizationManager localization,
|
||||||
IMediaSourceManager mediaSourceManager,
|
IMediaSourceManager mediaSourceManager,
|
||||||
IMediaEncoder mediaEncoder)
|
IMediaEncoder mediaEncoder,
|
||||||
|
Device device)
|
||||||
{
|
{
|
||||||
_session = session;
|
_session = session;
|
||||||
_sessionManager = sessionManager;
|
_sessionManager = sessionManager;
|
||||||
|
@ -82,14 +81,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
_localization = localization;
|
_localization = localization;
|
||||||
_mediaSourceManager = mediaSourceManager;
|
_mediaSourceManager = mediaSourceManager;
|
||||||
_mediaEncoder = mediaEncoder;
|
_mediaEncoder = mediaEncoder;
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsSessionActive => !_disposed && _device is not null;
|
|
||||||
|
|
||||||
public bool SupportsMediaControl => IsSessionActive;
|
|
||||||
|
|
||||||
public void Init(Device device)
|
|
||||||
{
|
|
||||||
_device = device;
|
_device = device;
|
||||||
_device.OnDeviceUnavailable = OnDeviceUnavailable;
|
_device.OnDeviceUnavailable = OnDeviceUnavailable;
|
||||||
_device.PlaybackStart += OnDevicePlaybackStart;
|
_device.PlaybackStart += OnDevicePlaybackStart;
|
||||||
|
@ -102,6 +94,10 @@ namespace Emby.Dlna.PlayTo
|
||||||
_deviceDiscovery.DeviceLeft += OnDeviceDiscoveryDeviceLeft;
|
_deviceDiscovery.DeviceLeft += OnDeviceDiscoveryDeviceLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsSessionActive => !_disposed;
|
||||||
|
|
||||||
|
public bool SupportsMediaControl => IsSessionActive;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send a message to the DLNA device to notify what is the next track in the playlist.
|
* Send a message to the DLNA device to notify what is the next track in the playlist.
|
||||||
*/
|
*/
|
||||||
|
@ -131,22 +127,22 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDeviceDiscoveryDeviceLeft(object sender, GenericEventArgs<UpnpDeviceInfo> e)
|
private void OnDeviceDiscoveryDeviceLeft(object? sender, GenericEventArgs<UpnpDeviceInfo> e)
|
||||||
{
|
{
|
||||||
var info = e.Argument;
|
var info = e.Argument;
|
||||||
|
|
||||||
if (!_disposed
|
if (!_disposed
|
||||||
&& info.Headers.TryGetValue("USN", out string usn)
|
&& info.Headers.TryGetValue("USN", out string? usn)
|
||||||
&& usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1
|
&& usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1
|
||||||
&& (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1
|
&& (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1
|
||||||
|| (info.Headers.TryGetValue("NT", out string nt)
|
|| (info.Headers.TryGetValue("NT", out string? nt)
|
||||||
&& nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1)))
|
&& nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1)))
|
||||||
{
|
{
|
||||||
OnDeviceUnavailable();
|
OnDeviceUnavailable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnDeviceMediaChanged(object sender, MediaChangedEventArgs e)
|
private async void OnDeviceMediaChanged(object? sender, MediaChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (_disposed || string.IsNullOrEmpty(e.OldMediaInfo.Url))
|
if (_disposed || string.IsNullOrEmpty(e.OldMediaInfo.Url))
|
||||||
{
|
{
|
||||||
|
@ -188,7 +184,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnDevicePlaybackStopped(object sender, PlaybackStoppedEventArgs e)
|
private async void OnDevicePlaybackStopped(object? sender, PlaybackStoppedEventArgs e)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
{
|
{
|
||||||
|
@ -257,7 +253,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnDevicePlaybackStart(object sender, PlaybackStartEventArgs e)
|
private async void OnDevicePlaybackStart(object? sender, PlaybackStartEventArgs e)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
{
|
{
|
||||||
|
@ -281,7 +277,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnDevicePlaybackProgress(object sender, PlaybackProgressEventArgs e)
|
private async void OnDevicePlaybackProgress(object? sender, PlaybackProgressEventArgs e)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
{
|
{
|
||||||
|
@ -486,9 +482,9 @@ namespace Emby.Dlna.PlayTo
|
||||||
|
|
||||||
private PlaylistItem CreatePlaylistItem(
|
private PlaylistItem CreatePlaylistItem(
|
||||||
BaseItem item,
|
BaseItem item,
|
||||||
User user,
|
User? user,
|
||||||
long startPostionTicks,
|
long startPostionTicks,
|
||||||
string mediaSourceId,
|
string? mediaSourceId,
|
||||||
int? audioStreamIndex,
|
int? audioStreamIndex,
|
||||||
int? subtitleStreamIndex)
|
int? subtitleStreamIndex)
|
||||||
{
|
{
|
||||||
|
@ -525,7 +521,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
return playlistItem;
|
return playlistItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetDlnaHeaders(PlaylistItem item)
|
private string? GetDlnaHeaders(PlaylistItem item)
|
||||||
{
|
{
|
||||||
var profile = item.Profile;
|
var profile = item.Profile;
|
||||||
var streamInfo = item.StreamInfo;
|
var streamInfo = item.StreamInfo;
|
||||||
|
@ -579,7 +575,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlaylistItem GetPlaylistItem(BaseItem item, MediaSourceInfo[] mediaSources, DeviceProfile profile, string deviceId, string mediaSourceId, int? audioStreamIndex, int? subtitleStreamIndex)
|
private PlaylistItem GetPlaylistItem(BaseItem item, MediaSourceInfo[] mediaSources, DeviceProfile profile, string deviceId, string? mediaSourceId, int? audioStreamIndex, int? subtitleStreamIndex)
|
||||||
{
|
{
|
||||||
if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
@ -696,7 +692,6 @@ namespace Emby.Dlna.PlayTo
|
||||||
_device.MediaChanged -= OnDeviceMediaChanged;
|
_device.MediaChanged -= OnDeviceMediaChanged;
|
||||||
_deviceDiscovery.DeviceLeft -= OnDeviceDiscoveryDeviceLeft;
|
_deviceDiscovery.DeviceLeft -= OnDeviceDiscoveryDeviceLeft;
|
||||||
_device.OnDeviceUnavailable = null;
|
_device.OnDeviceUnavailable = null;
|
||||||
_device = null;
|
|
||||||
|
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
|
@ -716,7 +711,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
case GeneralCommandType.ToggleMute:
|
case GeneralCommandType.ToggleMute:
|
||||||
return _device.ToggleMute(cancellationToken);
|
return _device.ToggleMute(cancellationToken);
|
||||||
case GeneralCommandType.SetAudioStreamIndex:
|
case GeneralCommandType.SetAudioStreamIndex:
|
||||||
if (command.Arguments.TryGetValue("Index", out string index))
|
if (command.Arguments.TryGetValue("Index", out string? index))
|
||||||
{
|
{
|
||||||
if (int.TryParse(index, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val))
|
if (int.TryParse(index, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val))
|
||||||
{
|
{
|
||||||
|
@ -740,7 +735,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
|
|
||||||
throw new ArgumentException("SetSubtitleStreamIndex argument cannot be null");
|
throw new ArgumentException("SetSubtitleStreamIndex argument cannot be null");
|
||||||
case GeneralCommandType.SetVolume:
|
case GeneralCommandType.SetVolume:
|
||||||
if (command.Arguments.TryGetValue("Volume", out string vol))
|
if (command.Arguments.TryGetValue("Volume", out string? vol))
|
||||||
{
|
{
|
||||||
if (int.TryParse(vol, NumberStyles.Integer, CultureInfo.InvariantCulture, out var volume))
|
if (int.TryParse(vol, NumberStyles.Integer, CultureInfo.InvariantCulture, out var volume))
|
||||||
{
|
{
|
||||||
|
@ -865,34 +860,19 @@ namespace Emby.Dlna.PlayTo
|
||||||
throw new ObjectDisposedException(GetType().Name);
|
throw new ObjectDisposedException(GetType().Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_device is null)
|
return name switch
|
||||||
{
|
{
|
||||||
return Task.CompletedTask;
|
SessionMessageType.Play => SendPlayCommand((data as PlayRequest)!, cancellationToken),
|
||||||
}
|
SessionMessageType.Playstate => SendPlaystateCommand((data as PlaystateRequest)!, cancellationToken),
|
||||||
|
SessionMessageType.GeneralCommand => SendGeneralCommand((data as GeneralCommand)!, cancellationToken),
|
||||||
if (name == SessionMessageType.Play)
|
_ => Task.CompletedTask // Not supported or needed right now
|
||||||
{
|
};
|
||||||
return SendPlayCommand(data as PlayRequest, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name == SessionMessageType.Playstate)
|
|
||||||
{
|
|
||||||
return SendPlaystateCommand(data as PlaystateRequest, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name == SessionMessageType.GeneralCommand)
|
|
||||||
{
|
|
||||||
return SendGeneralCommand(data as GeneralCommand, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not supported or needed right now
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StreamParams
|
private class StreamParams
|
||||||
{
|
{
|
||||||
private MediaSourceInfo _mediaSource;
|
private MediaSourceInfo? _mediaSource;
|
||||||
private IMediaSourceManager _mediaSourceManager;
|
private IMediaSourceManager? _mediaSourceManager;
|
||||||
|
|
||||||
public Guid ItemId { get; set; }
|
public Guid ItemId { get; set; }
|
||||||
|
|
||||||
|
@ -904,17 +884,17 @@ namespace Emby.Dlna.PlayTo
|
||||||
|
|
||||||
public int? SubtitleStreamIndex { get; set; }
|
public int? SubtitleStreamIndex { get; set; }
|
||||||
|
|
||||||
public string DeviceProfileId { get; set; }
|
public string? DeviceProfileId { get; set; }
|
||||||
|
|
||||||
public string DeviceId { get; set; }
|
public string? DeviceId { get; set; }
|
||||||
|
|
||||||
public string MediaSourceId { get; set; }
|
public string? MediaSourceId { get; set; }
|
||||||
|
|
||||||
public string LiveStreamId { get; set; }
|
public string? LiveStreamId { get; set; }
|
||||||
|
|
||||||
public BaseItem Item { get; set; }
|
public BaseItem? Item { get; set; }
|
||||||
|
|
||||||
public async Task<MediaSourceInfo> GetMediaSource(CancellationToken cancellationToken)
|
public async Task<MediaSourceInfo?> GetMediaSource(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (_mediaSource is not null)
|
if (_mediaSource is not null)
|
||||||
{
|
{
|
||||||
|
@ -944,8 +924,8 @@ namespace Emby.Dlna.PlayTo
|
||||||
{
|
{
|
||||||
var part = parts[i];
|
var part = parts[i];
|
||||||
|
|
||||||
if (string.Equals(part, "audio", StringComparison.OrdinalIgnoreCase) ||
|
if (string.Equals(part, "audio", StringComparison.OrdinalIgnoreCase)
|
||||||
string.Equals(part, "videos", StringComparison.OrdinalIgnoreCase))
|
|| string.Equals(part, "videos", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (Guid.TryParse(parts[i + 1], out var result))
|
if (Guid.TryParse(parts[i + 1], out var result))
|
||||||
{
|
{
|
||||||
|
|
|
@ -205,12 +205,11 @@ namespace Emby.Dlna.PlayTo
|
||||||
_userDataManager,
|
_userDataManager,
|
||||||
_localization,
|
_localization,
|
||||||
_mediaSourceManager,
|
_mediaSourceManager,
|
||||||
_mediaEncoder);
|
_mediaEncoder,
|
||||||
|
device);
|
||||||
|
|
||||||
sessionInfo.AddController(controller);
|
sessionInfo.AddController(controller);
|
||||||
|
|
||||||
controller.Init(device);
|
|
||||||
|
|
||||||
var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
|
var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
|
||||||
_dlnaManager.GetDefaultProfile();
|
_dlnaManager.GetDefaultProfile();
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
[XmlAttribute("type")]
|
[XmlAttribute("type")]
|
||||||
public DlnaProfileType Type { get; set; }
|
public DlnaProfileType Type { get; set; }
|
||||||
|
|
||||||
public ProfileCondition[]? Conditions { get; set; } = Array.Empty<ProfileCondition>();
|
public ProfileCondition[] Conditions { get; set; } = Array.Empty<ProfileCondition>();
|
||||||
|
|
||||||
[XmlAttribute("container")]
|
[XmlAttribute("container")]
|
||||||
public string Container { get; set; } = string.Empty;
|
public string Container { get; set; } = string.Empty;
|
||||||
|
|
|
@ -18,17 +18,17 @@ namespace MediaBrowser.Model.Dlna
|
||||||
[XmlAttribute("type")]
|
[XmlAttribute("type")]
|
||||||
public DlnaProfileType Type { get; set; }
|
public DlnaProfileType Type { get; set; }
|
||||||
|
|
||||||
public bool SupportsContainer(string container)
|
public bool SupportsContainer(string? container)
|
||||||
{
|
{
|
||||||
return ContainerProfile.ContainsContainer(Container, container);
|
return ContainerProfile.ContainsContainer(Container, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SupportsVideoCodec(string codec)
|
public bool SupportsVideoCodec(string? codec)
|
||||||
{
|
{
|
||||||
return Type == DlnaProfileType.Video && ContainerProfile.ContainsContainer(VideoCodec, codec);
|
return Type == DlnaProfileType.Video && ContainerProfile.ContainsContainer(VideoCodec, codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SupportsAudioCodec(string codec)
|
public bool SupportsAudioCodec(string? codec)
|
||||||
{
|
{
|
||||||
return (Type == DlnaProfileType.Audio || Type == DlnaProfileType.Video) && ContainerProfile.ContainsContainer(AudioCodec, codec);
|
return (Type == DlnaProfileType.Audio || Type == DlnaProfileType.Video) && ContainerProfile.ContainsContainer(AudioCodec, codec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,22 +10,4 @@ namespace MediaBrowser.Model.Dlna
|
||||||
|
|
||||||
bool CanExtractSubtitles(string codec);
|
bool CanExtractSubtitles(string codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FullTranscoderSupport : ITranscoderSupport
|
|
||||||
{
|
|
||||||
public bool CanEncodeToAudioCodec(string codec)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanEncodeToSubtitleCodec(string codec)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanExtractSubtitles(string codec)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
|
|
||||||
|
@ -59,22 +57,22 @@ namespace MediaBrowser.Model.Dlna
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the media sources.
|
/// Gets or sets the media sources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MediaSourceInfo[] MediaSources { get; set; }
|
public MediaSourceInfo[] MediaSources { get; set; } = Array.Empty<MediaSourceInfo>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the device profile.
|
/// Gets or sets the device profile.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DeviceProfile Profile { get; set; }
|
required public DeviceProfile Profile { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a media source id. Optional. Only needed if a specific AudioStreamIndex or SubtitleStreamIndex are requested.
|
/// Gets or sets a media source id. Optional. Only needed if a specific AudioStreamIndex or SubtitleStreamIndex are requested.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string MediaSourceId { get; set; }
|
public string? MediaSourceId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the device id.
|
/// Gets or sets the device id.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DeviceId { get; set; }
|
public string? DeviceId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets an override of supported number of audio channels
|
/// Gets or sets an override of supported number of audio channels
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -37,29 +35,20 @@ namespace MediaBrowser.Model.Dlna
|
||||||
_logger = logger;
|
_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>
|
/// <summary>
|
||||||
/// Gets the optimal audio stream.
|
/// Gets the optimal audio stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">The <see cref="MediaOptions"/> object to get the audio stream from.</param>
|
/// <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>
|
/// <returns>The <see cref="StreamInfo"/> of the optimal audio stream.</returns>
|
||||||
public StreamInfo GetOptimalAudioStream(MediaOptions options)
|
public StreamInfo? GetOptimalAudioStream(MediaOptions options)
|
||||||
{
|
{
|
||||||
ValidateMediaOptions(options, false);
|
ValidateMediaOptions(options, false);
|
||||||
|
|
||||||
var mediaSources = new List<MediaSourceInfo>();
|
var mediaSources = new List<MediaSourceInfo>();
|
||||||
foreach (var mediaSource in options.MediaSources)
|
foreach (var mediaSource in options.MediaSources)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(options.MediaSourceId) ||
|
if (string.IsNullOrEmpty(options.MediaSourceId)
|
||||||
string.Equals(mediaSource.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
|
|| string.Equals(mediaSource.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
mediaSources.Add(mediaSource);
|
mediaSources.Add(mediaSource);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +57,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
var streams = new List<StreamInfo>();
|
var streams = new List<StreamInfo>();
|
||||||
foreach (var mediaSourceInfo in mediaSources)
|
foreach (var mediaSourceInfo in mediaSources)
|
||||||
{
|
{
|
||||||
StreamInfo streamInfo = GetOptimalAudioStream(mediaSourceInfo, options);
|
StreamInfo? streamInfo = GetOptimalAudioStream(mediaSourceInfo, options);
|
||||||
if (streamInfo is not null)
|
if (streamInfo is not null)
|
||||||
{
|
{
|
||||||
streams.Add(streamInfo);
|
streams.Add(streamInfo);
|
||||||
|
@ -84,7 +73,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return GetOptimalStream(streams, options.GetMaxBitrate(true) ?? 0);
|
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
|
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)
|
foreach (var tcProfile in options.Profile.TranscodingProfiles)
|
||||||
{
|
{
|
||||||
if (tcProfile.Type == playlistItem.MediaType
|
if (tcProfile.Type == playlistItem.MediaType
|
||||||
|
@ -190,15 +179,15 @@ namespace MediaBrowser.Model.Dlna
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">The <see cref="MediaOptions"/> object to get the video stream from.</param>
|
/// <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>
|
/// <returns>The <see cref="StreamInfo"/> of the optimal video stream.</returns>
|
||||||
public StreamInfo GetOptimalVideoStream(MediaOptions options)
|
public StreamInfo? GetOptimalVideoStream(MediaOptions options)
|
||||||
{
|
{
|
||||||
ValidateMediaOptions(options, true);
|
ValidateMediaOptions(options, true);
|
||||||
|
|
||||||
var mediaSources = new List<MediaSourceInfo>();
|
var mediaSources = new List<MediaSourceInfo>();
|
||||||
foreach (var mediaSourceInfo in options.MediaSources)
|
foreach (var mediaSourceInfo in options.MediaSources)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(options.MediaSourceId) ||
|
if (string.IsNullOrEmpty(options.MediaSourceId)
|
||||||
string.Equals(mediaSourceInfo.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
|
|| string.Equals(mediaSourceInfo.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
mediaSources.Add(mediaSourceInfo);
|
mediaSources.Add(mediaSourceInfo);
|
||||||
}
|
}
|
||||||
|
@ -223,7 +212,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return GetOptimalStream(streams, options.GetMaxBitrate(false) ?? 0);
|
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();
|
=> SortMediaSources(streams, maxBitrate).FirstOrDefault();
|
||||||
|
|
||||||
private static IOrderedEnumerable<StreamInfo> SortMediaSources(List<StreamInfo> streams, long maxBitrate)
|
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="type">The <see cref="DlnaProfileType"/>.</param>
|
||||||
/// <param name="playProfile">The <see cref="DirectPlayProfile"/> object to get the video stream from.</param>
|
/// <param name="playProfile">The <see cref="DirectPlayProfile"/> object to get the video stream from.</param>
|
||||||
/// <returns>The the normalized input container.</returns>
|
/// <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))
|
if (string.IsNullOrEmpty(inputContainer))
|
||||||
{
|
{
|
||||||
|
@ -394,7 +383,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return formats[0];
|
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
|
var directPlayProfile = options.Profile.DirectPlayProfiles
|
||||||
.FirstOrDefault(x => x.Type == DlnaProfileType.Audio && IsAudioDirectPlaySupported(x, item, audioStream));
|
.FirstOrDefault(x => x.Type == DlnaProfileType.Audio && IsAudioDirectPlaySupported(x, item, audioStream));
|
||||||
|
@ -449,7 +438,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return (directPlayProfile, null, transcodeReasons);
|
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;
|
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 container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Video, directPlayProfile);
|
||||||
var protocol = "http";
|
var protocol = "http";
|
||||||
|
@ -587,7 +576,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
playlistItem.SubProtocol = protocol;
|
playlistItem.SubProtocol = protocol;
|
||||||
|
|
||||||
playlistItem.VideoCodecs = new[] { item.VideoStream.Codec };
|
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)
|
private StreamInfo BuildVideoItem(MediaSourceInfo item, MediaOptions options)
|
||||||
|
@ -646,7 +635,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
isEligibleForDirectPlay,
|
isEligibleForDirectPlay,
|
||||||
isEligibleForDirectStream);
|
isEligibleForDirectStream);
|
||||||
|
|
||||||
DirectPlayProfile directPlayProfile = null;
|
DirectPlayProfile? directPlayProfile = null;
|
||||||
if (isEligibleForDirectPlay || isEligibleForDirectStream)
|
if (isEligibleForDirectPlay || isEligibleForDirectStream)
|
||||||
{
|
{
|
||||||
// See if it can be direct played
|
// See if it can be direct played
|
||||||
|
@ -677,16 +666,16 @@ namespace MediaBrowser.Model.Dlna
|
||||||
playlistItem.AudioStreamIndex = audioStream?.Index;
|
playlistItem.AudioStreamIndex = audioStream?.Index;
|
||||||
if (audioStream is not null)
|
if (audioStream is not null)
|
||||||
{
|
{
|
||||||
playlistItem.AudioCodecs = ContainerProfile.SplitValue(directPlayProfile.AudioCodec);
|
playlistItem.AudioCodecs = ContainerProfile.SplitValue(directPlayProfile?.AudioCodec);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetStreamInfoOptionsFromDirectPlayProfile(options, item, playlistItem, directPlayProfile);
|
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)
|
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.SubtitleDeliveryMethod = subtitleProfile.Method;
|
||||||
playlistItem.SubtitleFormat = subtitleProfile.Format;
|
playlistItem.SubtitleFormat = subtitleProfile.Format;
|
||||||
|
@ -748,7 +737,14 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return playlistItem;
|
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))
|
if (!(item.SupportsTranscoding || item.SupportsDirectStream))
|
||||||
{
|
{
|
||||||
|
@ -795,7 +791,16 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return transcodingProfiles.FirstOrDefault();
|
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
|
// Prefer matching video codecs
|
||||||
var videoCodecs = ContainerProfile.SplitValue(videoCodec);
|
var videoCodecs = ContainerProfile.SplitValue(videoCodec);
|
||||||
|
@ -862,12 +867,12 @@ namespace MediaBrowser.Model.Dlna
|
||||||
int? bitDepth = videoStream?.BitDepth;
|
int? bitDepth = videoStream?.BitDepth;
|
||||||
int? videoBitrate = videoStream?.BitRate;
|
int? videoBitrate = videoStream?.BitRate;
|
||||||
double? videoLevel = videoStream?.Level;
|
double? videoLevel = videoStream?.Level;
|
||||||
string videoProfile = videoStream?.Profile;
|
string? videoProfile = videoStream?.Profile;
|
||||||
string videoRangeType = videoStream?.VideoRangeType;
|
string? videoRangeType = videoStream?.VideoRangeType;
|
||||||
float videoFramerate = videoStream is null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
|
float videoFramerate = videoStream is null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
|
||||||
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
||||||
bool? isInterlaced = videoStream?.IsInterlaced;
|
bool? isInterlaced = videoStream?.IsInterlaced;
|
||||||
string videoCodecTag = videoStream?.CodecTag;
|
string? videoCodecTag = videoStream?.CodecTag;
|
||||||
bool? isAvc = videoStream?.IsAVC;
|
bool? isAvc = videoStream?.IsAVC;
|
||||||
|
|
||||||
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : item.Timestamp;
|
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);
|
playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate);
|
||||||
|
|
||||||
bool? isSecondaryAudio = audioStream is null ? null : item.IsSecondaryAudio(audioStream);
|
bool? isSecondaryAudio = audioStream is null ? null : item.IsSecondaryAudio(audioStream);
|
||||||
int? inputAudioBitrate = audioStream is null ? null : audioStream.BitRate;
|
int? inputAudioBitrate = audioStream?.BitRate;
|
||||||
int? audioChannels = audioStream is null ? null : audioStream.Channels;
|
int? audioChannels = audioStream?.Channels;
|
||||||
string audioProfile = audioStream is null ? null : audioStream.Profile;
|
string? audioProfile = audioStream?.Profile;
|
||||||
int? inputAudioSampleRate = audioStream is null ? null : audioStream.SampleRate;
|
int? inputAudioSampleRate = audioStream?.SampleRate;
|
||||||
int? inputAudioBitDepth = audioStream is null ? null : audioStream.BitDepth;
|
int? inputAudioBitDepth = audioStream?.BitDepth;
|
||||||
|
|
||||||
var appliedAudioConditions = options.Profile.CodecProfiles
|
var appliedAudioConditions = options.Profile.CodecProfiles
|
||||||
.Where(i => i.Type == CodecType.VideoAudio &&
|
.Where(i => i.Type == CodecType.VideoAudio &&
|
||||||
|
@ -955,7 +960,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
playlistItem?.TranscodeReasons);
|
playlistItem?.TranscodeReasons);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetDefaultAudioBitrate(string audioCodec, int? audioChannels)
|
private static int GetDefaultAudioBitrate(string? audioCodec, int? audioChannels)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(audioCodec))
|
if (!string.IsNullOrEmpty(audioCodec))
|
||||||
{
|
{
|
||||||
|
@ -988,9 +993,9 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return 192000;
|
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);
|
int? targetAudioChannels = item.GetTargetAudioChannels(targetAudioCodec);
|
||||||
|
|
||||||
|
@ -1081,13 +1086,13 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return 7168000;
|
return 7168000;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (DirectPlayProfile Profile, PlayMethod? PlayMethod, int? AudioStreamIndex, TranscodeReason TranscodeReasons) GetVideoDirectPlayProfile(
|
private (DirectPlayProfile? Profile, PlayMethod? PlayMethod, int? AudioStreamIndex, TranscodeReason TranscodeReasons) GetVideoDirectPlayProfile(
|
||||||
MediaOptions options,
|
MediaOptions options,
|
||||||
MediaSourceInfo mediaSource,
|
MediaSourceInfo mediaSource,
|
||||||
MediaStream videoStream,
|
MediaStream? videoStream,
|
||||||
MediaStream audioStream,
|
MediaStream? audioStream,
|
||||||
ICollection<MediaStream> candidateAudioStreams,
|
ICollection<MediaStream> candidateAudioStreams,
|
||||||
MediaStream subtitleStream,
|
MediaStream? subtitleStream,
|
||||||
bool isEligibleForDirectPlay,
|
bool isEligibleForDirectPlay,
|
||||||
bool isEligibleForDirectStream)
|
bool isEligibleForDirectStream)
|
||||||
{
|
{
|
||||||
|
@ -1110,12 +1115,12 @@ namespace MediaBrowser.Model.Dlna
|
||||||
int? bitDepth = videoStream?.BitDepth;
|
int? bitDepth = videoStream?.BitDepth;
|
||||||
int? videoBitrate = videoStream?.BitRate;
|
int? videoBitrate = videoStream?.BitRate;
|
||||||
double? videoLevel = videoStream?.Level;
|
double? videoLevel = videoStream?.Level;
|
||||||
string videoProfile = videoStream?.Profile;
|
string? videoProfile = videoStream?.Profile;
|
||||||
string videoRangeType = videoStream?.VideoRangeType;
|
string? videoRangeType = videoStream?.VideoRangeType;
|
||||||
float videoFramerate = videoStream is null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
|
float videoFramerate = videoStream is null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
|
||||||
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
||||||
bool? isInterlaced = videoStream?.IsInterlaced;
|
bool? isInterlaced = videoStream?.IsInterlaced;
|
||||||
string videoCodecTag = videoStream?.CodecTag;
|
string? videoCodecTag = videoStream?.CodecTag;
|
||||||
bool? isAvc = videoStream?.IsAVC;
|
bool? isAvc = videoStream?.IsAVC;
|
||||||
|
|
||||||
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : mediaSource.Timestamp;
|
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : mediaSource.Timestamp;
|
||||||
|
@ -1203,14 +1208,14 @@ namespace MediaBrowser.Model.Dlna
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check video codec
|
// Check video codec
|
||||||
string videoCodec = videoStream?.Codec;
|
string? videoCodec = videoStream?.Codec;
|
||||||
if (!directPlayProfile.SupportsVideoCodec(videoCodec))
|
if (!directPlayProfile.SupportsVideoCodec(videoCodec))
|
||||||
{
|
{
|
||||||
directPlayProfileReasons |= TranscodeReason.VideoCodecNotSupported;
|
directPlayProfileReasons |= TranscodeReason.VideoCodecNotSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check audio codec
|
// Check audio codec
|
||||||
MediaStream selectedAudioStream = null;
|
MediaStream? selectedAudioStream = null;
|
||||||
if (candidateAudioStreams.Any())
|
if (candidateAudioStreams.Any())
|
||||||
{
|
{
|
||||||
selectedAudioStream = candidateAudioStreams.FirstOrDefault(audioStream => directPlayProfile.SupportsAudioCodec(audioStream.Codec));
|
selectedAudioStream = candidateAudioStreams.FirstOrDefault(audioStream => directPlayProfile.SupportsAudioCodec(audioStream.Codec));
|
||||||
|
@ -1331,8 +1336,8 @@ namespace MediaBrowser.Model.Dlna
|
||||||
SubtitleProfile[] subtitleProfiles,
|
SubtitleProfile[] subtitleProfiles,
|
||||||
PlayMethod playMethod,
|
PlayMethod playMethod,
|
||||||
ITranscoderSupport transcoderSupport,
|
ITranscoderSupport transcoderSupport,
|
||||||
string outputContainer,
|
string? outputContainer,
|
||||||
string transcodingSubProtocol)
|
string? transcodingSubProtocol)
|
||||||
{
|
{
|
||||||
if (!subtitleStream.IsExternal && (playMethod != PlayMethod.Transcode || !string.Equals(transcodingSubProtocol, "hls", StringComparison.OrdinalIgnoreCase)))
|
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))
|
if (!string.IsNullOrEmpty(transcodingContainer))
|
||||||
{
|
{
|
||||||
|
@ -1427,7 +1432,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return false;
|
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)
|
foreach (var profile in subtitleProfiles)
|
||||||
{
|
{
|
||||||
|
@ -1560,7 +1565,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
private static IEnumerable<ProfileCondition> GetProfileConditionsForAudio(
|
private static IEnumerable<ProfileCondition> GetProfileConditionsForAudio(
|
||||||
IEnumerable<CodecProfile> codecProfiles,
|
IEnumerable<CodecProfile> codecProfiles,
|
||||||
string container,
|
string container,
|
||||||
string codec,
|
string? codec,
|
||||||
int? audioChannels,
|
int? audioChannels,
|
||||||
int? audioBitrate,
|
int? audioBitrate,
|
||||||
int? audioSampleRate,
|
int? audioSampleRate,
|
||||||
|
@ -1580,7 +1585,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return conditions.Where(condition => !ConditionProcessor.IsAudioConditionSatisfied(condition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth));
|
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)
|
foreach (ProfileCondition condition in conditions)
|
||||||
{
|
{
|
||||||
|
@ -2056,7 +2061,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check audio codec
|
// Check audio codec
|
||||||
string audioCodec = audioStream?.Codec;
|
string? audioCodec = audioStream?.Codec;
|
||||||
if (!profile.SupportsAudioCodec(audioCodec))
|
if (!profile.SupportsAudioCodec(audioCodec))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in a new issue