aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-04-14 23:54:52 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-04-14 23:54:52 -0400
commite89d4e605bfa365958fb7c4968c5c01d6b172ee2 (patch)
tree34743acbf5ea96caad2cda511402ef21ffa3c5f6
parent2913638b671bfc344a08cacdf4a9dc921b426776 (diff)
support theme songs in the web client
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs12
-rw-r--r--MediaBrowser.Api/Playback/Hls/BaseHlsService.cs51
-rw-r--r--MediaBrowser.Dlna/PlayTo/Device.cs3
-rw-r--r--MediaBrowser.Dlna/PlayTo/DlnaController.cs26
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlayToManager.cs3
-rw-r--r--MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs17
-rw-r--r--MediaBrowser.Dlna/Server/SsdpHandler.cs12
-rw-r--r--MediaBrowser.Model/Dto/UserDto.cs6
-rw-r--r--MediaBrowser.Model/Session/SessionInfoDto.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs5
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/server.json67
-rw-r--r--MediaBrowser.Server.Implementations/Session/SessionManager.cs14
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs1
-rw-r--r--MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj9
14 files changed, 187 insertions, 45 deletions
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index b95062567..e588068d0 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -187,7 +187,7 @@ namespace MediaBrowser.Api.Playback
if (!state.HasMediaStreams)
{
- return state.IsInputVideo ? "-map -0:s" : string.Empty;
+ return state.IsInputVideo ? "-sn" : string.Empty;
}
if (state.VideoStream != null)
@@ -1493,7 +1493,7 @@ namespace MediaBrowser.Api.Playback
if (videoRequest != null)
{
- if (state.VideoStream != null && CanStreamCopyVideo(videoRequest, state.VideoStream, state.VideoType))
+ if (state.VideoStream != null && CanStreamCopyVideo(videoRequest, state.VideoStream))
{
videoRequest.VideoCodec = "copy";
}
@@ -1507,19 +1507,13 @@ namespace MediaBrowser.Api.Playback
return state;
}
- private bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream, VideoType videoType)
+ private bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream)
{
if (videoStream.IsInterlaced)
{
return false;
}
- // Not going to attempt this with folder rips
- if (videoType != VideoType.VideoFile)
- {
- return false;
- }
-
// Source and target codecs must match
if (!string.Equals(request.VideoCodec, videoStream.Codec, StringComparison.OrdinalIgnoreCase))
{
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index 6e71e503f..b5cd1bd40 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -24,7 +24,8 @@ namespace MediaBrowser.Api.Playback.Hls
/// </summary>
public abstract class BaseHlsService : BaseStreamingService
{
- protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, dlnaManager)
+ protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager)
+ : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, dlnaManager)
{
}
@@ -77,6 +78,7 @@ namespace MediaBrowser.Api.Playback.Hls
return ProcessRequestAsync(request).Result;
}
+ private static readonly SemaphoreSlim FfmpegStartLock = new SemaphoreSlim(1, 1);
/// <summary>
/// Processes the request async.
/// </summary>
@@ -103,32 +105,41 @@ namespace MediaBrowser.Api.Playback.Hls
}
var playlist = GetOutputFilePath(state);
- var isPlaylistNewlyCreated = false;
- // If the playlist doesn't already exist, startup ffmpeg
- if (!File.Exists(playlist))
+ if (File.Exists(playlist))
{
- isPlaylistNewlyCreated = true;
-
+ ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType.Hls);
+ }
+ else
+ {
+ await FfmpegStartLock.WaitAsync().ConfigureAwait(false);
try
{
- await StartFfMpeg(state, playlist).ConfigureAwait(false);
+ if (File.Exists(playlist))
+ {
+ ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType.Hls);
+ }
+ else
+ {
+ // If the playlist doesn't already exist, startup ffmpeg
+ try
+ {
+ await StartFfMpeg(state, playlist).ConfigureAwait(false);
+ }
+ catch
+ {
+ state.Dispose();
+ throw;
+ }
+ }
+
+ await WaitForMinimumSegmentCount(playlist, GetSegmentWait()).ConfigureAwait(false);
}
- catch
+ finally
{
- state.Dispose();
- throw;
+ FfmpegStartLock.Release();
}
}
- else
- {
- ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType.Hls);
- }
-
- if (isPlaylistNewlyCreated)
- {
- await WaitForMinimumSegmentCount(playlist, GetSegmentWait()).ConfigureAwait(false);
- }
int audioBitrate;
int videoBitrate;
@@ -295,7 +306,7 @@ namespace MediaBrowser.Api.Playback.Hls
// If performSubtitleConversions is true we're actually starting ffmpeg
var startNumberParam = performSubtitleConversions ? GetStartNumber(state).ToString(UsCulture) : "0";
-
+
var args = string.Format("{0} {1} -i {2}{3} -map_metadata -1 -threads {4} {5} {6} -sc_threshold 0 {7} -hls_time {8} -start_number {9} -hls_list_size {10} \"{11}\"",
itsOffset,
inputModifier,
diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs
index 2d0b3955b..fc62f9780 100644
--- a/MediaBrowser.Dlna/PlayTo/Device.cs
+++ b/MediaBrowser.Dlna/PlayTo/Device.cs
@@ -210,6 +210,9 @@ namespace MediaBrowser.Dlna.PlayTo
return SetVolume(tmp);
}
+ /// <summary>
+ /// Sets volume on a scale of 0-100
+ /// </summary>
public async Task<bool> SetVolume(int value)
{
var command = RendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetVolume");
diff --git a/MediaBrowser.Dlna/PlayTo/DlnaController.cs b/MediaBrowser.Dlna/PlayTo/DlnaController.cs
index 96c92b830..830d47829 100644
--- a/MediaBrowser.Dlna/PlayTo/DlnaController.cs
+++ b/MediaBrowser.Dlna/PlayTo/DlnaController.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Net;
+using System.Globalization;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Entities;
@@ -206,7 +207,8 @@ namespace MediaBrowser.Dlna.PlayTo
IsPaused = _device.IsPaused,
MediaSourceId = playlistItem.MediaSourceId,
AudioStreamIndex = playlistItem.AudioStreamIndex,
- SubtitleStreamIndex = playlistItem.SubtitleStreamIndex
+ SubtitleStreamIndex = playlistItem.SubtitleStreamIndex,
+ VolumeLevel = _device.Volume
}).ConfigureAwait(false);
}
@@ -614,6 +616,8 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
+ private readonly CultureInfo _usCulture = new CultureInfo("en-US");
+
public Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken)
{
GeneralCommandType commandType;
@@ -632,6 +636,24 @@ namespace MediaBrowser.Dlna.PlayTo
return _device.VolumeUp(true);
case GeneralCommandType.ToggleMute:
return _device.ToggleMute();
+ case GeneralCommandType.SetVolume:
+ {
+ string volumeArg;
+
+ if (command.Arguments.TryGetValue("Volume", out volumeArg))
+ {
+ int volume;
+
+ if (int.TryParse(volumeArg, NumberStyles.Any, _usCulture, out volume))
+ {
+ return _device.SetVolume(volume);
+ }
+
+ throw new ArgumentException("Unsupported volume value supplied.");
+ }
+
+ throw new ArgumentException("Volume argument cannot be null");
+ }
default:
return Task.FromResult(true);
}
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
index 1730245be..5cc3f13e5 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
@@ -265,7 +265,8 @@ namespace MediaBrowser.Dlna.PlayTo
GeneralCommandType.VolumeUp.ToString(),
GeneralCommandType.Mute.ToString(),
GeneralCommandType.Unmute.ToString(),
- GeneralCommandType.ToggleMute.ToString()
+ GeneralCommandType.ToggleMute.ToString(),
+ GeneralCommandType.SetVolume.ToString()
}
});
diff --git a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs
index 2e8d9044d..2c0b3a2c9 100644
--- a/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs
+++ b/MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs
@@ -57,8 +57,17 @@ namespace MediaBrowser.Dlna.Server
{
builder.Append("<UDN>" + SecurityElement.Escape(_serverUdn) + "</UDN>");
builder.Append("<dlna:X_DLNACAP>" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + "</dlna:X_DLNACAP>");
- builder.Append("<dlna:X_DLNADOC>M-DMS-1.50</dlna:X_DLNADOC>");
- builder.Append("<dlna:X_DLNADOC>" + SecurityElement.Escape(_profile.XDlnaDoc ?? string.Empty) + "</dlna:X_DLNADOC>");
+
+ if (!string.IsNullOrWhiteSpace(_profile.XDlnaDoc))
+ {
+ builder.Append("<dlna:X_DLNADOC xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\">" +
+ SecurityElement.Escape(_profile.XDlnaDoc) + "</dlna:X_DLNADOC>");
+ }
+ else
+ {
+ builder.Append("<dlna:X_DLNADOC xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\">DMS-1.50</dlna:X_DLNADOC>");
+ }
+
builder.Append("<friendlyName>" + SecurityElement.Escape(_profile.FriendlyName ?? string.Empty) + "</friendlyName>");
builder.Append("<deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType>");
builder.Append("<manufacturer>" + SecurityElement.Escape(_profile.Manufacturer ?? string.Empty) + "</manufacturer>");
@@ -99,7 +108,7 @@ namespace MediaBrowser.Dlna.Server
foreach (var service in GetServices())
{
- builder.Append("<icon>");
+ builder.Append("<service>");
builder.Append("<serviceType>" + SecurityElement.Escape(service.ServiceType ?? string.Empty) + "</serviceType>");
builder.Append("<serviceId>" + SecurityElement.Escape(service.ServiceId ?? string.Empty) + "</serviceId>");
@@ -107,7 +116,7 @@ namespace MediaBrowser.Dlna.Server
builder.Append("<controlURL>" + SecurityElement.Escape(service.ControlUrl ?? string.Empty) + "</controlURL>");
builder.Append("<eventSubURL>" + SecurityElement.Escape(service.EventSubUrl ?? string.Empty) + "</eventSubURL>");
- builder.Append("</icon>");
+ builder.Append("</service>");
}
builder.Append("</serviceList>");
diff --git a/MediaBrowser.Dlna/Server/SsdpHandler.cs b/MediaBrowser.Dlna/Server/SsdpHandler.cs
index 10f0101ef..c908eb4a8 100644
--- a/MediaBrowser.Dlna/Server/SsdpHandler.cs
+++ b/MediaBrowser.Dlna/Server/SsdpHandler.cs
@@ -147,7 +147,7 @@ namespace MediaBrowser.Dlna.Server
foreach (var d in Devices)
{
- if (!string.IsNullOrEmpty(req) && req != d.Type)
+ if (!string.IsNullOrEmpty(req) && !string.Equals(req, d.Type, StringComparison.OrdinalIgnoreCase))
{
continue;
}
@@ -263,13 +263,19 @@ namespace MediaBrowser.Dlna.Server
}
}
- foreach (var t in new[] { "upnp:rootdevice", "urn:schemas-upnp-org:device:MediaServer:1", "urn:schemas-upnp-org:service:ContentDirectory:1", "uuid:" + uuid })
+ foreach (var t in new[]
+ {
+ "upnp:rootdevice",
+ "urn:schemas-upnp-org:device:MediaServer:1",
+ "urn:schemas-upnp-org:service:ContentDirectory:1",
+ "uuid:" + uuid
+ })
{
list.Add(new UpnpDevice(uuid, t, descriptor, address));
}
NotifyAll();
- _logger.Debug("Registered mount {0}", uuid);
+ _logger.Debug("Registered mount {0} at {1}", uuid, descriptor);
}
private void UnregisterNotification(Guid uuid)
diff --git a/MediaBrowser.Model/Dto/UserDto.cs b/MediaBrowser.Model/Dto/UserDto.cs
index dcf0843fe..efbd64343 100644
--- a/MediaBrowser.Model/Dto/UserDto.cs
+++ b/MediaBrowser.Model/Dto/UserDto.cs
@@ -1,7 +1,7 @@
-using System.ComponentModel;
-using System.Diagnostics;
-using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Configuration;
using System;
+using System.ComponentModel;
+using System.Diagnostics;
using System.Runtime.Serialization;
namespace MediaBrowser.Model.Dto
diff --git a/MediaBrowser.Model/Session/SessionInfoDto.cs b/MediaBrowser.Model/Session/SessionInfoDto.cs
index f235cebb3..df7bdd7ec 100644
--- a/MediaBrowser.Model/Session/SessionInfoDto.cs
+++ b/MediaBrowser.Model/Session/SessionInfoDto.cs
@@ -52,6 +52,12 @@ namespace MediaBrowser.Model.Session
public string UserId { get; set; }
/// <summary>
+ /// Gets or sets the user primary image tag.
+ /// </summary>
+ /// <value>The user primary image tag.</value>
+ public Guid? UserPrimaryImageTag { get; set; }
+
+ /// <summary>
/// Gets or sets the name of the user.
/// </summary>
/// <value>The name of the user.</value>
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
index b92e82385..372e4addf 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
@@ -34,7 +34,10 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
{
var collectionType = args.GetCollectionType();
- if (string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase))
+ var isStandalone = args.Parent == null;
+
+ if (isStandalone ||
+ string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase))
{
return new Controller.Entities.Audio.Audio();
}
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index fe120737f..d16e0be99 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -450,5 +450,70 @@
"LabelMinResumeDuration": "Min resume duration (seconds):",
"LabelMinResumePercentageHelp": "Titles are assumed unplayed if stopped before this time",
"LabelMaxResumePercentageHelp": "Titles are assumed fully played if stopped after this time",
- "LabelMinResumeDurationHelp": "Titles shorter than this will not be resumable"
+ "LabelMinResumeDurationHelp": "Titles shorter than this will not be resumable",
+ "TitleAutoOrganize": "Auto-Organize",
+ "TabActivityLog": "Activity Log",
+ "HeaderName": "Name",
+ "HeaderDate": "Date",
+ "HeaderSource": "Source",
+ "HeaderStatus": "Status",
+ "HeaderDestination": "Destination",
+ "HeaderProgram": "Program",
+ "HeaderClients": "Clients",
+ "LabelCompleted": "Completed",
+ "LabelFailed": "Failed",
+ "LabelSkipped": "Skipped",
+ "HeaderEpisodeOrganization": "Episode Organization",
+ "LabelSeries": "Series:",
+ "LabelSeasonNumber": "Season number:",
+ "LabelEpisodeNumber": "Episode number:",
+ "LabelEndingEpisodeNumber": "Ending episode number:",
+ "LabelEndingEpisodeNumberHelp": "Only required for multi-episode files",
+ "HeaderSupportTheTeam": "Support the Media Browser Team",
+ "LabelSupportAmount": "Amount (USD)",
+ "HeaderSupportTheTeamHelp": "Help ensure the continued development of this project by donating. A portion of all donations will be contributed to other free tools we depend on.",
+ "ButtonEnterSupporterKey": "Enter supporter key",
+ "DonationNextStep": "Once complete, please return and enter your supporter key, which you will receive by email.",
+ "AutoOrganizeHelp": "Auto-organize monitors your download folders for new files and moves them to your media directories.",
+ "AutoOrganizeTvHelp": "TV file organizing will only add episodes to existing series. It will not create new series folders.",
+ "OptionEnableEpisodeOrganization": "Enable new episode organization",
+ "LabelWatchFolder": "Watch folder:",
+ "LabelWatchFolderHelp": "The server will poll this folder during the 'Organize new media files' scheduled task.",
+ "ButtonViewScheduledTasks": "View scheduled tasks",
+ "LabelMinFileSizeForOrganize": "Minimum file size (MB):",
+ "LabelMinFileSizeForOrganizeHelp": "Files under this size will be ignored.",
+ "LabelSeasonFolderPattern": "Season folder pattern:",
+ "LabelSeasonZeroFolderName": "Season zero folder name:",
+ "HeaderEpisodeFilePattern": "Episode file pattern",
+ "LabelEpisodePattern": "Episode pattern:",
+ "LabelMultiEpisodePattern": "Multi-Episode pattern:",
+ "HeaderSupportedPatterns": "Supported Patterns",
+ "HeaderTerm": "Term",
+ "HeaderPattern": "Pattern",
+ "HeaderResult": "Result",
+ "LabelDeleteEmptyFolders": "Delete empty folders after organizing",
+ "LabelDeleteEmptyFoldersHelp": "Enable this to keep the download directory clean.",
+ "LabelDeleteLeftOverFiles": "Delete left over files with the following extensions:",
+ "LabelDeleteLeftOverFilesHelp": "Separate with ;. For example: .nfo;.txt",
+ "OptionOverwriteExistingEpisodes": "Overwrite existing episodes",
+ "LabelTransferMethod": "Transfer method",
+ "OptionCopy": "Copy",
+ "OptionMove": "Move",
+ "LabelTransferMethodHelp": "Copy or move files from the watch folder",
+ "HeaderLatestNews": "Latest News",
+ "HeaderHelpImproveMediaBrowser": "Help Improve Media Browser",
+ "HeaderRunningTasks": "Running Tasks",
+ "HeaderActiveDevices": "Active Devices",
+ "HeaderPendingInstallations": "Pending Installations",
+ "HeaerServerInformation": "Server Information",
+ "ButtonRestartNow": "Restart Now",
+ "ButtonRestart": "Restart",
+ "ButtonShutdown": "Shutdown",
+ "ButtonUpdateNow": "Update Now",
+ "PleaseUpdateManually": "Please shutdown the server and update manually.",
+ "NewServerVersionAvailable": "A new version of Media Browser Server is available!",
+ "ServerUpToDate": "Media Browser Server is up to date",
+ "ErrorConnectingToMediaBrowserRepository": "There was an error connecting to the remote Media Browser repository.",
+ "LabelComponentsUpdated": "The following components have been installed or updated:",
+ "MessagePleaseRestartServerToFinishUpdating": "Please restart the server to finish applying updates."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index 3e741f41b..6f0a71c8c 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -1182,6 +1182,13 @@ namespace MediaBrowser.Server.Implementations.Session
if (session.UserId.HasValue)
{
dto.UserId = session.UserId.Value.ToString("N");
+
+ var user = _userManager.GetUserById(session.UserId.Value);
+
+ if (user != null)
+ {
+ dto.UserPrimaryImageTag = GetImageCacheTag(user, ImageType.Primary);
+ }
}
return dto;
@@ -1311,6 +1318,11 @@ namespace MediaBrowser.Server.Implementations.Session
}
}
+ if (backropItem == null)
+ {
+ backropItem = item.Parents.FirstOrDefault(i => i.HasImage(ImageType.Backdrop));
+ }
+
if (thumbItem == null)
{
thumbItem = item.Parents.FirstOrDefault(i => i.HasImage(ImageType.Thumb));
@@ -1322,7 +1334,7 @@ namespace MediaBrowser.Server.Implementations.Session
info.ThumbItemId = GetDtoId(thumbItem);
}
- if (thumbItem != null)
+ if (backropItem != null)
{
info.BackdropImageTag = GetImageCacheTag(backropItem, ImageType.Backdrop);
info.BackdropItemId = GetDtoId(backropItem);
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index 8df247ac0..931bb6a10 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -608,6 +608,7 @@ namespace MediaBrowser.WebDashboard.Api
"supporterkeypage.js",
"supporterpage.js",
"episodes.js",
+ "thememediaplayer.js",
"tvgenres.js",
"tvlatest.js",
"tvpeople.js",
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index 10ed2b7f4..b1cfab37a 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -220,6 +220,9 @@
<Content Include="dashboard-ui\css\images\media\tvflyout.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\css\images\nowplayingdefault.jpg">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\css\livetv.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -505,6 +508,9 @@
<Content Include="dashboard-ui\livetvrecordings.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\nowplaying.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\advancedpaths.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -637,6 +643,9 @@
<Content Include="dashboard-ui\scripts\livetvsuggested.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\scripts\thememediaplayer.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\tvupcoming.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>