aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/Library/MediaSourceManager.cs98
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs2
-rw-r--r--Emby.Server.Implementations/Session/SessionManager.cs66
-rw-r--r--Emby.Server.Implementations/Session/SessionWebSocketListener.cs6
4 files changed, 31 insertions, 141 deletions
diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs
index ccd4c3631..4857008f3 100644
--- a/Emby.Server.Implementations/Library/MediaSourceManager.cs
+++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs
@@ -9,13 +9,10 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Serialization;
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Threading;
@@ -365,12 +362,10 @@ namespace Emby.Server.Implementations.Library
private readonly Dictionary<string, LiveStreamInfo> _openStreams = new Dictionary<string, LiveStreamInfo>(StringComparer.OrdinalIgnoreCase);
private readonly SemaphoreSlim _liveStreamSemaphore = new SemaphoreSlim(1, 1);
- public async Task<LiveStreamResponse> OpenLiveStream(LiveStreamRequest request, bool enableAutoClose, CancellationToken cancellationToken)
+ public async Task<LiveStreamResponse> OpenLiveStream(LiveStreamRequest request, CancellationToken cancellationToken)
{
await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
- enableAutoClose = false;
-
try
{
var tuple = GetProvider(request.OpenToken);
@@ -389,8 +384,6 @@ namespace Emby.Server.Implementations.Library
var info = new LiveStreamInfo
{
- Date = DateTime.UtcNow,
- EnableCloseTimer = enableAutoClose,
Id = mediaSource.LiveStreamId,
MediaSource = mediaSource,
DirectStreamProvider = mediaSourceTuple.Item2
@@ -398,11 +391,6 @@ namespace Emby.Server.Implementations.Library
_openStreams[mediaSource.LiveStreamId] = info;
- if (enableAutoClose)
- {
- StartCloseTimer();
- }
-
var json = _jsonSerializer.SerializeToString(mediaSource);
_logger.Debug("Live stream opened: " + json);
var clone = _jsonSerializer.DeserializeFromString<MediaSourceInfo>(json);
@@ -462,28 +450,6 @@ namespace Emby.Server.Implementations.Library
return result.Item1;
}
- public async Task PingLiveStream(string id, CancellationToken cancellationToken)
- {
- await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
-
- try
- {
- LiveStreamInfo info;
- if (_openStreams.TryGetValue(id, out info))
- {
- info.Date = DateTime.UtcNow;
- }
- else
- {
- _logger.Error("Failed to ping live stream {0}", id);
- }
- }
- finally
- {
- _liveStreamSemaphore.Release();
- }
- }
-
private async Task CloseLiveStreamWithProvider(IMediaSourceProvider provider, string streamId)
{
_logger.Info("Closing live stream {0} with provider {1}", streamId, provider.GetType().Name);
@@ -525,11 +491,6 @@ namespace Emby.Server.Implementations.Library
await CloseLiveStreamWithProvider(tuple.Item1, tuple.Item2).ConfigureAwait(false);
}
-
- if (_openStreams.Count == 0)
- {
- StopCloseTimer();
- }
}
}
finally
@@ -558,66 +519,11 @@ namespace Emby.Server.Implementations.Library
return new Tuple<IMediaSourceProvider, string>(provider, keyId);
}
- private ITimer _closeTimer;
- private readonly TimeSpan _openStreamMaxAge = TimeSpan.FromSeconds(180);
-
- private void StartCloseTimer()
- {
- StopCloseTimer();
-
- _closeTimer = _timerFactory.Create(CloseTimerCallback, null, _openStreamMaxAge, _openStreamMaxAge);
- }
-
- private void StopCloseTimer()
- {
- var timer = _closeTimer;
-
- if (timer != null)
- {
- _closeTimer = null;
- timer.Dispose();
- }
- }
-
- private async void CloseTimerCallback(object state)
- {
- List<LiveStreamInfo> infos;
- await _liveStreamSemaphore.WaitAsync().ConfigureAwait(false);
-
- try
- {
- infos = _openStreams
- .Values
- .Where(i => i.EnableCloseTimer && DateTime.UtcNow - i.Date > _openStreamMaxAge)
- .ToList();
- }
- finally
- {
- _liveStreamSemaphore.Release();
- }
-
- foreach (var info in infos)
- {
- if (!info.Closed)
- {
- try
- {
- await CloseLiveStream(info.Id).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error closing media source", ex);
- }
- }
- }
- }
-
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
- StopCloseTimer();
Dispose(true);
}
@@ -644,8 +550,6 @@ namespace Emby.Server.Implementations.Library
private class LiveStreamInfo
{
- public DateTime Date;
- public bool EnableCloseTimer;
public string Id;
public bool Closed;
public MediaSourceInfo MediaSource;
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
index 93996f5da..329f5b8a4 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
@@ -190,7 +190,7 @@ namespace Emby.Server.Implementations.LiveTv
else if (width >= 1260)
{
- videoStream.BitRate = 3000000;
+ videoStream.BitRate = 4000000;
}
else if (width >= 700)
diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs
index 05a240cea..0a2312735 100644
--- a/Emby.Server.Implementations/Session/SessionManager.cs
+++ b/Emby.Server.Implementations/Session/SessionManager.cs
@@ -197,6 +197,8 @@ namespace Emby.Server.Implementations.Session
_logger.ErrorException("Error disposing session controller", ex);
}
}
+
+ info.Dispose();
}
/// <summary>
@@ -308,10 +310,7 @@ namespace Emby.Server.Implementations.Session
/// <summary>
/// Updates the now playing item id.
/// </summary>
- /// <param name="session">The session.</param>
- /// <param name="info">The information.</param>
- /// <param name="libraryItem">The library item.</param>
- private async Task UpdateNowPlayingItem(SessionInfo session, PlaybackProgressInfo info, BaseItem libraryItem)
+ private async Task UpdateNowPlayingItem(SessionInfo session, PlaybackProgressInfo info, BaseItem libraryItem, bool updateLastCheckInTime)
{
if (string.IsNullOrWhiteSpace(info.MediaSourceId))
{
@@ -350,7 +349,11 @@ namespace Emby.Server.Implementations.Session
session.NowPlayingItem = info.Item;
session.LastActivityDate = DateTime.UtcNow;
- session.LastPlaybackCheckIn = DateTime.UtcNow;
+
+ if (updateLastCheckInTime)
+ {
+ session.LastPlaybackCheckIn = DateTime.UtcNow;
+ }
session.PlayState.IsPaused = info.IsPaused;
session.PlayState.PositionTicks = info.PositionTicks;
@@ -415,7 +418,7 @@ namespace Emby.Server.Implementations.Session
if (!_activeConnections.TryGetValue(key, out sessionInfo))
{
- sessionInfo = new SessionInfo
+ sessionInfo = new SessionInfo(this, _logger)
{
Client = appName,
DeviceId = deviceId,
@@ -602,14 +605,14 @@ namespace Emby.Server.Implementations.Session
? null
: GetNowPlayingItem(session, info.ItemId);
- await UpdateNowPlayingItem(session, info, libraryItem).ConfigureAwait(false);
+ await UpdateNowPlayingItem(session, info, libraryItem, true).ConfigureAwait(false);
if (!string.IsNullOrEmpty(session.DeviceId) && info.PlayMethod != PlayMethod.Transcode)
{
ClearTranscodingInfo(session.DeviceId);
}
- session.QueueableMediaTypes = info.QueueableMediaTypes;
+ session.StartAutomaticProgress(_timerFactory, info);
var users = GetUsers(session);
@@ -668,14 +671,15 @@ namespace Emby.Server.Implementations.Session
await _userDataManager.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false);
}
+ public Task OnPlaybackProgress(PlaybackProgressInfo info)
+ {
+ return OnPlaybackProgress(info, false);
+ }
+
/// <summary>
/// Used to report playback progress for an item
/// </summary>
- /// <param name="info">The info.</param>
- /// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
- public async Task OnPlaybackProgress(PlaybackProgressInfo info)
+ public async Task OnPlaybackProgress(PlaybackProgressInfo info, bool isAutomated)
{
if (info == null)
{
@@ -688,7 +692,7 @@ namespace Emby.Server.Implementations.Session
? null
: GetNowPlayingItem(session, info.ItemId);
- await UpdateNowPlayingItem(session, info, libraryItem).ConfigureAwait(false);
+ await UpdateNowPlayingItem(session, info, libraryItem, !isAutomated).ConfigureAwait(false);
var users = GetUsers(session);
@@ -700,18 +704,6 @@ namespace Emby.Server.Implementations.Session
}
}
- if (!string.IsNullOrWhiteSpace(info.LiveStreamId))
- {
- try
- {
- await _mediaSourceManager.PingLiveStream(info.LiveStreamId, CancellationToken.None).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error closing live stream", ex);
- }
- }
-
EventHelper.FireEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
{
Item = libraryItem,
@@ -727,6 +719,11 @@ namespace Emby.Server.Implementations.Session
}, _logger);
+ if (!isAutomated)
+ {
+ session.StartAutomaticProgress(_timerFactory, info);
+ }
+
StartIdleCheckTimer();
}
@@ -788,6 +785,8 @@ namespace Emby.Server.Implementations.Session
var session = GetSession(info.SessionId);
+ session.StopAutomaticProgress();
+
var libraryItem = string.IsNullOrWhiteSpace(info.ItemId)
? null
: GetNowPlayingItem(session, info.ItemId);
@@ -1009,19 +1008,9 @@ namespace Emby.Server.Implementations.Session
}
}
- if (command.PlayCommand != PlayCommand.PlayNow)
- {
- if (items.Any(i => !session.QueueableMediaTypes.Contains(i.MediaType, StringComparer.OrdinalIgnoreCase)))
- {
- throw new ArgumentException(string.Format("{0} is unable to queue the requested media type.", session.DeviceName ?? session.Id));
- }
- }
- else
+ if (items.Any(i => !session.PlayableMediaTypes.Contains(i.MediaType, StringComparer.OrdinalIgnoreCase)))
{
- if (items.Any(i => !session.PlayableMediaTypes.Contains(i.MediaType, StringComparer.OrdinalIgnoreCase)))
- {
- throw new ArgumentException(string.Format("{0} is unable to play the requested media type.", session.DeviceName ?? session.Id));
- }
+ throw new ArgumentException(string.Format("{0} is unable to play the requested media type.", session.DeviceName ?? session.Id));
}
if (user != null && command.ItemIds.Length == 1 && user.Configuration.EnableNextEpisodeAutoPlay)
@@ -1601,7 +1590,6 @@ namespace Emby.Server.Implementations.Session
LastActivityDate = session.LastActivityDate,
NowViewingItem = session.NowViewingItem,
ApplicationVersion = session.ApplicationVersion,
- QueueableMediaTypes = session.QueueableMediaTypes,
PlayableMediaTypes = session.PlayableMediaTypes,
AdditionalUsers = session.AdditionalUsers,
SupportedCommands = session.SupportedCommands,
diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
index 336c2caee..478f9da71 100644
--- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
+++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
@@ -289,7 +289,6 @@ namespace Emby.Server.Implementations.Session
var itemId = vals[0];
- var queueableMediaTypes = string.Empty;
var canSeek = true;
if (vals.Length > 1)
@@ -298,15 +297,14 @@ namespace Emby.Server.Implementations.Session
}
if (vals.Length > 2)
{
- queueableMediaTypes = vals[2];
+ // vals[2] used to be QueueableMediaTypes
}
var info = new PlaybackStartInfo
{
CanSeek = canSeek,
ItemId = itemId,
- SessionId = session.Id,
- QueueableMediaTypes = queueableMediaTypes.Split(',').ToList()
+ SessionId = session.Id
};
if (vals.Length > 3)