using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Controller.SyncPlay;
using MediaBrowser.Model.SyncPlay;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Jellyfin.Api.Controllers
{
///
/// The sync play controller.
///
[Authorize(Policy = Policies.DefaultAuthorization)]
public class SyncPlayController : BaseJellyfinApiController
{
private readonly ISessionManager _sessionManager;
private readonly IAuthorizationContext _authorizationContext;
private readonly ISyncPlayManager _syncPlayManager;
///
/// Initializes a new instance of the class.
///
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
public SyncPlayController(
ISessionManager sessionManager,
IAuthorizationContext authorizationContext,
ISyncPlayManager syncPlayManager)
{
_sessionManager = sessionManager;
_authorizationContext = authorizationContext;
_syncPlayManager = syncPlayManager;
}
///
/// Create a new SyncPlay group.
///
/// New group created.
/// A indicating success.
[HttpPost("New")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SyncPlayCreateGroup()
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
_syncPlayManager.NewGroup(currentSession, CancellationToken.None);
return NoContent();
}
///
/// Join an existing SyncPlay group.
///
/// The sync play group id.
/// Group join successful.
/// A indicating success.
[HttpPost("Join")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SyncPlayJoinGroup([FromQuery, Required] Guid groupId)
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
var joinRequest = new JoinGroupRequest()
{
GroupId = groupId
};
_syncPlayManager.JoinGroup(currentSession, groupId, joinRequest, CancellationToken.None);
return NoContent();
}
///
/// Leave the joined SyncPlay group.
///
/// Group leave successful.
/// A indicating success.
[HttpPost("Leave")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SyncPlayLeaveGroup()
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
_syncPlayManager.LeaveGroup(currentSession, CancellationToken.None);
return NoContent();
}
///
/// Gets all SyncPlay groups.
///
/// Optional. Filter by item id.
/// Groups returned.
/// An containing the available SyncPlay groups.
[HttpGet("List")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult> SyncPlayGetGroups([FromQuery] Guid? filterItemId)
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
return Ok(_syncPlayManager.ListGroups(currentSession, filterItemId.HasValue ? filterItemId.Value : Guid.Empty));
}
///
/// Request play in SyncPlay group.
///
/// Play request sent to all group members.
/// A indicating success.
[HttpPost("Play")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SyncPlayPlay()
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
var syncPlayRequest = new PlaybackRequest()
{
Type = PlaybackRequestType.Play
};
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
}
///
/// Request pause in SyncPlay group.
///
/// Pause request sent to all group members.
/// A indicating success.
[HttpPost("Pause")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SyncPlayPause()
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
var syncPlayRequest = new PlaybackRequest()
{
Type = PlaybackRequestType.Pause
};
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
}
///
/// Request seek in SyncPlay group.
///
/// The playback position in ticks.
/// Seek request sent to all group members.
/// A indicating success.
[HttpPost("Seek")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SyncPlaySeek([FromQuery] long positionTicks)
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
var syncPlayRequest = new PlaybackRequest()
{
Type = PlaybackRequestType.Seek,
PositionTicks = positionTicks
};
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
}
///
/// Request group wait in SyncPlay group while buffering.
///
/// When the request has been made by the client.
/// The playback position in ticks.
/// Whether the buffering is done.
/// Buffering request sent to all group members.
/// A indicating success.
[HttpPost("Buffering")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SyncPlayBuffering([FromQuery] DateTime when, [FromQuery] long positionTicks, [FromQuery] bool bufferingDone)
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
var syncPlayRequest = new PlaybackRequest()
{
Type = bufferingDone ? PlaybackRequestType.Ready : PlaybackRequestType.Buffer,
When = when,
PositionTicks = positionTicks
};
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
}
///
/// Update session ping.
///
/// The ping.
/// Ping updated.
/// A indicating success.
[HttpPost("Ping")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SyncPlayPing([FromQuery] double ping)
{
var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
var syncPlayRequest = new PlaybackRequest()
{
Type = PlaybackRequestType.Ping,
Ping = Convert.ToInt64(ping)
};
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
}
}
}