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.cs337
1 files changed, 178 insertions, 159 deletions
diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs
index 9d7c0d365..a5b8e2b3c 100644
--- a/Emby.Dlna/PlayTo/PlayToController.cs
+++ b/Emby.Dlna/PlayTo/PlayToController.cs
@@ -7,6 +7,8 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Emby.Dlna.Didl;
+using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
@@ -17,11 +19,11 @@ using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Session;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
+using Photo = MediaBrowser.Controller.Entities.Photo;
namespace Emby.Dlna.PlayTo
{
@@ -29,7 +31,6 @@ namespace Emby.Dlna.PlayTo
{
private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US"));
- private Device _device;
private readonly SessionInfo _session;
private readonly ISessionManager _sessionManager;
private readonly ILibraryManager _libraryManager;
@@ -48,6 +49,7 @@ namespace Emby.Dlna.PlayTo
private readonly string _accessToken;
private readonly List<PlaylistItem> _playlist = new List<PlaylistItem>();
+ private Device _device;
private int _currentPlaylistIndex;
private bool _disposed;
@@ -146,11 +148,14 @@ namespace Emby.Dlna.PlayTo
{
var positionTicks = GetProgressPositionTicks(streamInfo);
- ReportPlaybackStopped(streamInfo, positionTicks);
+ await ReportPlaybackStopped(streamInfo, positionTicks).ConfigureAwait(false);
}
streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager, _mediaSourceManager);
- if (streamInfo.Item == null) return;
+ if (streamInfo.Item == null)
+ {
+ return;
+ }
var newItemProgress = GetProgressInfo(streamInfo);
@@ -173,11 +178,14 @@ namespace Emby.Dlna.PlayTo
{
var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
- if (streamInfo.Item == null) return;
+ if (streamInfo.Item == null)
+ {
+ return;
+ }
var positionTicks = GetProgressPositionTicks(streamInfo);
- ReportPlaybackStopped(streamInfo, positionTicks);
+ await ReportPlaybackStopped(streamInfo, positionTicks).ConfigureAwait(false);
var mediaSource = await streamInfo.GetMediaSource(CancellationToken.None).ConfigureAwait(false);
@@ -185,7 +193,7 @@ namespace Emby.Dlna.PlayTo
(_device.Duration == null ? (long?)null : _device.Duration.Value.Ticks) :
mediaSource.RunTimeTicks;
- var playedToCompletion = (positionTicks.HasValue && positionTicks.Value == 0);
+ var playedToCompletion = positionTicks.HasValue && positionTicks.Value == 0;
if (!playedToCompletion && duration.HasValue && positionTicks.HasValue)
{
@@ -210,7 +218,7 @@ namespace Emby.Dlna.PlayTo
}
}
- private async void ReportPlaybackStopped(StreamParams streamInfo, long? positionTicks)
+ private async Task ReportPlaybackStopped(StreamParams streamInfo, long? positionTicks)
{
try
{
@@ -220,7 +228,6 @@ namespace Emby.Dlna.PlayTo
SessionId = _session.Id,
PositionTicks = positionTicks,
MediaSourceId = streamInfo.MediaSourceId
-
}).ConfigureAwait(false);
}
catch (Exception ex)
@@ -365,8 +372,13 @@ namespace Emby.Dlna.PlayTo
if (!command.ControllingUserId.Equals(Guid.Empty))
{
- _sessionManager.LogSessionActivity(_session.Client, _session.ApplicationVersion, _session.DeviceId,
- _session.DeviceName, _session.RemoteEndPoint, user);
+ _sessionManager.LogSessionActivity(
+ _session.Client,
+ _session.ApplicationVersion,
+ _session.DeviceId,
+ _session.DeviceName,
+ _session.RemoteEndPoint,
+ user);
}
return PlayItems(playlist, cancellationToken);
@@ -418,6 +430,7 @@ namespace Emby.Dlna.PlayTo
await _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl, CancellationToken.None).ConfigureAwait(false);
return;
}
+
await SeekAfterTransportChange(newPosition, CancellationToken.None).ConfigureAwait(false);
}
}
@@ -441,7 +454,13 @@ namespace Emby.Dlna.PlayTo
}
}
- private PlaylistItem CreatePlaylistItem(BaseItem item, User user, long startPostionTicks, string mediaSourceId, int? audioStreamIndex, int? subtitleStreamIndex)
+ private PlaylistItem CreatePlaylistItem(
+ BaseItem item,
+ User user,
+ long startPostionTicks,
+ string mediaSourceId,
+ int? audioStreamIndex,
+ int? subtitleStreamIndex)
{
var deviceInfo = _device.Properties;
@@ -484,42 +503,44 @@ namespace Emby.Dlna.PlayTo
if (streamInfo.MediaType == DlnaProfileType.Audio)
{
return new ContentFeatureBuilder(profile)
- .BuildAudioHeader(streamInfo.Container,
- streamInfo.TargetAudioCodec.FirstOrDefault(),
- streamInfo.TargetAudioBitrate,
- streamInfo.TargetAudioSampleRate,
- streamInfo.TargetAudioChannels,
- streamInfo.TargetAudioBitDepth,
- streamInfo.IsDirectStream,
- streamInfo.RunTimeTicks ?? 0,
- streamInfo.TranscodeSeekInfo);
+ .BuildAudioHeader(
+ streamInfo.Container,
+ streamInfo.TargetAudioCodec.FirstOrDefault(),
+ streamInfo.TargetAudioBitrate,
+ streamInfo.TargetAudioSampleRate,
+ streamInfo.TargetAudioChannels,
+ streamInfo.TargetAudioBitDepth,
+ streamInfo.IsDirectStream,
+ streamInfo.RunTimeTicks ?? 0,
+ streamInfo.TranscodeSeekInfo);
}
if (streamInfo.MediaType == DlnaProfileType.Video)
{
var list = new ContentFeatureBuilder(profile)
- .BuildVideoHeader(streamInfo.Container,
- streamInfo.TargetVideoCodec.FirstOrDefault(),
- streamInfo.TargetAudioCodec.FirstOrDefault(),
- streamInfo.TargetWidth,
- streamInfo.TargetHeight,
- streamInfo.TargetVideoBitDepth,
- streamInfo.TargetVideoBitrate,
- streamInfo.TargetTimestamp,
- streamInfo.IsDirectStream,
- streamInfo.RunTimeTicks ?? 0,
- streamInfo.TargetVideoProfile,
- streamInfo.TargetVideoLevel,
- streamInfo.TargetFramerate ?? 0,
- streamInfo.TargetPacketLength,
- streamInfo.TranscodeSeekInfo,
- streamInfo.IsTargetAnamorphic,
- streamInfo.IsTargetInterlaced,
- streamInfo.TargetRefFrames,
- streamInfo.TargetVideoStreamCount,
- streamInfo.TargetAudioStreamCount,
- streamInfo.TargetVideoCodecTag,
- streamInfo.IsTargetAVC);
+ .BuildVideoHeader(
+ streamInfo.Container,
+ streamInfo.TargetVideoCodec.FirstOrDefault(),
+ streamInfo.TargetAudioCodec.FirstOrDefault(),
+ streamInfo.TargetWidth,
+ streamInfo.TargetHeight,
+ streamInfo.TargetVideoBitDepth,
+ streamInfo.TargetVideoBitrate,
+ streamInfo.TargetTimestamp,
+ streamInfo.IsDirectStream,
+ streamInfo.RunTimeTicks ?? 0,
+ streamInfo.TargetVideoProfile,
+ streamInfo.TargetVideoLevel,
+ streamInfo.TargetFramerate ?? 0,
+ streamInfo.TargetPacketLength,
+ streamInfo.TranscodeSeekInfo,
+ streamInfo.IsTargetAnamorphic,
+ streamInfo.IsTargetInterlaced,
+ streamInfo.TargetRefFrames,
+ streamInfo.TargetVideoStreamCount,
+ streamInfo.TargetAudioStreamCount,
+ streamInfo.TargetVideoCodecTag,
+ streamInfo.IsTargetAVC);
return list.Count == 0 ? null : list[0];
}
@@ -619,6 +640,10 @@ namespace Emby.Dlna.PlayTo
GC.SuppressFinalize(this);
}
+ /// <summary>
+ /// Releases unmanaged and optionally managed resources.
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
@@ -644,68 +669,57 @@ namespace Emby.Dlna.PlayTo
private Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken)
{
- if (Enum.TryParse(command.Name, true, out GeneralCommandType commandType))
- {
- switch (commandType)
- {
- case GeneralCommandType.VolumeDown:
- return _device.VolumeDown(cancellationToken);
- case GeneralCommandType.VolumeUp:
- return _device.VolumeUp(cancellationToken);
- case GeneralCommandType.Mute:
- return _device.Mute(cancellationToken);
- case GeneralCommandType.Unmute:
- return _device.Unmute(cancellationToken);
- case GeneralCommandType.ToggleMute:
- return _device.ToggleMute(cancellationToken);
- case GeneralCommandType.SetAudioStreamIndex:
+ switch (command.Name)
+ {
+ case GeneralCommandType.VolumeDown:
+ return _device.VolumeDown(cancellationToken);
+ case GeneralCommandType.VolumeUp:
+ return _device.VolumeUp(cancellationToken);
+ case GeneralCommandType.Mute:
+ return _device.Mute(cancellationToken);
+ case GeneralCommandType.Unmute:
+ return _device.Unmute(cancellationToken);
+ case GeneralCommandType.ToggleMute:
+ return _device.ToggleMute(cancellationToken);
+ case GeneralCommandType.SetAudioStreamIndex:
+ if (command.Arguments.TryGetValue("Index", out string index))
+ {
+ if (int.TryParse(index, NumberStyles.Integer, _usCulture, out var val))
{
- if (command.Arguments.TryGetValue("Index", out string arg))
- {
- if (int.TryParse(arg, NumberStyles.Integer, _usCulture, out var val))
- {
- return SetAudioStreamIndex(val);
- }
+ return SetAudioStreamIndex(val);
+ }
- throw new ArgumentException("Unsupported SetAudioStreamIndex value supplied.");
- }
+ throw new ArgumentException("Unsupported SetAudioStreamIndex value supplied.");
+ }
- throw new ArgumentException("SetAudioStreamIndex argument cannot be null");
- }
- case GeneralCommandType.SetSubtitleStreamIndex:
+ throw new ArgumentException("SetAudioStreamIndex argument cannot be null");
+ case GeneralCommandType.SetSubtitleStreamIndex:
+ if (command.Arguments.TryGetValue("Index", out index))
+ {
+ if (int.TryParse(index, NumberStyles.Integer, _usCulture, out var val))
{
- if (command.Arguments.TryGetValue("Index", out string arg))
- {
- if (int.TryParse(arg, NumberStyles.Integer, _usCulture, out var val))
- {
- return SetSubtitleStreamIndex(val);
- }
+ return SetSubtitleStreamIndex(val);
+ }
- throw new ArgumentException("Unsupported SetSubtitleStreamIndex value supplied.");
- }
+ throw new ArgumentException("Unsupported SetSubtitleStreamIndex value supplied.");
+ }
- throw new ArgumentException("SetSubtitleStreamIndex argument cannot be null");
- }
- case GeneralCommandType.SetVolume:
+ throw new ArgumentException("SetSubtitleStreamIndex argument cannot be null");
+ case GeneralCommandType.SetVolume:
+ if (command.Arguments.TryGetValue("Volume", out string vol))
+ {
+ if (int.TryParse(vol, NumberStyles.Integer, _usCulture, out var volume))
{
- if (command.Arguments.TryGetValue("Volume", out string arg))
- {
- if (int.TryParse(arg, NumberStyles.Integer, _usCulture, out var volume))
- {
- return _device.SetVolume(volume, cancellationToken);
- }
+ return _device.SetVolume(volume, cancellationToken);
+ }
- throw new ArgumentException("Unsupported volume value supplied.");
- }
+ throw new ArgumentException("Unsupported volume value supplied.");
+ }
- throw new ArgumentException("Volume argument cannot be null");
- }
- default:
- return Task.CompletedTask;
- }
+ throw new ArgumentException("Volume argument cannot be null");
+ default:
+ return Task.CompletedTask;
}
-
- return Task.CompletedTask;
}
private async Task SetAudioStreamIndex(int? newIndex)
@@ -763,7 +777,7 @@ namespace Emby.Dlna.PlayTo
const int maxWait = 15000000;
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).ConfigureAwait(false);
currentWait += interval;
@@ -772,8 +786,67 @@ namespace Emby.Dlna.PlayTo
await _device.Seek(TimeSpan.FromTicks(positionTicks), cancellationToken).ConfigureAwait(false);
}
+ private static int? GetIntValue(IReadOnlyDictionary<string, string> values, string name)
+ {
+ var value = values.GetValueOrDefault(name);
+
+ if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
+ {
+ return result;
+ }
+
+ return null;
+ }
+
+ private static long GetLongValue(IReadOnlyDictionary<string, string> values, string name)
+ {
+ var value = values.GetValueOrDefault(name);
+
+ if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
+ {
+ return result;
+ }
+
+ return 0;
+ }
+
+ /// <inheritdoc />
+ public Task SendMessage<T>(SessionMessageType name, Guid messageId, T data, CancellationToken cancellationToken)
+ {
+ if (_disposed)
+ {
+ 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 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 MediaSourceInfo mediaSource;
+ private IMediaSourceManager _mediaSourceManager;
+
public Guid ItemId { get; set; }
public bool IsDirectStream { get; set; }
@@ -785,21 +858,20 @@ namespace Emby.Dlna.PlayTo
public int? SubtitleStreamIndex { get; set; }
public string DeviceProfileId { get; set; }
+
public string DeviceId { get; set; }
public string MediaSourceId { get; set; }
+
public string LiveStreamId { get; set; }
public BaseItem Item { get; set; }
- private MediaSourceInfo MediaSource;
-
- private IMediaSourceManager _mediaSourceManager;
public async Task<MediaSourceInfo> GetMediaSource(CancellationToken cancellationToken)
{
- if (MediaSource != null)
+ if (mediaSource != null)
{
- return MediaSource;
+ return mediaSource;
}
var hasMediaSources = Item as IHasMediaSources;
@@ -809,9 +881,12 @@ namespace Emby.Dlna.PlayTo
return null;
}
- MediaSource = await _mediaSourceManager.GetMediaSource(Item, MediaSourceId, LiveStreamId, false, cancellationToken).ConfigureAwait(false);
+ if (_mediaSourceManager != null)
+ {
+ mediaSource = await _mediaSourceManager.GetMediaSource(Item, MediaSourceId, LiveStreamId, false, cancellationToken).ConfigureAwait(false);
+ }
- return MediaSource;
+ return mediaSource;
}
private static Guid GetItemId(string url)
@@ -883,61 +958,5 @@ namespace Emby.Dlna.PlayTo
return request;
}
}
-
- private static int? GetIntValue(IReadOnlyDictionary<string, string> values, string name)
- {
- var value = values.GetValueOrDefault(name);
-
- if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
- {
- return result;
- }
-
- return null;
- }
-
- private static long GetLongValue(IReadOnlyDictionary<string, string> values, string name)
- {
- var value = values.GetValueOrDefault(name);
-
- if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
- {
- return result;
- }
-
- return 0;
- }
-
- /// <inheritdoc />
- public Task SendMessage<T>(string name, Guid messageId, T data, CancellationToken cancellationToken)
- {
- if (_disposed)
- {
- throw new ObjectDisposedException(GetType().Name);
- }
-
- if (_device == null)
- {
- return Task.CompletedTask;
- }
-
- if (string.Equals(name, "Play", StringComparison.OrdinalIgnoreCase))
- {
- return SendPlayCommand(data as PlayRequest, cancellationToken);
- }
-
- if (string.Equals(name, "PlayState", StringComparison.OrdinalIgnoreCase))
- {
- return SendPlaystateCommand(data as PlaystateRequest, cancellationToken);
- }
-
- if (string.Equals(name, "GeneralCommand", StringComparison.OrdinalIgnoreCase))
- {
- return SendGeneralCommand(data as GeneralCommand, cancellationToken);
- }
-
- // Not supported or needed right now
- return Task.CompletedTask;
- }
}
}