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

View File

@ -4,16 +4,23 @@ using System;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Threading;
namespace MediaBrowser.Controller.Session
{
/// <summary>
/// Class SessionInfo
/// </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>();
AdditionalUsers = new List<SessionUserInfo>();
@ -196,5 +203,85 @@ namespace MediaBrowser.Controller.Session
{
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;
}
}
}