mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-03 06:18:28 +01:00
support more kinds of remote control besides web socket
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using MediaBrowser.Common.Events;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
@@ -6,6 +7,7 @@ using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Session;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@@ -75,6 +77,12 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||
_userRepository = userRepository;
|
||||
}
|
||||
|
||||
private List<ISessionRemoteController> _remoteControllers;
|
||||
public void AddParts(IEnumerable<ISessionRemoteController> remoteControllers)
|
||||
{
|
||||
_remoteControllers = remoteControllers.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all connections.
|
||||
/// </summary>
|
||||
@@ -122,7 +130,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||
var activityDate = DateTime.UtcNow;
|
||||
|
||||
var session = GetSessionInfo(clientType, appVersion, deviceId, deviceName, user);
|
||||
|
||||
|
||||
session.LastActivityDate = activityDate;
|
||||
|
||||
if (user == null)
|
||||
@@ -233,7 +241,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||
var key = item.GetUserDataKey();
|
||||
|
||||
var user = session.User;
|
||||
|
||||
|
||||
var data = _userDataRepository.GetUserData(user.Id, key);
|
||||
|
||||
data.PlayCount++;
|
||||
@@ -321,7 +329,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("positionTicks");
|
||||
}
|
||||
|
||||
|
||||
var session = Sessions.First(i => i.Id.Equals(sessionId));
|
||||
|
||||
RemoveNowPlayingItem(session, item);
|
||||
@@ -329,7 +337,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||
var key = item.GetUserDataKey();
|
||||
|
||||
var user = session.User;
|
||||
|
||||
|
||||
var data = _userDataRepository.GetUserData(user.Id, key);
|
||||
|
||||
if (positionTicks.HasValue)
|
||||
@@ -408,5 +416,54 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||
|
||||
data.PlaybackPositionTicks = positionTicks;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the session for remote control.
|
||||
/// </summary>
|
||||
/// <param name="sessionId">The session id.</param>
|
||||
/// <returns>SessionInfo.</returns>
|
||||
/// <exception cref="ResourceNotFoundException"></exception>
|
||||
private SessionInfo GetSessionForRemoteControl(Guid sessionId)
|
||||
{
|
||||
var session = Sessions.First(i => i.Id.Equals(sessionId));
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
throw new ResourceNotFoundException(string.Format("Session {0} not found.", sessionId));
|
||||
}
|
||||
|
||||
if (!session.SupportsRemoteControl)
|
||||
{
|
||||
throw new ArgumentException(string.Format("Session {0} does not support remote control.", session.Id));
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the controllers.
|
||||
/// </summary>
|
||||
/// <param name="session">The session.</param>
|
||||
/// <returns>IEnumerable{ISessionRemoteController}.</returns>
|
||||
private IEnumerable<ISessionRemoteController> GetControllers(SessionInfo session)
|
||||
{
|
||||
return _remoteControllers.Where(i => i.Supports(session));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the system command.
|
||||
/// </summary>
|
||||
/// <param name="sessionId">The session id.</param>
|
||||
/// <param name="command">The command.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public Task SendSystemCommand(Guid sessionId, SystemCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var session = GetSessionForRemoteControl(sessionId);
|
||||
|
||||
var tasks = GetControllers(session).Select(i => i.SendSystemCommand(session, command, cancellationToken));
|
||||
|
||||
return Task.WhenAll(tasks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Net;
|
||||
using MediaBrowser.Model.Session;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Session
|
||||
{
|
||||
public class WebSocketController : ISessionRemoteController
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public WebSocketController(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public bool Supports(SessionInfo session)
|
||||
{
|
||||
return session.WebSockets.Any(i => i.State == WebSocketState.Open);
|
||||
}
|
||||
|
||||
public async Task SendSystemCommand(SessionInfo session, SystemCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var socket = session.WebSockets.OrderByDescending(i => i.LastActivityDate).FirstOrDefault(i => i.State == WebSocketState.Open);
|
||||
|
||||
if (socket != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await socket.SendAsync(new WebSocketMessage<string>
|
||||
{
|
||||
MessageType = "SystemCommand",
|
||||
Data = command.ToString()
|
||||
|
||||
}, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error sending web socket message", ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("The requested session does not have an open web socket.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user