support automatic progress reporting

This commit is contained in:
Luke Pulverenti 2017-04-17 14:40:42 -04:00
parent eddcc46602
commit 0b5019ed1b
2 changed files with 98 additions and 5 deletions

View file

@ -197,6 +197,8 @@ namespace Emby.Server.Implementations.Session
_logger.ErrorException("Error disposing session controller", ex); _logger.ErrorException("Error disposing session controller", ex);
} }
} }
info.Dispose();
} }
/// <summary> /// <summary>
@ -415,7 +417,7 @@ namespace Emby.Server.Implementations.Session
if (!_activeConnections.TryGetValue(key, out sessionInfo)) if (!_activeConnections.TryGetValue(key, out sessionInfo))
{ {
sessionInfo = new SessionInfo sessionInfo = new SessionInfo(this, _logger)
{ {
Client = appName, Client = appName,
DeviceId = deviceId, DeviceId = deviceId,
@ -609,6 +611,7 @@ namespace Emby.Server.Implementations.Session
ClearTranscodingInfo(session.DeviceId); ClearTranscodingInfo(session.DeviceId);
} }
session.StopAutomaticProgress();
session.QueueableMediaTypes = info.QueueableMediaTypes; session.QueueableMediaTypes = info.QueueableMediaTypes;
var users = GetUsers(session); var users = GetUsers(session);
@ -727,6 +730,7 @@ namespace Emby.Server.Implementations.Session
}, _logger); }, _logger);
session.StartAutomaticProgress(_timerFactory, info);
StartIdleCheckTimer(); StartIdleCheckTimer();
} }
@ -788,6 +792,8 @@ namespace Emby.Server.Implementations.Session
var session = GetSession(info.SessionId); var session = GetSession(info.SessionId);
session.StopAutomaticProgress();
var libraryItem = string.IsNullOrWhiteSpace(info.ItemId) var libraryItem = string.IsNullOrWhiteSpace(info.ItemId)
? null ? null
: GetNowPlayingItem(session, info.ItemId); : GetNowPlayingItem(session, info.ItemId);

View file

@ -4,16 +4,23 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Threading;
namespace MediaBrowser.Controller.Session namespace MediaBrowser.Controller.Session
{ {
/// <summary> /// <summary>
/// Class SessionInfo /// Class SessionInfo
/// </summary> /// </summary>
public class SessionInfo public class SessionInfo : IDisposable
{ {
public SessionInfo() private ISessionManager _sessionManager;
private readonly ILogger _logger;
public SessionInfo(ISessionManager sessionManager, ILogger logger)
{ {
_sessionManager = sessionManager;
_logger = logger;
QueueableMediaTypes = new List<string>(); QueueableMediaTypes = new List<string>();
AdditionalUsers = new List<SessionUserInfo>(); AdditionalUsers = new List<SessionUserInfo>();
@ -21,7 +28,7 @@ namespace MediaBrowser.Controller.Session
} }
public PlayerStateInfo PlayState { get; set; } public PlayerStateInfo PlayState { get; set; }
public List<SessionUserInfo> AdditionalUsers { get; set; } public List<SessionUserInfo> AdditionalUsers { get; set; }
public ClientCapabilities Capabilities { get; set; } public ClientCapabilities Capabilities { get; set; }
@ -133,7 +140,7 @@ namespace MediaBrowser.Controller.Session
/// </summary> /// </summary>
/// <value>The application icon URL.</value> /// <value>The application icon URL.</value>
public string AppIconUrl { get; set; } public string AppIconUrl { get; set; }
/// <summary> /// <summary>
/// Gets or sets the supported commands. /// Gets or sets the supported commands.
/// </summary> /// </summary>
@ -196,5 +203,85 @@ namespace MediaBrowser.Controller.Session
{ {
return (UserId ?? Guid.Empty) == userId || AdditionalUsers.Any(i => userId == new Guid(i.UserId)); return (UserId ?? Guid.Empty) == userId || AdditionalUsers.Any(i => userId == new Guid(i.UserId));
} }
private readonly object _progressLock = new object();
private ITimer _progressTimer;
private PlaybackProgressInfo _lastProgressInfo;
public void StartAutomaticProgress(ITimerFactory timerFactory, PlaybackProgressInfo progressInfo)
{
lock (_progressLock)
{
_lastProgressInfo = progressInfo;
if (_progressTimer != null)
{
return;
}
_progressTimer = timerFactory.Create(OnProgressTimerCallback, null, 1000, 1000);
}
}
// 1 second
private const long ProgressIncrement = 10000000;
private async void OnProgressTimerCallback(object state)
{
var progressInfo = _lastProgressInfo;
if (progressInfo == null)
{
return;
}
if (progressInfo.IsPaused)
{
return;
}
var positionTicks = progressInfo.PositionTicks ?? 0;
if (positionTicks <= 0)
{
return;
}
var newPositionTicks = positionTicks + ProgressIncrement;
var item = progressInfo.Item;
long? runtimeTicks = item == null ? null : item.RunTimeTicks;
// Don't report beyond the runtime
if (runtimeTicks.HasValue && newPositionTicks >= runtimeTicks.Value)
{
return;
}
progressInfo.PositionTicks = newPositionTicks;
try
{
await _sessionManager.OnPlaybackProgress(progressInfo).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.ErrorException("Error reporting playback progress", ex);
}
}
public void StopAutomaticProgress()
{
lock (_progressLock)
{
if (_progressTimer != null)
{
_progressTimer.Dispose();
_progressTimer = null;
}
_lastProgressInfo = null;
}
}
public void Dispose()
{
StopAutomaticProgress();
_sessionManager = null;
}
} }
} }