diff --git a/MediaBrowser.Controller/Session/ISessionController.cs b/MediaBrowser.Controller/Session/ISessionController.cs
index 1d5fbf3590..170b50bf54 100644
--- a/MediaBrowser.Controller/Session/ISessionController.cs
+++ b/MediaBrowser.Controller/Session/ISessionController.cs
@@ -96,6 +96,22 @@ namespace MediaBrowser.Controller.Session
/// The cancellation token.
/// Task.
Task SendSessionEndedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken);
+
+ ///
+ /// Sends the playback start notification.
+ ///
+ /// The session information.
+ /// The cancellation token.
+ /// Task.
+ Task SendPlaybackStartNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken);
+
+ ///
+ /// Sends the playback start notification.
+ ///
+ /// The session information.
+ /// The cancellation token.
+ /// Task.
+ Task SendPlaybackStoppedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken);
///
/// Sends the server restart notification.
diff --git a/MediaBrowser.Dlna/PlayTo/DlnaController.cs b/MediaBrowser.Dlna/PlayTo/DlnaController.cs
index 6edb9d6f6e..596081a5e2 100644
--- a/MediaBrowser.Dlna/PlayTo/DlnaController.cs
+++ b/MediaBrowser.Dlna/PlayTo/DlnaController.cs
@@ -331,6 +331,16 @@ namespace MediaBrowser.Dlna.PlayTo
return Task.FromResult(true);
}
+ public Task SendPlaybackStartNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken)
+ {
+ return Task.FromResult(true);
+ }
+
+ public Task SendPlaybackStoppedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken)
+ {
+ return Task.FromResult(true);
+ }
+
public Task SendServerShutdownNotification(CancellationToken cancellationToken)
{
return Task.FromResult(true);
diff --git a/MediaBrowser.Model/Entities/BaseItemInfo.cs b/MediaBrowser.Model/Entities/BaseItemInfo.cs
index 16a08d6937..824f8dc038 100644
--- a/MediaBrowser.Model/Entities/BaseItemInfo.cs
+++ b/MediaBrowser.Model/Entities/BaseItemInfo.cs
@@ -46,6 +46,12 @@ namespace MediaBrowser.Model.Entities
/// The primary image tag.
public Guid? PrimaryImageTag { get; set; }
+ ///
+ /// Gets or sets the primary image item identifier.
+ ///
+ /// The primary image item identifier.
+ public string PrimaryImageItemId { get; set; }
+
///
/// Gets or sets the thumb image tag.
///
diff --git a/MediaBrowser.Model/Session/GeneralCommand.cs b/MediaBrowser.Model/Session/GeneralCommand.cs
index a50c3b5fee..4202ec456b 100644
--- a/MediaBrowser.Model/Session/GeneralCommand.cs
+++ b/MediaBrowser.Model/Session/GeneralCommand.cs
@@ -46,6 +46,7 @@ namespace MediaBrowser.Model.Session
ToggleMute = 21,
SetVolume = 22,
SetAudioStreamIndex = 23,
- SetSubtitleStreamIndex = 24
+ SetSubtitleStreamIndex = 24,
+ ToggleFullscreen = 25
}
}
diff --git a/MediaBrowser.Model/Session/PlaystateCommand.cs b/MediaBrowser.Model/Session/PlaystateCommand.cs
index 91572ba623..6466c64852 100644
--- a/MediaBrowser.Model/Session/PlaystateCommand.cs
+++ b/MediaBrowser.Model/Session/PlaystateCommand.cs
@@ -31,10 +31,6 @@ namespace MediaBrowser.Model.Session
///
Seek,
///
- /// The fullscreen
- ///
- Fullscreen,
- ///
/// The rewind
///
Rewind,
diff --git a/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs b/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs
index 5a4522bd30..307619cbe5 100644
--- a/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs
+++ b/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs
@@ -46,6 +46,16 @@ namespace MediaBrowser.Server.Implementations.Roku
return Task.FromResult(true);
}
+ public Task SendPlaybackStartNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken)
+ {
+ return Task.FromResult(true);
+ }
+
+ public Task SendPlaybackStoppedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken)
+ {
+ return Task.FromResult(true);
+ }
+
public Task SendMessageCommand(MessageCommand command, CancellationToken cancellationToken)
{
return SendCommand(new WebSocketMessage
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index 6452d5ac7e..53d1e64362 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -444,6 +444,8 @@ namespace MediaBrowser.Server.Implementations.Session
MediaSourceId = info.MediaSourceId
}, _logger);
+
+ await SendPlaybackStartNotification(session, CancellationToken.None).ConfigureAwait(false);
}
///
@@ -583,6 +585,8 @@ namespace MediaBrowser.Server.Implementations.Session
MediaSourceId = mediaSourceId
}, _logger);
+
+ await SendPlaybackStoppedNotification(session, CancellationToken.None).ConfigureAwait(false);
}
private string GetMediaSourceId(BaseItem item, string reportedMediaSourceId)
@@ -972,7 +976,6 @@ namespace MediaBrowser.Server.Implementations.Session
return Task.WhenAll(tasks);
}
-
public Task SendSessionEndedNotification(SessionInfo sessionInfo, CancellationToken cancellationToken)
{
var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList();
@@ -994,6 +997,48 @@ namespace MediaBrowser.Server.Implementations.Session
return Task.WhenAll(tasks);
}
+ public Task SendPlaybackStartNotification(SessionInfo sessionInfo, CancellationToken cancellationToken)
+ {
+ var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList();
+ var dto = GetSessionInfoDto(sessionInfo);
+
+ var tasks = sessions.Select(session => Task.Run(async () =>
+ {
+ try
+ {
+ await session.SessionController.SendPlaybackStartNotification(dto, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error in SendPlaybackStartNotification.", ex);
+ }
+
+ }, cancellationToken));
+
+ return Task.WhenAll(tasks);
+ }
+
+ public Task SendPlaybackStoppedNotification(SessionInfo sessionInfo, CancellationToken cancellationToken)
+ {
+ var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList();
+ var dto = GetSessionInfoDto(sessionInfo);
+
+ var tasks = sessions.Select(session => Task.Run(async () =>
+ {
+ try
+ {
+ await session.SessionController.SendPlaybackStoppedNotification(dto, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error in SendPlaybackStoppedNotification.", ex);
+ }
+
+ }, cancellationToken));
+
+ return Task.WhenAll(tasks);
+ }
+
///
/// Adds the additional user.
///
@@ -1163,6 +1208,11 @@ namespace MediaBrowser.Server.Implementations.Session
info.PrimaryImageTag = GetImageCacheTag(item, ImageType.Primary);
+ if (info.PrimaryImageTag.HasValue)
+ {
+ info.PrimaryImageItemId = GetDtoId(item);
+ }
+
var backropItem = item.HasImage(ImageType.Backdrop) ? item : null;
var thumbItem = item.HasImage(ImageType.Thumb) ? item : null;
diff --git a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs
index 17a3594d84..2f547340ee 100644
--- a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs
+++ b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs
@@ -210,5 +210,29 @@ namespace MediaBrowser.Server.Implementations.Session
}, cancellationToken);
}
+
+ public Task SendPlaybackStartNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken)
+ {
+ var socket = GetActiveSocket();
+
+ return socket.SendAsync(new WebSocketMessage
+ {
+ MessageType = "PlaybackStart",
+ Data = sessionInfo
+
+ }, cancellationToken);
+ }
+
+ public Task SendPlaybackStoppedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken)
+ {
+ var socket = GetActiveSocket();
+
+ return socket.SendAsync(new WebSocketMessage
+ {
+ MessageType = "PlaybackStopped",
+ Data = sessionInfo
+
+ }, cancellationToken);
+ }
}
}