aboutsummaryrefslogtreecommitdiff
path: root/Emby.Dlna/PlayTo/PlayToController.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Dlna/PlayTo/PlayToController.cs')
-rw-r--r--Emby.Dlna/PlayTo/PlayToController.cs198
1 files changed, 88 insertions, 110 deletions
diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs
index 0e49fd2c02..b1ad15cdc9 100644
--- a/Emby.Dlna/PlayTo/PlayToController.cs
+++ b/Emby.Dlna/PlayTo/PlayToController.cs
@@ -1,5 +1,3 @@
-#nullable disable
-
#pragma warning disable CS1591
using System;
@@ -30,8 +28,6 @@ namespace Emby.Dlna.PlayTo
{
public class PlayToController : ISessionController, IDisposable
{
- private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US"));
-
private readonly SessionInfo _session;
private readonly ISessionManager _sessionManager;
private readonly ILibraryManager _libraryManager;
@@ -46,7 +42,7 @@ namespace Emby.Dlna.PlayTo
private readonly IDeviceDiscovery _deviceDiscovery;
private readonly string _serverAddress;
- private readonly string _accessToken;
+ private readonly string? _accessToken;
private readonly List<PlaylistItem> _playlist = new List<PlaylistItem>();
private Device _device;
@@ -63,12 +59,13 @@ namespace Emby.Dlna.PlayTo
IUserManager userManager,
IImageProcessor imageProcessor,
string serverAddress,
- string accessToken,
+ string? accessToken,
IDeviceDiscovery deviceDiscovery,
IUserDataManager userDataManager,
ILocalizationManager localization,
IMediaSourceManager mediaSourceManager,
- IMediaEncoder mediaEncoder)
+ IMediaEncoder mediaEncoder,
+ Device device)
{
_session = session;
_sessionManager = sessionManager;
@@ -84,14 +81,7 @@ namespace Emby.Dlna.PlayTo
_localization = localization;
_mediaSourceManager = mediaSourceManager;
_mediaEncoder = mediaEncoder;
- }
-
- public bool IsSessionActive => !_disposed && _device != null;
- public bool SupportsMediaControl => IsSessionActive;
-
- public void Init(Device device)
- {
_device = device;
_device.OnDeviceUnavailable = OnDeviceUnavailable;
_device.PlaybackStart += OnDevicePlaybackStart;
@@ -104,6 +94,10 @@ namespace Emby.Dlna.PlayTo
_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.
*/
@@ -133,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;
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("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1
- || (info.Headers.TryGetValue("NT", out string nt)
+ || (info.Headers.TryGetValue("NT", out string? nt)
&& nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1)))
{
OnDeviceUnavailable();
}
}
- private async void OnDeviceMediaChanged(object sender, MediaChangedEventArgs e)
+ private async void OnDeviceMediaChanged(object? sender, MediaChangedEventArgs e)
{
if (_disposed || string.IsNullOrEmpty(e.OldMediaInfo.Url))
{
@@ -158,7 +152,7 @@ namespace Emby.Dlna.PlayTo
try
{
var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager, _mediaSourceManager);
- if (streamInfo.Item != null)
+ if (streamInfo.Item is not null)
{
var positionTicks = GetProgressPositionTicks(streamInfo);
@@ -166,7 +160,7 @@ namespace Emby.Dlna.PlayTo
}
streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager, _mediaSourceManager);
- if (streamInfo.Item == null)
+ if (streamInfo.Item is null)
{
return;
}
@@ -176,13 +170,13 @@ namespace Emby.Dlna.PlayTo
await _sessionManager.OnPlaybackStart(newItemProgress).ConfigureAwait(false);
// Send a message to the DLNA device to notify what is the next track in the playlist.
- var currentItemIndex = _playlist.FindIndex(item => item.StreamInfo.ItemId == streamInfo.ItemId);
+ var currentItemIndex = _playlist.FindIndex(item => item.StreamInfo.ItemId.Equals(streamInfo.ItemId));
if (currentItemIndex >= 0)
{
_currentPlaylistIndex = currentItemIndex;
}
- await SendNextTrackMessage(currentItemIndex, CancellationToken.None);
+ await SendNextTrackMessage(currentItemIndex, CancellationToken.None).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -190,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)
{
@@ -201,7 +195,7 @@ namespace Emby.Dlna.PlayTo
{
var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
- if (streamInfo.Item == null)
+ if (streamInfo.Item is null)
{
return;
}
@@ -212,9 +206,9 @@ namespace Emby.Dlna.PlayTo
var mediaSource = await streamInfo.GetMediaSource(CancellationToken.None).ConfigureAwait(false);
- var duration = mediaSource == null ?
- (_device.Duration == null ? (long?)null : _device.Duration.Value.Ticks) :
- mediaSource.RunTimeTicks;
+ var duration = mediaSource is null
+ ? _device.Duration?.Ticks
+ : mediaSource.RunTimeTicks;
var playedToCompletion = positionTicks.HasValue && positionTicks.Value == 0;
@@ -259,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)
{
@@ -270,7 +264,7 @@ namespace Emby.Dlna.PlayTo
{
var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
- if (info.Item != null)
+ if (info.Item is not null)
{
var progress = GetProgressInfo(info);
@@ -283,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)
{
@@ -301,7 +295,7 @@ namespace Emby.Dlna.PlayTo
var info = StreamParams.ParseFromUrl(mediaUrl, _libraryManager, _mediaSourceManager);
- if (info.Item != null)
+ if (info.Item is not null)
{
var progress = GetProgressInfo(info);
@@ -340,7 +334,6 @@ namespace Emby.Dlna.PlayTo
SubtitleStreamIndex = info.SubtitleStreamIndex,
VolumeLevel = _device.Volume,
- // TODO
CanSeek = true,
PlayMethod = info.IsDirectStream ? PlayMethod.DirectStream : PlayMethod.Transcode
@@ -351,7 +344,9 @@ namespace Emby.Dlna.PlayTo
{
_logger.LogDebug("{0} - Received PlayRequest: {1}", _session.DeviceName, command.PlayCommand);
- var user = command.ControllingUserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(command.ControllingUserId);
+ var user = command.ControllingUserId.Equals(default)
+ ? null :
+ _userManager.GetUserById(command.ControllingUserId);
var items = new List<BaseItem>();
foreach (var id in command.ItemIds)
@@ -394,7 +389,7 @@ namespace Emby.Dlna.PlayTo
_playlist.AddRange(playlist);
}
- if (!command.ControllingUserId.Equals(Guid.Empty))
+ if (!command.ControllingUserId.Equals(default))
{
_sessionManager.LogSessionActivity(
_session.Client,
@@ -442,20 +437,22 @@ namespace Emby.Dlna.PlayTo
{
var media = _device.CurrentMediaInfo;
- if (media != null)
+ if (media is not null)
{
var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
- if (info.Item != null && !EnableClientSideSeek(info))
+ if (info.Item is not null && !EnableClientSideSeek(info))
{
- var user = !_session.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(_session.UserId) : null;
+ var user = _session.UserId.Equals(default)
+ ? null
+ : _userManager.GetUserById(_session.UserId);
var newItem = CreatePlaylistItem(info.Item, user, newPosition, info.MediaSourceId, info.AudioStreamIndex, info.SubtitleStreamIndex);
await _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl, CancellationToken.None).ConfigureAwait(false);
// Send a message to the DLNA device to notify what is the next track in the play list.
var newItemIndex = _playlist.FindIndex(item => item.StreamUrl == newItem.StreamUrl);
- await SendNextTrackMessage(newItemIndex, CancellationToken.None);
+ await SendNextTrackMessage(newItemIndex, CancellationToken.None).ConfigureAwait(false);
return;
}
@@ -485,9 +482,9 @@ namespace Emby.Dlna.PlayTo
private PlaylistItem CreatePlaylistItem(
BaseItem item,
- User user,
+ User? user,
long startPostionTicks,
- string mediaSourceId,
+ string? mediaSourceId,
int? audioStreamIndex,
int? subtitleStreamIndex)
{
@@ -524,7 +521,7 @@ namespace Emby.Dlna.PlayTo
return playlistItem;
}
- private string GetDlnaHeaders(PlaylistItem item)
+ private string? GetDlnaHeaders(PlaylistItem item)
{
var profile = item.Profile;
var streamInfo = item.StreamInfo;
@@ -559,6 +556,7 @@ namespace Emby.Dlna.PlayTo
streamInfo.IsDirectStream,
streamInfo.RunTimeTicks ?? 0,
streamInfo.TargetVideoProfile,
+ streamInfo.TargetVideoRangeType,
streamInfo.TargetVideoLevel,
streamInfo.TargetFramerate ?? 0,
streamInfo.TargetPacketLength,
@@ -571,19 +569,19 @@ namespace Emby.Dlna.PlayTo
streamInfo.TargetVideoCodecTag,
streamInfo.IsTargetAVC);
- return list.Count == 0 ? null : list[0];
+ return list.FirstOrDefault();
}
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))
{
return new PlaylistItem
{
- StreamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildVideoItem(new VideoOptions
+ StreamInfo = new StreamBuilder(_mediaEncoder, _logger).GetOptimalVideoStream(new MediaOptions
{
ItemId = item.Id,
MediaSources = mediaSources,
@@ -603,7 +601,7 @@ namespace Emby.Dlna.PlayTo
{
return new PlaylistItem
{
- StreamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildAudioItem(new AudioOptions
+ StreamInfo = new StreamBuilder(_mediaEncoder, _logger).GetOptimalAudioStream(new MediaOptions
{
ItemId = item.Id,
MediaSources = mediaSources,
@@ -656,7 +654,7 @@ namespace Emby.Dlna.PlayTo
await _device.SetAvTransport(currentitem.StreamUrl, GetDlnaHeaders(currentitem), currentitem.Didl, cancellationToken).ConfigureAwait(false);
// Send a message to the DLNA device to notify what is the next track in the play list.
- await SendNextTrackMessage(index, cancellationToken);
+ await SendNextTrackMessage(index, cancellationToken).ConfigureAwait(false);
var streamInfo = currentitem.StreamInfo;
if (streamInfo.StartPositionTicks > 0 && EnableClientSideSeek(streamInfo))
@@ -694,7 +692,6 @@ namespace Emby.Dlna.PlayTo
_device.MediaChanged -= OnDeviceMediaChanged;
_deviceDiscovery.DeviceLeft -= OnDeviceDiscoveryDeviceLeft;
_device.OnDeviceUnavailable = null;
- _device = null;
_disposed = true;
}
@@ -714,9 +711,9 @@ namespace Emby.Dlna.PlayTo
case GeneralCommandType.ToggleMute:
return _device.ToggleMute(cancellationToken);
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, _usCulture, out var val))
+ if (int.TryParse(index, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val))
{
return SetAudioStreamIndex(val);
}
@@ -728,7 +725,7 @@ namespace Emby.Dlna.PlayTo
case GeneralCommandType.SetSubtitleStreamIndex:
if (command.Arguments.TryGetValue("Index", out index))
{
- if (int.TryParse(index, NumberStyles.Integer, _usCulture, out var val))
+ if (int.TryParse(index, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val))
{
return SetSubtitleStreamIndex(val);
}
@@ -738,9 +735,9 @@ namespace Emby.Dlna.PlayTo
throw new ArgumentException("SetSubtitleStreamIndex argument cannot be null");
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, _usCulture, out var volume))
+ if (int.TryParse(vol, NumberStyles.Integer, CultureInfo.InvariantCulture, out var volume))
{
return _device.SetVolume(volume, cancellationToken);
}
@@ -758,22 +755,24 @@ namespace Emby.Dlna.PlayTo
{
var media = _device.CurrentMediaInfo;
- if (media != null)
+ if (media is not null)
{
var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
- if (info.Item != null)
+ if (info.Item is not null)
{
var newPosition = GetProgressPositionTicks(info) ?? 0;
- var user = !_session.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(_session.UserId) : null;
+ var user = _session.UserId.Equals(default)
+ ? null
+ : _userManager.GetUserById(_session.UserId);
var newItem = CreatePlaylistItem(info.Item, user, newPosition, info.MediaSourceId, newIndex, info.SubtitleStreamIndex);
await _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl, CancellationToken.None).ConfigureAwait(false);
// Send a message to the DLNA device to notify what is the next track in the play list.
var newItemIndex = _playlist.FindIndex(item => item.StreamUrl == newItem.StreamUrl);
- await SendNextTrackMessage(newItemIndex, CancellationToken.None);
+ await SendNextTrackMessage(newItemIndex, CancellationToken.None).ConfigureAwait(false);
if (EnableClientSideSeek(newItem.StreamInfo))
{
@@ -787,22 +786,24 @@ namespace Emby.Dlna.PlayTo
{
var media = _device.CurrentMediaInfo;
- if (media != null)
+ if (media is not null)
{
var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
- if (info.Item != null)
+ if (info.Item is not null)
{
var newPosition = GetProgressPositionTicks(info) ?? 0;
- var user = !_session.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(_session.UserId) : null;
+ var user = _session.UserId.Equals(default)
+ ? null
+ : _userManager.GetUserById(_session.UserId);
var newItem = CreatePlaylistItem(info.Item, user, newPosition, info.MediaSourceId, info.AudioStreamIndex, newIndex);
await _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl, CancellationToken.None).ConfigureAwait(false);
// Send a message to the DLNA device to notify what is the next track in the play list.
var newItemIndex = _playlist.FindIndex(item => item.StreamUrl == newItem.StreamUrl);
- await SendNextTrackMessage(newItemIndex, CancellationToken.None);
+ await SendNextTrackMessage(newItemIndex, CancellationToken.None).ConfigureAwait(false);
if (EnableClientSideSeek(newItem.StreamInfo) && newPosition > 0)
{
@@ -818,7 +819,7 @@ namespace Emby.Dlna.PlayTo
const int Interval = 500;
var currentWait = 0;
- while (_device.TransportState != TransportState.Playing && currentWait < MaxWait)
+ while (_device.TransportState != TransportState.PLAYING && currentWait < MaxWait)
{
await Task.Delay(Interval, cancellationToken).ConfigureAwait(false);
currentWait += Interval;
@@ -859,34 +860,19 @@ namespace Emby.Dlna.PlayTo
throw new ObjectDisposedException(GetType().Name);
}
- if (_device == null)
- {
- return Task.CompletedTask;
- }
-
- if (name == SessionMessageType.Play)
- {
- return SendPlayCommand(data as PlayRequest, cancellationToken);
- }
-
- if (name == SessionMessageType.Playstate)
+ return name switch
{
- 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;
+ SessionMessageType.Play => SendPlayCommand((data as PlayRequest)!, cancellationToken),
+ SessionMessageType.Playstate => SendPlaystateCommand((data as PlaystateRequest)!, cancellationToken),
+ SessionMessageType.GeneralCommand => SendGeneralCommand((data as GeneralCommand)!, cancellationToken),
+ _ => Task.CompletedTask // Not supported or needed right now
+ };
}
private class StreamParams
{
- private MediaSourceInfo mediaSource;
- private IMediaSourceManager _mediaSourceManager;
+ private MediaSourceInfo? _mediaSource;
+ private IMediaSourceManager? _mediaSourceManager;
public Guid ItemId { get; set; }
@@ -898,44 +884,39 @@ namespace Emby.Dlna.PlayTo
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 != null)
+ if (_mediaSource is not null)
{
- return mediaSource;
+ return _mediaSource;
}
- var hasMediaSources = Item as IHasMediaSources;
-
- if (hasMediaSources == null)
+ if (Item is not IHasMediaSources)
{
return null;
}
- if (_mediaSourceManager != null)
+ if (_mediaSourceManager is not null)
{
- mediaSource = await _mediaSourceManager.GetMediaSource(Item, MediaSourceId, LiveStreamId, false, cancellationToken).ConfigureAwait(false);
+ _mediaSource = await _mediaSourceManager.GetMediaSource(Item, MediaSourceId, LiveStreamId, false, cancellationToken).ConfigureAwait(false);
}
- return mediaSource;
+ return _mediaSource;
}
private static Guid GetItemId(string url)
{
- if (string.IsNullOrEmpty(url))
- {
- throw new ArgumentNullException(nameof(url));
- }
+ ArgumentException.ThrowIfNullOrEmpty(url);
var parts = url.Split('/');
@@ -943,8 +924,8 @@ namespace Emby.Dlna.PlayTo
{
var part = parts[i];
- if (string.Equals(part, "audio", StringComparison.OrdinalIgnoreCase) ||
- string.Equals(part, "videos", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(part, "audio", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(part, "videos", StringComparison.OrdinalIgnoreCase))
{
if (Guid.TryParse(parts[i + 1], out var result))
{
@@ -953,22 +934,19 @@ namespace Emby.Dlna.PlayTo
}
}
- return Guid.Empty;
+ return default;
}
public static StreamParams ParseFromUrl(string url, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager)
{
- if (string.IsNullOrEmpty(url))
- {
- throw new ArgumentNullException(nameof(url));
- }
+ ArgumentException.ThrowIfNullOrEmpty(url);
var request = new StreamParams
{
ItemId = GetItemId(url)
};
- if (request.ItemId.Equals(Guid.Empty))
+ if (request.ItemId.Equals(default))
{
return request;
}