diff options
62 files changed, 490 insertions, 277 deletions
diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 471037801..3e5dca9b7 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -215,12 +215,12 @@ namespace Emby.Drawing { CheckDisposed(); - if (!_fileSystem.FileExists(cacheFilePath)) + if (!_fileSystem.FileExists(cacheFilePath)) { var newWidth = Convert.ToInt32(newSize.Width); var newHeight = Convert.ToInt32(newSize.Height); - _fileSystem.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); @@ -270,7 +270,7 @@ namespace Emby.Drawing await semaphore.WaitAsync().ConfigureAwait(false); // Check again in case of contention - if (_fileSystem.FileExists(croppedImagePath)) + if (_fileSystem.FileExists(croppedImagePath)) { semaphore.Release(); return GetResult(croppedImagePath); @@ -280,7 +280,7 @@ namespace Emby.Drawing try { - _fileSystem.CreateDirectory(Path.GetDirectoryName(croppedImagePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(croppedImagePath)); await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); imageProcessingLockTaken = true; @@ -400,7 +400,7 @@ namespace Emby.Drawing size = GetImageSizeInternal(path, allowSlowMethod); StartSaveImageSizeTimer(); - + _cachedImagedSizes.AddOrUpdate(cacheHash, size, (keyName, oldValue) => size); } @@ -452,7 +452,7 @@ namespace Emby.Drawing try { var path = ImageSizeFile; - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); _jsonSerializer.SerializeToFile(_cachedImagedSizes, path); } catch (Exception ex) @@ -624,7 +624,7 @@ namespace Emby.Drawing await semaphore.WaitAsync().ConfigureAwait(false); // Check again in case of contention - if (_fileSystem.FileExists(enhancedImagePath)) + if (_fileSystem.FileExists(enhancedImagePath)) { semaphore.Release(); return enhancedImagePath; @@ -634,7 +634,7 @@ namespace Emby.Drawing try { - _fileSystem.CreateDirectory(Path.GetDirectoryName(enhancedImagePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(enhancedImagePath)); await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); @@ -819,4 +819,4 @@ namespace Emby.Drawing } } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 86f06213c..5d88a41aa 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -839,7 +839,7 @@ namespace MediaBrowser.Api.Playback } // leave blank so ffmpeg will decide - return string.Empty; + return null; } /// <summary> @@ -849,7 +849,7 @@ namespace MediaBrowser.Api.Playback /// <returns>System.String.</returns> protected string GetInputArgument(StreamState state) { - var arg = string.Format("{1}-i {0}", GetInputPathArgument(state), GetVideoDecoder(state)); + var arg = string.Format("-i {0}", GetInputPathArgument(state)); if (state.SubtitleStream != null) { @@ -1060,6 +1060,7 @@ namespace MediaBrowser.Api.Playback var bytes = Encoding.UTF8.GetBytes(Environment.NewLine + line); await target.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false); + await target.FlushAsync().ConfigureAwait(false); } } } @@ -2191,6 +2192,12 @@ namespace MediaBrowser.Api.Playback inputModifier += " -re"; } + var videoDecoder = GetVideoDecoder(state); + if (!string.IsNullOrWhiteSpace(videoDecoder)) + { + inputModifier += " " + videoDecoder; + } + return inputModifier; } diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 036397b4f..a9a9610a9 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -23,7 +23,8 @@ namespace MediaBrowser.Api.Playback.Hls /// </summary> public abstract class BaseHlsService : BaseStreamingService { - protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer) + protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer) + : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer) { } @@ -90,12 +91,12 @@ namespace MediaBrowser.Api.Playback.Hls TranscodingJob job = null; var playlist = state.OutputFilePath; - if (!FileSystem.FileExists(playlist)) + if (!FileSystem.FileExists(playlist)) { await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false); try { - if (!FileSystem.FileExists(playlist)) + if (!FileSystem.FileExists(playlist)) { // If the playlist doesn't already exist, startup ffmpeg try @@ -150,7 +151,7 @@ namespace MediaBrowser.Api.Playback.Hls { ApiEntryPoint.Instance.OnTranscodeEndRequest(job); } - + return ResultFactory.GetResult(playlistText, MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>()); } @@ -317,4 +318,4 @@ namespace MediaBrowser.Api.Playback.Hls return false; } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 9359c65f2..cb49e65c7 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -165,7 +165,7 @@ namespace MediaBrowser.Api.Playback.Hls TranscodingJob job = null; - if (FileSystem.FileExists(segmentPath)) + if (FileSystem.FileExists(segmentPath)) { job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType); return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); @@ -174,7 +174,7 @@ namespace MediaBrowser.Api.Playback.Hls await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false); try { - if (FileSystem.FileExists(segmentPath)) + if (FileSystem.FileExists(segmentPath)) { job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType); return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); @@ -386,7 +386,7 @@ namespace MediaBrowser.Api.Playback.Hls try { - return fileSystem.GetFiles(folder) + return fileSystem.GetFiles(folder) .Where(i => string.Equals(i.Extension, segmentExtension, StringComparison.OrdinalIgnoreCase) && Path.GetFileNameWithoutExtension(i.Name).StartsWith(filePrefix, StringComparison.OrdinalIgnoreCase)) .OrderByDescending(fileSystem.GetLastWriteTimeUtc) .FirstOrDefault(); @@ -431,7 +431,7 @@ namespace MediaBrowser.Api.Playback.Hls CancellationToken cancellationToken) { // If all transcoding has completed, just return immediately - if (transcodingJob != null && transcodingJob.HasExited && FileSystem.FileExists(segmentPath)) + if (transcodingJob != null && transcodingJob.HasExited && FileSystem.FileExists(segmentPath)) { return GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob); } @@ -451,7 +451,7 @@ namespace MediaBrowser.Api.Playback.Hls // If it appears in the playlist, it's done if (text.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1) { - if (FileSystem.FileExists(segmentPath)) + if (FileSystem.FileExists(segmentPath)) { return GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob); } @@ -988,4 +988,4 @@ namespace MediaBrowser.Api.Playback.Hls return base.CanStreamCopyVideo(request, videoStream); } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index 39dd41356..ec3613298 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -158,9 +158,14 @@ namespace MediaBrowser.Common.Implementations.Security return new SupporterInfo(); } - var url = MbAdmin.HttpsUrl + "/service/supporter/retrieve?key=" + key; + var data = new Dictionary<string, string> + { + { "key", key }, + }; + + var url = MbAdmin.HttpsUrl + "/service/supporter/retrieve"; - using (var stream = await _httpClient.Get(url, CancellationToken.None).ConfigureAwait(false)) + using (var stream = await _httpClient.Post(url, data, CancellationToken.None).ConfigureAwait(false)) { var response = _jsonSerializer.DeserializeFromStream<SuppporterInfoResponse>(stream); diff --git a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs index 42871866d..8bcefed58 100644 --- a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs @@ -51,18 +51,18 @@ namespace MediaBrowser.Common.ScheduledTasks DisposeTimer(); var triggerDate = lastResult != null ? - lastResult.EndTimeUtc.Add(Interval) : - DateTime.UtcNow.Add(FirstRunDelay); + lastResult.EndTimeUtc.Add(Interval) : + DateTime.UtcNow.Add(FirstRunDelay); if (DateTime.UtcNow > triggerDate) { if (isApplicationStartup) { - triggerDate = DateTime.UtcNow.AddMinutes(2); + triggerDate = DateTime.UtcNow.AddMinutes(1); } else { - triggerDate = DateTime.UtcNow.Add(Interval); + triggerDate = DateTime.UtcNow.AddSeconds(10); } } diff --git a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs index ca5e343f8..3a9c1f9d0 100644 --- a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs @@ -115,7 +115,11 @@ namespace MediaBrowser.Controller.Channels var info = GetItemLookupInfo<ChannelItemLookupInfo>(); info.ContentType = ContentType; - info.ExtraType = ExtraType; + + if (ExtraType.HasValue) + { + info.ExtraType = ExtraType.Value; + } return info; } diff --git a/MediaBrowser.Controller/Channels/IChannelMediaItem.cs b/MediaBrowser.Controller/Channels/IChannelMediaItem.cs index 50df07e72..60a29da90 100644 --- a/MediaBrowser.Controller/Channels/IChannelMediaItem.cs +++ b/MediaBrowser.Controller/Channels/IChannelMediaItem.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Controller.Channels ChannelMediaContentType ContentType { get; set; } - ExtraType ExtraType { get; set; } + ExtraType? ExtraType { get; set; } List<ChannelMediaInfo> ChannelMediaSources { get; set; } } diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 623329ca6..43b980c20 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -24,14 +24,20 @@ namespace MediaBrowser.Controller.Entities.Audio IThemeMedia, IArchivable { - public string FormatName { get; set; } public long? Size { get; set; } public string Container { get; set; } public int? TotalBitrate { get; set; } public List<string> Tags { get; set; } - public ExtraType ExtraType { get; set; } + public ExtraType? ExtraType { get; set; } - public bool IsThemeMedia { get; set; } + [IgnoreDataMember] + public bool IsThemeMedia + { + get + { + return ExtraType.HasValue && ExtraType.Value == Model.Entities.ExtraType.ThemeSong; + } + } public Audio() { @@ -46,12 +52,6 @@ namespace MediaBrowser.Controller.Entities.Audio get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; } } - /// <summary> - /// Gets or sets a value indicating whether this instance has embedded image. - /// </summary> - /// <value><c>true</c> if this instance has embedded image; otherwise, <c>false</c>.</value> - public bool HasEmbeddedImage { get; set; } - [IgnoreDataMember] protected override bool SupportsOwnedItems { @@ -212,8 +212,7 @@ namespace MediaBrowser.Controller.Entities.Audio Path = enablePathSubstituion ? GetMappedPath(i.Path, locationType) : i.Path, RunTimeTicks = i.RunTimeTicks, Container = i.Container, - Size = i.Size, - Formats = (i.FormatName ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() + Size = i.Size }; if (string.IsNullOrEmpty(info.Container)) diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 807beee52..98d1eb4ce 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -66,6 +66,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// Gets the tracks. /// </summary> /// <value>The tracks.</value> + [IgnoreDataMember] public IEnumerable<Audio> Tracks { get diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index d413bda9b..75dd046a0 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -876,7 +876,7 @@ namespace MediaBrowser.Controller.Entities if (!i.IsThemeMedia) { - i.IsThemeMedia = true; + i.ExtraType = ExtraType.ThemeVideo; subOptions.ForceSave = true; } @@ -906,7 +906,7 @@ namespace MediaBrowser.Controller.Entities if (!i.IsThemeMedia) { - i.IsThemeMedia = true; + i.ExtraType = ExtraType.ThemeSong; subOptions.ForceSave = true; } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 4cdc4657e..04d42e16f 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -702,7 +702,7 @@ namespace MediaBrowser.Controller.Entities /// </summary> /// <param name="path">The path.</param> /// <returns><c>true</c> if the specified path is offline; otherwise, <c>false</c>.</returns> - private bool IsPathOffline(string path) + public static bool IsPathOffline(string path) { if (FileSystem.FileExists(path)) { @@ -736,12 +736,12 @@ namespace MediaBrowser.Controller.Entities /// <param name="folders">The folders.</param> /// <param name="path">The path.</param> /// <returns><c>true</c> if the specified folders contains path; otherwise, <c>false</c>.</returns> - private bool ContainsPath(IEnumerable<VirtualFolderInfo> folders, string path) + private static bool ContainsPath(IEnumerable<VirtualFolderInfo> folders, string path) { return folders.SelectMany(i => i.Locations).Any(i => ContainsPath(i, path)); } - private bool ContainsPath(string parent, string path) + private static bool ContainsPath(string parent, string path) { return string.Equals(parent, path, StringComparison.OrdinalIgnoreCase) || FileSystem.ContainsSubPath(parent, path); } diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index cfd6b46e0..21b89d7a9 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -62,17 +62,13 @@ namespace MediaBrowser.Controller.Entities.TV } /// <summary> - /// The _series - /// </summary> - private Series _series; - /// <summary> /// This Episode's Series Instance /// </summary> /// <value>The series.</value> [IgnoreDataMember] public Series Series { - get { return _series ?? (_series = FindParent<Series>()); } + get { return FindParent<Series>(); } } [IgnoreDataMember] diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 00dc5dc67..cc0c9ee46 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -33,14 +33,20 @@ namespace MediaBrowser.Controller.Entities public List<string> LocalAlternateVersions { get; set; } public List<LinkedChild> LinkedAlternateVersions { get; set; } - public bool IsThemeMedia { get; set; } + [IgnoreDataMember] + public bool IsThemeMedia + { + get + { + return ExtraType.HasValue && ExtraType.Value == Model.Entities.ExtraType.ThemeVideo; + } + } - public string FormatName { get; set; } public long? Size { get; set; } public string Container { get; set; } public int? TotalBitrate { get; set; } public string ShortOverview { get; set; } - public ExtraType ExtraType { get; set; } + public ExtraType? ExtraType { get; set; } /// <summary> /// Gets or sets the preferred metadata country code. @@ -498,7 +504,6 @@ namespace MediaBrowser.Controller.Entities VideoType = i.VideoType, Container = i.Container, Size = i.Size, - Formats = (i.FormatName ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(), Timestamp = i.Timestamp, Type = type, PlayableStreamFileNames = i.PlayableStreamFileNames.ToList(), diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 1be04bb7c..0a91a9143 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -18,6 +18,7 @@ namespace MediaBrowser.Controller.LiveTv public string ProviderImagePath { get; set; } public string ProviderImageUrl { get; set; } public string EpisodeTitle { get; set; } + [IgnoreDataMember] public bool IsSeries { get; set; } public string SeriesTimerId { get; set; } [IgnoreDataMember] @@ -25,6 +26,7 @@ namespace MediaBrowser.Controller.LiveTv public RecordingStatus Status { get; set; } [IgnoreDataMember] public bool IsSports { get; set; } + [IgnoreDataMember] public bool IsNews { get; set; } [IgnoreDataMember] public bool IsKids { get; set; } @@ -32,7 +34,9 @@ namespace MediaBrowser.Controller.LiveTv [IgnoreDataMember] public bool IsMovie { get; set; } public bool? IsHD { get; set; } + [IgnoreDataMember] public bool IsLive { get; set; } + [IgnoreDataMember] public bool IsPremiere { get; set; } public ChannelType ChannelType { get; set; } public string ProgramId { get; set; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 0f7d0a6ce..6d65672ec 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -125,18 +125,21 @@ namespace MediaBrowser.Controller.LiveTv /// Gets or sets a value indicating whether this instance is series. /// </summary> /// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value> + [IgnoreDataMember] public bool IsSeries { get; set; } /// <summary> /// Gets or sets a value indicating whether this instance is live. /// </summary> /// <value><c>true</c> if this instance is live; otherwise, <c>false</c>.</value> + [IgnoreDataMember] public bool IsLive { get; set; } /// <summary> /// Gets or sets a value indicating whether this instance is news. /// </summary> /// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value> + [IgnoreDataMember] public bool IsNews { get; set; } /// <summary> @@ -150,6 +153,7 @@ namespace MediaBrowser.Controller.LiveTv /// Gets or sets a value indicating whether this instance is premiere. /// </summary> /// <value><c>true</c> if this instance is premiere; otherwise, <c>false</c>.</value> + [IgnoreDataMember] public bool IsPremiere { get; set; } /// <summary> @@ -248,6 +252,7 @@ namespace MediaBrowser.Controller.LiveTv return info; } + [IgnoreDataMember] public override bool SupportsPeople { get diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index a26d8b402..b8318a01c 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -18,6 +18,7 @@ namespace MediaBrowser.Controller.LiveTv public string ProviderImagePath { get; set; } public string ProviderImageUrl { get; set; } public string EpisodeTitle { get; set; } + [IgnoreDataMember] public bool IsSeries { get; set; } public string SeriesTimerId { get; set; } [IgnoreDataMember] @@ -25,6 +26,7 @@ namespace MediaBrowser.Controller.LiveTv public RecordingStatus Status { get; set; } [IgnoreDataMember] public bool IsSports { get; set; } + [IgnoreDataMember] public bool IsNews { get; set; } [IgnoreDataMember] public bool IsKids { get; set; } @@ -32,7 +34,9 @@ namespace MediaBrowser.Controller.LiveTv [IgnoreDataMember] public bool IsMovie { get; set; } public bool? IsHD { get; set; } + [IgnoreDataMember] public bool IsLive { get; set; } + [IgnoreDataMember] public bool IsPremiere { get; set; } public ChannelType ChannelType { get; set; } public string ProgramId { get; set; } diff --git a/MediaBrowser.Dlna/Ssdp/Datagram.cs b/MediaBrowser.Dlna/Ssdp/Datagram.cs index 0a6d27303..791297b0c 100644 --- a/MediaBrowser.Dlna/Ssdp/Datagram.cs +++ b/MediaBrowser.Dlna/Ssdp/Datagram.cs @@ -30,7 +30,7 @@ namespace MediaBrowser.Dlna.Ssdp { var msg = Encoding.ASCII.GetBytes(Message); - var socket = CreateSocket(!IgnoreBindFailure); + var socket = CreateSocket(); if (socket == null) { @@ -69,7 +69,7 @@ namespace MediaBrowser.Dlna.Ssdp } catch (Exception ex) { - if (!IgnoreBindFailure || EnableDebugLogging) + if (EnableDebugLogging) { _logger.ErrorException("Error sending Datagram to {0} from {1}: " + Message, ex, ToEndPoint, FromEndPoint == null ? "" : FromEndPoint.ToString()); } @@ -102,7 +102,7 @@ namespace MediaBrowser.Dlna.Ssdp } } - private Socket CreateSocket(bool isBroadcast) + private Socket CreateSocket() { try { @@ -110,11 +110,8 @@ namespace MediaBrowser.Dlna.Ssdp socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - if (isBroadcast) - { - socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); - socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4); - } + socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); + socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4); return socket; } diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs index e6e9624d5..93d81427b 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -230,8 +230,8 @@ namespace MediaBrowser.Dlna.Ssdp values["ST"] = d.Type; values["USN"] = d.USN; - SendDatagram(header, values, endpoint, null, true, 1); - SendDatagram(header, values, endpoint, new IPEndPoint(d.Address, 0), true, 1); + SendDatagram(header, values, endpoint, null, false, 1); + SendDatagram(header, values, endpoint, new IPEndPoint(d.Address, 0), false, 1); //SendDatagram(header, values, endpoint, null, true); if (enableDebugLogging) diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 55a3983bb..e20d5d0a2 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -342,9 +342,55 @@ namespace MediaBrowser.MediaEncoding.Encoder inputModifier += " -re"; } + var videoDecoder = GetVideoDecoder(job); + if (!string.IsNullOrWhiteSpace(videoDecoder)) + { + inputModifier += " " + videoDecoder; + } + return inputModifier; } + /// <summary> + /// Gets the name of the output video codec + /// </summary> + /// <param name="state">The state.</param> + /// <returns>System.String.</returns> + protected string GetVideoDecoder(EncodingJob state) + { + if (string.Equals(GetEncodingOptions().HardwareVideoDecoder, "qsv", StringComparison.OrdinalIgnoreCase)) + { + if (state.VideoStream != null && !string.IsNullOrWhiteSpace(state.VideoStream.Codec)) + { + switch (state.MediaSource.VideoStream.Codec.ToLower()) + { + case "avc": + case "h264": + if (MediaEncoder.SupportsDecoder("h264_qsv")) + { + return "-c:v h264_qsv "; + } + break; + case "mpeg2video": + if (MediaEncoder.SupportsDecoder("mpeg2_qsv")) + { + return "-c:v mpeg2_qsv "; + } + break; + case "vc1": + if (MediaEncoder.SupportsDecoder("vc1_qsv")) + { + return "-c:v vc1_qsv "; + } + break; + } + } + } + + // leave blank so ffmpeg will decide + return null; + } + private string GetUserAgentParam(EncodingJob job) { string useragent = null; @@ -436,7 +482,7 @@ namespace MediaBrowser.MediaEncoding.Encoder state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationToken).ConfigureAwait(false); } - if (state.MediaSource.RequiresOpening) + if (state.MediaSource.RequiresOpening && string.IsNullOrWhiteSpace(state.LiveStreamId)) { var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest { diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs index 806910d89..47babfd13 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs @@ -56,7 +56,7 @@ namespace MediaBrowser.MediaEncoding.Encoder public bool EnableMpegtsM2TsMode { get; set; } public TranscodeSeekInfo TranscodeSeekInfo { get; set; } public long? EncodingDurationTicks { get; set; } - public string LiveTvStreamId { get; set; } + public string LiveStreamId { get; set; } public long? RunTimeTicks; public string ItemType { get; set; } diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index 476d9166b..03dbd07f0 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -326,26 +326,36 @@ namespace MediaBrowser.MediaEncoding.Encoder /// <returns>System.Nullable{System.Int32}.</returns> private int? GetNumAudioChannelsParam(EncodingJobOptions request, MediaStream audioStream, string outputAudioCodec) { - if (audioStream != null) + var inputChannels = audioStream == null + ? null + : audioStream.Channels; + + if (inputChannels <= 0) { - var codec = outputAudioCodec ?? string.Empty; + inputChannels = null; + } - if (audioStream.Channels > 2 && codec.IndexOf("wma", StringComparison.OrdinalIgnoreCase) != -1) - { - // wmav2 currently only supports two channel output - return 2; - } + var codec = outputAudioCodec ?? string.Empty; + + if (codec.IndexOf("wma", StringComparison.OrdinalIgnoreCase) != -1) + { + // wmav2 currently only supports two channel output + return Math.Min(2, inputChannels ?? 2); } if (request.MaxAudioChannels.HasValue) { - if (audioStream != null && audioStream.Channels.HasValue) + if (inputChannels.HasValue) { - return Math.Min(request.MaxAudioChannels.Value, audioStream.Channels.Value); + return Math.Min(request.MaxAudioChannels.Value, inputChannels.Value); } + var channelLimit = codec.IndexOf("mp3", StringComparison.OrdinalIgnoreCase) != -1 + ? 2 + : 6; + // If we don't have any media info then limit it to 5 to prevent encoding errors due to asking for too many channels - return Math.Min(request.MaxAudioChannels.Value, 5); + return Math.Min(request.MaxAudioChannels.Value, channelLimit); } return request.AudioChannels; @@ -519,6 +529,11 @@ namespace MediaBrowser.MediaEncoding.Encoder return false; } + if (videoStream.IsAnamorphic ?? false) + { + return false; + } + // Can't stream copy if we're burning in subtitles if (request.SubtitleStreamIndex.HasValue) { diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index fe300e2c4..6f25d4b6e 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -618,7 +618,7 @@ namespace MediaBrowser.MediaEncoding.Encoder vf += string.Format(",scale=min(iw\\,{0}):trunc(ow/dar/2)*2", maxWidthParam); } - FileSystem.CreateDirectory(targetDirectory); + FileSystem.CreateDirectory(targetDirectory); var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg"); var args = string.Format("-i {0} -threads 1 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf); @@ -892,4 +892,4 @@ namespace MediaBrowser.MediaEncoding.Encoder } } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index b137a8502..4ec688611 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -103,7 +103,7 @@ namespace MediaBrowser.Model.Configuration /// </summary> /// <value><c>true</c> if [enable user views]; otherwise, <c>false</c>.</value> public bool EnableUserViews { get; set; } - + /// <summary> /// Gets or sets a value indicating whether [enable library metadata sub folder]. /// </summary> @@ -223,7 +223,7 @@ namespace MediaBrowser.Model.Configuration public bool EnableWindowsShortcuts { get; set; } public bool EnableVideoFrameByFrameAnalysis { get; set; } - + /// <summary> /// Initializes a new instance of the <see cref="ServerConfiguration" /> class. /// </summary> @@ -272,8 +272,6 @@ namespace MediaBrowser.Model.Configuration PeopleMetadataOptions = new PeopleMetadataOptions(); - EnableVideoFrameByFrameAnalysis = false; - InsecureApps9 = new[] { "Unknown app", @@ -579,4 +577,4 @@ namespace MediaBrowser.Model.Configuration }; } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 43534efda..0335c43f0 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -157,7 +157,7 @@ namespace MediaBrowser.Model.Dlna if (all) { if (item.Protocol == MediaProtocol.File && - directPlayMethods.Contains(PlayMethod.DirectPlay) && + directPlayMethods.Contains(PlayMethod.DirectPlay) && _localPlayer.CanAccessFile(item.Path)) { playlistItem.PlayMethod = PlayMethod.DirectPlay; @@ -288,7 +288,7 @@ namespace MediaBrowser.Model.Dlna { _logger.Debug("Profile: {0}, No direct play profiles found for Path: {1}", options.Profile.Name ?? "Unknown Profile", - item.Path ?? "Unknown path"); + item.Path ?? "Unknown path"); } return playMethods; @@ -306,7 +306,7 @@ namespace MediaBrowser.Model.Dlna { highestScore = stream.Score.Value; } - } + } } List<MediaStream> topStreams = new List<MediaStream>(); @@ -540,8 +540,8 @@ namespace MediaBrowser.Model.Dlna { _logger.Debug("Profile: {0}, No direct play profiles found for Path: {1}", profile.Name ?? "Unknown Profile", - mediaSource.Path ?? "Unknown path"); - + mediaSource.Path ?? "Unknown path"); + return null; } @@ -658,7 +658,7 @@ namespace MediaBrowser.Model.Dlna if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioProfile, isSecondaryAudio)) { LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource); - + return null; } } @@ -725,7 +725,7 @@ namespace MediaBrowser.Model.Dlna public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, EncodingContext context, PlayMethod playMethod) { - if (playMethod != PlayMethod.Transcode && !subtitleStream.IsExternal) + if (playMethod != PlayMethod.Transcode && !subtitleStream.IsExternal) { // Look for supported embedded subs foreach (SubtitleProfile profile in subtitleProfiles) @@ -749,11 +749,11 @@ namespace MediaBrowser.Model.Dlna // Look for an external profile that matches the stream type (text/graphical) foreach (SubtitleProfile profile in subtitleProfiles) - { - if (profile.Method != SubtitleDeliveryMethod.External) - { - continue; - } + { + if (profile.Method != SubtitleDeliveryMethod.External) + { + continue; + } if (!profile.SupportsLanguage(subtitleStream.Language)) { @@ -762,9 +762,9 @@ namespace MediaBrowser.Model.Dlna if (subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format)) { - bool requiresConversion = !StringHelper.EqualsIgnoreCase(subtitleStream.Codec, profile.Format); + bool requiresConversion = !StringHelper.EqualsIgnoreCase(subtitleStream.Codec, profile.Format); - if (subtitleStream.IsTextSubtitleStream || !requiresConversion) + if (subtitleStream.IsTextSubtitleStream || !requiresConversion) { if (subtitleStream.SupportsExternalStream) { diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 16d5a8de4..596a76327 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -494,8 +494,6 @@ namespace MediaBrowser.Providers.Manager ParentId = Guid.NewGuid() }; - dummy.SetParent(new Folder()); - var options = GetMetadataOptions(dummy); var summary = new MetadataPluginSummary diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 43c5717e3..e1775d259 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -43,7 +43,7 @@ namespace MediaBrowser.Providers.MediaInfo var audio = (Audio)item; // Can't extract if we didn't find a video stream in the file - if (!audio.HasEmbeddedImage) + if (!audio.GetMediaSources(false).Take(1).SelectMany(i => i.MediaStreams).Any(i => i.Type == MediaStreamType.EmbeddedImage)) { return Task.FromResult(new DynamicImageResponse { HasImage = false }); } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs index 0d4fc6720..4cf507d15 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs @@ -103,9 +103,8 @@ namespace MediaBrowser.Providers.MediaInfo { var mediaStreams = mediaInfo.MediaStreams; - audio.FormatName = mediaInfo.Container; + //audio.FormatName = mediaInfo.Container; audio.TotalBitrate = mediaInfo.Bitrate; - audio.HasEmbeddedImage = mediaStreams.Any(i => i.Type == MediaStreamType.EmbeddedImage); audio.RunTimeTicks = mediaInfo.RunTimeTicks; audio.Size = mediaInfo.Size; diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 1f245541a..05756bba2 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -190,8 +190,8 @@ namespace MediaBrowser.Providers.MediaInfo var mediaStreams = mediaInfo.MediaStreams; video.TotalBitrate = mediaInfo.Bitrate; - video.FormatName = (mediaInfo.Container ?? string.Empty) - .Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase); + //video.FormatName = (mediaInfo.Container ?? string.Empty) + // .Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase); // For dvd's this may not always be accurate, so don't set the runtime if the item already has one var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0; @@ -488,7 +488,8 @@ namespace MediaBrowser.Providers.MediaInfo { var subtitleResolver = new SubtitleResolver(_localization, _fileSystem); - var externalSubtitleStreams = subtitleResolver.GetExternalSubtitleStreams(video, currentStreams.Count, options.DirectoryService, false).ToList(); + var startIndex = currentStreams.Count == 0 ? 0 : (currentStreams.Select(i => i.Index).Max() + 1); + var externalSubtitleStreams = subtitleResolver.GetExternalSubtitleStreams(video, startIndex, options.DirectoryService, false).ToList(); var enableSubtitleDownloading = options.MetadataRefreshMode == MetadataRefreshMode.Default || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh; @@ -512,7 +513,7 @@ namespace MediaBrowser.Providers.MediaInfo // Rescan if (downloadedLanguages.Count > 0) { - externalSubtitleStreams = subtitleResolver.GetExternalSubtitleStreams(video, currentStreams.Count, options.DirectoryService, true).ToList(); + externalSubtitleStreams = subtitleResolver.GetExternalSubtitleStreams(video, startIndex, options.DirectoryService, true).ToList(); } } diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index aab3a2121..f6e91528d 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -1079,20 +1079,25 @@ namespace MediaBrowser.Server.Implementations.Connect var url = GetConnectUrl("keyAssociation"); - url += "?serverId=" + ConnectServerId; - url += "&supporterKey=" + _securityManager.SupporterKey; - var options = new HttpRequestOptions { Url = url, CancellationToken = CancellationToken.None }; + var postData = new Dictionary<string, string> + { + {"serverId", ConnectServerId}, + {"supporterKey", _securityManager.SupporterKey} + }; + + options.SetPostData(postData); + SetServerAccessToken(options); SetApplicationHeader(options); // No need to examine the response - using (var stream = (await _httpClient.SendAsync(options, "GET").ConfigureAwait(false)).Content) + using (var stream = (await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)).Content) { return _json.DeserializeFromStream<ConnectSupporterSummary>(stream); } @@ -1107,16 +1112,21 @@ namespace MediaBrowser.Server.Implementations.Connect var url = GetConnectUrl("keyAssociation"); - url += "?serverId=" + ConnectServerId; - url += "&supporterKey=" + _securityManager.SupporterKey; - url += "&userId=" + id; - var options = new HttpRequestOptions { Url = url, CancellationToken = CancellationToken.None }; + var postData = new Dictionary<string, string> + { + {"serverId", ConnectServerId}, + {"supporterKey", _securityManager.SupporterKey}, + {"userId", id} + }; + + options.SetPostData(postData); + SetServerAccessToken(options); SetApplicationHeader(options); @@ -1135,16 +1145,21 @@ namespace MediaBrowser.Server.Implementations.Connect var url = GetConnectUrl("keyAssociation"); - url += "?serverId=" + ConnectServerId; - url += "&supporterKey=" + _securityManager.SupporterKey; - url += "&userId=" + id; - var options = new HttpRequestOptions { Url = url, CancellationToken = CancellationToken.None }; + var postData = new Dictionary<string, string> + { + {"serverId", ConnectServerId}, + {"supporterKey", _securityManager.SupporterKey}, + {"userId", id} + }; + + options.SetPostData(postData); + SetServerAccessToken(options); SetApplicationHeader(options); diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs index a6a8b3a7a..548a2222a 100644 --- a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs +++ b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs @@ -157,7 +157,7 @@ namespace MediaBrowser.Server.Implementations.Devices _libraryMonitor.ReportFileSystemChangeBeginning(path); - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); try { @@ -290,4 +290,4 @@ namespace MediaBrowser.Server.Implementations.Devices return config.GetConfiguration<DevicesOptions>("devices"); } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index fa5841bb8..a2ffa9aff 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -147,7 +147,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints // It also can fail with others like 727-ExternalPortOnlySupportsWildcard, 728-NoPortMapsAvailable // and those errors (upnp errors) could be useful for diagnosting. - _logger.ErrorException("Error creating port forwarding rules", ex); + // Commenting out because users are reporting problems out of our control + //_logger.ErrorException("Error creating port forwarding rules", ex); } } diff --git a/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs index 2867cbecb..54f2539ff 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs @@ -112,7 +112,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization try { return _fileSystem - .GetFileSystemEntryPaths(path) + .GetDirectoryPaths(path) .ToList(); } catch (IOException ex) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 26961c490..966c1e037 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1165,7 +1165,7 @@ namespace MediaBrowser.Server.Implementations.Library /// <returns>IEnumerable{VirtualFolderInfo}.</returns> private IEnumerable<VirtualFolderInfo> GetView(string path) { - return _fileSystem.GetFileSystemEntryPaths(path) + return _fileSystem.GetDirectoryPaths(path) .Select(dir => new VirtualFolderInfo { Name = Path.GetFileName(dir), diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index a348c728e..8ef7e94c2 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -173,7 +173,7 @@ namespace MediaBrowser.Server.Implementations.Library if (source.Protocol == MediaProtocol.File) { // TODO: Path substitution - if (!_fileSystem.FileExists(source.Path)) + if (!_fileSystem.FileExists(source.Path)) { source.SupportsDirectStream = false; } @@ -585,4 +585,4 @@ namespace MediaBrowser.Server.Implementations.Library public MediaSourceInfo MediaSource; } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index d9f23977c..ff38e057b 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -125,7 +125,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies } else if (IsIgnored(child.Name)) { - + } else { diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 38b83eb02..2b55945e6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -135,7 +135,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var timers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false); List<ChannelInfo> channels = null; - + foreach (var timer in timers) { List<ProgramInfo> epgData; @@ -608,7 +608,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var timer = e.Argument; _logger.Info("Recording timer fired."); - + try { var cancellationTokenSource = new CancellationTokenSource(); @@ -670,7 +670,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)) + ".ts"; recordPath = Path.Combine(recordPath, recordingFileName); - _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath)); var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.ProgramId, info.Id, StringComparison.OrdinalIgnoreCase)); @@ -724,7 +724,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _logger.Info("Writing file to path: " + recordPath); using (var response = await _httpClient.SendAsync(httpRequestOptions, "GET")) { - using (var output = _fileSystem.GetFileStream(recordPath, FileMode.Create, FileAccess.Write, FileShare.Read)) + using (var output = _fileSystem.GetFileStream(recordPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, linkedToken); } @@ -885,7 +885,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private void SaveEpgDataForChannel(string channelId, List<ProgramInfo> epgData) { var path = GetChannelEpgCachePath(channelId); - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); lock (_epgLock) { _jsonSerializer.SerializeToFile(epgData, path); @@ -932,4 +932,4 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV }); } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 5b83d63b1..3ee808bb5 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -67,10 +67,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } - else if (info.ProductionYear != null) + else if (info.IsMovie && info.ProductionYear != null) { name += " (" + info.ProductionYear + ")"; } + else + { + name += " " + info.StartDate.ToString("yyyy-MM-dd"); + } return name; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 868889ba7..161bcbf48 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -980,4 +980,4 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 0a33d7383..fbafe7151 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -650,11 +650,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv { await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); } + else if (string.IsNullOrWhiteSpace(info.Etag)) + { + await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); + } else { - if (string.IsNullOrWhiteSpace(info.Etag) || !string.Equals(info.Etag, item.Etag, StringComparison.OrdinalIgnoreCase)) + // Increment this whenver some internal change deems it necessary + var etag = info.Etag + "1"; + + if (!string.Equals(etag, item.Etag, StringComparison.OrdinalIgnoreCase)) { - item.Etag = info.Etag; + item.Etag = etag; await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); } } @@ -1162,15 +1169,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv foreach (var program in channelPrograms) { - if (program.StartDate.Kind != DateTimeKind.Utc) - { - _logger.Error("{0} returned StartDate.DateTimeKind.{1} instead of UTC for program {2}", service.Name, program.StartDate.Kind.ToString(), program.Name); - } - else if (program.EndDate.Kind != DateTimeKind.Utc) - { - _logger.Error("{0} returned EndDate.DateTimeKind.{1} instead of UTC for program {2}", service.Name, program.EndDate.Kind.ToString(), program.Name); - } - var programItem = await GetProgram(program, channelId, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false); programs.Add(programItem.Id); @@ -2362,4 +2360,4 @@ namespace MediaBrowser.Server.Implementations.LiveTv }); } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index e5222e55d..5afe8f54a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts { @@ -16,14 +17,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts { protected readonly IConfigurationManager Config; protected readonly ILogger Logger; + protected IJsonSerializer JsonSerializer; private readonly ConcurrentDictionary<string, ChannelCache> _channelCache = new ConcurrentDictionary<string, ChannelCache>(StringComparer.OrdinalIgnoreCase); - public BaseTunerHost(IConfigurationManager config, ILogger logger) + public BaseTunerHost(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer) { Config = config; Logger = logger; + JsonSerializer = jsonSerializer; } protected abstract Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken); @@ -44,6 +47,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts var result = await GetChannelsInternal(tuner, cancellationToken).ConfigureAwait(false); var list = result.ToList(); + Logger.Debug("Channels from {0}: {1}", tuner.Url, JsonSerializer.SerializeToString(list)); if (!string.IsNullOrWhiteSpace(key)) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 571b00257..9cd706b53 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -20,13 +20,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun public class HdHomerunHost : BaseTunerHost, ITunerHost { private readonly IHttpClient _httpClient; - private readonly IJsonSerializer _jsonSerializer; public HdHomerunHost(IConfigurationManager config, ILogger logger, IHttpClient httpClient, IJsonSerializer jsonSerializer) - : base(config, logger) + : base(config, logger, jsonSerializer) { _httpClient = httpClient; - _jsonSerializer = jsonSerializer; } public string Name @@ -55,7 +53,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun }; using (var stream = await _httpClient.Get(options)) { - var root = _jsonSerializer.DeserializeFromStream<List<Channels>>(stream); + var root = JsonSerializer.DeserializeFromStream<List<Channels>>(stream); if (root != null) { @@ -380,7 +378,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun protected override async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) { - Logger.Debug("GetChannelStream: channel id: {0}. stream id: {1}", channelId, streamId ?? string.Empty); + Logger.Info("GetChannelStream: channel id: {0}. stream id: {1}", channelId, streamId ?? string.Empty); if (!channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase)) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 31139b15d..a26ed7a2a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -13,17 +13,21 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.IO; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts { public class M3UTunerHost : BaseTunerHost, ITunerHost { private readonly IFileSystem _fileSystem; - - public M3UTunerHost(IConfigurationManager config, ILogger logger, IFileSystem fileSystem) - : base(config, logger) + private IHttpClient _httpClient; + + public M3UTunerHost(IConfigurationManager config, ILogger logger, IFileSystem fileSystem, IHttpClient httpClient, IJsonSerializer jsonSerializer) + : base(config, logger, jsonSerializer) { _fileSystem = fileSystem; + _httpClient = httpClient; } public override string Type @@ -45,47 +49,48 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts string line; // Read the file and display it line by line. - var file = new StreamReader(url); - var channels = new List<M3UChannel>(); + using (var file = new StreamReader(await GetListingsStream(info, cancellationToken).ConfigureAwait(false))) + { + var channels = new List<M3UChannel>(); - string channnelName = null; - string channelNumber = null; + string channnelName = null; + string channelNumber = null; - while ((line = file.ReadLine()) != null) - { - line = line.Trim(); - if (string.IsNullOrWhiteSpace(line)) + while ((line = file.ReadLine()) != null) { - continue; - } + line = line.Trim(); + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } - if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase)) - { - continue; - } + if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase)) + { + continue; + } - if (line.StartsWith("#EXTINF:", StringComparison.OrdinalIgnoreCase)) - { - var parts = line.Split(new[] { ':' }, 2).Last().Split(new[] { ',' }, 2); - channelNumber = parts[0]; - channnelName = parts[1]; - } - else if (!string.IsNullOrWhiteSpace(channelNumber)) - { - channels.Add(new M3UChannel + if (line.StartsWith("#EXTINF:", StringComparison.OrdinalIgnoreCase)) + { + var parts = line.Split(new[] { ':' }, 2).Last().Split(new[] { ',' }, 2); + channelNumber = parts[0]; + channnelName = parts[1]; + } + else if (!string.IsNullOrWhiteSpace(channelNumber)) { - Name = channnelName, - Number = channelNumber, - Id = ChannelIdPrefix + urlHash + channelNumber, - Path = line - }); - - channelNumber = null; - channnelName = null; + channels.Add(new M3UChannel + { + Name = channnelName, + Number = channelNumber, + Id = ChannelIdPrefix + urlHash + channelNumber, + Path = line + }); + + channelNumber = null; + channnelName = null; + } } + return channels; } - file.Close(); - return channels; } public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken) @@ -123,9 +128,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts public async Task Validate(TunerHostInfo info) { - if (!_fileSystem.FileExists(info.Url)) + using (var stream = await GetListingsStream(info, CancellationToken.None).ConfigureAwait(false)) { - throw new FileNotFoundException(); + } } @@ -134,6 +139,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase); } + private Task<Stream> GetListingsStream(TunerHostInfo info, CancellationToken cancellationToken) + { + if (info.Url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) + { + return _httpClient.Get(info.Url, cancellationToken); + } + return Task.FromResult(_fileSystem.OpenRead(info.Url)); + } + protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) { var urlHash = info.Url.GetMD5().ToString("N"); diff --git a/MediaBrowser.Server.Implementations/Localization/Core/bg-BG.json b/MediaBrowser.Server.Implementations/Localization/Core/bg-BG.json index d719ae08e..aeebd2038 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/bg-BG.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/bg-BG.json @@ -17,7 +17,7 @@ "ValueSpecialEpisodeName": "Special - {0}", "LabelChapterName": "Chapter {0}", "NameSeasonNumber": "Season {0}", - "LabelExit": "\u0418\u0437\u043b\u0435\u0437", + "LabelExit": "\u0418\u0437\u0445\u043e\u0434", "LabelVisitCommunity": "\u041f\u043e\u0441\u0435\u0442\u0438 \u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u0442\u043e", "LabelGithub": "Github", "LabelApiDocumentation": "API \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f", @@ -25,7 +25,7 @@ "LabelBrowseLibrary": "\u0420\u0430\u0437\u0433\u043b\u0435\u0434\u0430\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0442\u0430", "LabelConfigureServer": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u0439 Emby", "LabelRestartServer": "\u0420\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0439 \u0441\u044a\u0440\u0432\u044a\u0440\u0430", - "CategorySync": "Sync", + "CategorySync": "\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437.", "CategoryUser": "User", "CategorySystem": "System", "CategoryApplication": "Application", diff --git a/MediaBrowser.Server.Implementations/Localization/Core/fr.json b/MediaBrowser.Server.Implementations/Localization/Core/fr.json index d8bffe699..b32d4cb0a 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/fr.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/fr.json @@ -173,5 +173,5 @@ "HeaderWriter": "Auteur(e)s", "HeaderParentalRatings": "Note parentale", "HeaderCommunityRatings": "Classification de la communaut\u00e9", - "StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly." + "StartupEmbyServerIsLoading": "Le serveur Emby est en cours de chargement. Veuillez r\u00e9essayer dans quelques instant." }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ru.json b/MediaBrowser.Server.Implementations/Localization/Core/ru.json index f36db9e25..fa1cbfc16 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ru.json @@ -49,7 +49,7 @@ "NotificationOptionCameraImageUploaded": "\u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0430 \u0432\u044b\u043a\u043b\u0430\u0434\u043a\u0430 \u043e\u0442\u0441\u043d\u044f\u0442\u043e\u0433\u043e \u0441 \u043a\u0430\u043c\u0435\u0440\u044b", "NotificationOptionUserLockedOut": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d", "NotificationOptionServerRestartRequired": "\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430", - "ViewTypePlaylists": "\u0421\u043f\u0438\u0441\u043a\u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f", + "ViewTypePlaylists": "\u041f\u043b\u0435\u0439-\u043b\u0438\u0441\u0442\u044b", "ViewTypeMovies": "\u041a\u0438\u043d\u043e", "ViewTypeTvShows": "\u0422\u0412", "ViewTypeGames": "\u0418\u0433\u0440\u044b", @@ -79,7 +79,7 @@ "ViewTypeMovieFavorites": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435", "ViewTypeMovieGenres": "\u0416\u0430\u043d\u0440\u044b", "ViewTypeMusicLatest": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435", - "ViewTypeMusicPlaylists": "\u0421\u043f\u0438\u0441\u043a\u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f", + "ViewTypeMusicPlaylists": "\u041f\u043b\u0435\u0439-\u043b\u0438\u0441\u0442\u044b", "ViewTypeMusicAlbums": "\u0410\u043b\u044c\u0431\u043e\u043c\u044b", "ViewTypeMusicAlbumArtists": "\u0418\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0438 \u0430\u043b\u044c\u0431\u043e\u043c\u0430", "HeaderOtherDisplaySettings": "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f", @@ -101,8 +101,8 @@ "ItemAddedWithName": "{0} (\u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0443)", "ItemRemovedWithName": "{0} (\u0438\u0437\u044a\u044f\u0442\u043e \u0438\u0437 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438)", "LabelIpAddressValue": "IP-\u0430\u0434\u0440\u0435\u0441: {0}", - "DeviceOnlineWithName": "{0} - \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e", - "UserOnlineFromDevice": "{0} - \u043f\u043e\u0434\u043a\u043b. \u0441 {1} \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e", + "DeviceOnlineWithName": "{0} - \u043f\u043e\u0434\u043a\u043b. \u0443\u0441\u0442-\u043d\u043e", + "UserOnlineFromDevice": "{0} - \u043f\u043e\u0434\u043a\u043b. \u0441 {1} \u0443\u0441\u0442-\u043d\u043e", "ProviderValue": "\u041f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a: {0}", "SubtitlesDownloadedForItem": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044b \u0434\u043b\u044f {0} \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u0438\u0441\u044c", "UserConfigurationUpdatedWithName": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437-\u043b\u044f {0} \u0431\u044b\u043b\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430", diff --git a/MediaBrowser.Server.Implementations/Localization/Core/zh-HK.json b/MediaBrowser.Server.Implementations/Localization/Core/zh-HK.json index 8b5a8ff0d..3abc8d75a 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/zh-HK.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/zh-HK.json @@ -1,16 +1,16 @@ { "AppDeviceValues": "App: {0}, Device: {1}", "UserDownloadingItemWithValues": "{0} is downloading {1}", - "FolderTypeMixed": "Mixed content", - "FolderTypeMovies": "Movies", - "FolderTypeMusic": "Music", - "FolderTypeAdultVideos": "Adult videos", - "FolderTypePhotos": "Photos", - "FolderTypeMusicVideos": "Music videos", - "FolderTypeHomeVideos": "Home videos", - "FolderTypeGames": "Games", - "FolderTypeBooks": "Books", - "FolderTypeTvShows": "TV", + "FolderTypeMixed": "\u6df7\u5408\u5167\u5bb9", + "FolderTypeMovies": "\u96fb\u5f71", + "FolderTypeMusic": "\u97f3\u6a02", + "FolderTypeAdultVideos": "\u6210\u4eba\u5f71\u7247", + "FolderTypePhotos": "\u76f8\u7247", + "FolderTypeMusicVideos": "\u97f3\u6a02\u5f71\u7247", + "FolderTypeHomeVideos": "\u9996\u9801\u5f71\u7247", + "FolderTypeGames": "\u904a\u6232", + "FolderTypeBooks": "\u66f8\u85c9", + "FolderTypeTvShows": "\u96fb\u8996\u7bc0\u76ee", "FolderTypeInherit": "\u7e7c\u627f", "HeaderCastCrew": "\u6f14\u54e1\u9663\u5bb9", "HeaderPeople": "People", @@ -130,7 +130,7 @@ "HeaderType": "Type", "HeaderSeverity": "Severity", "HeaderUser": "User", - "HeaderName": "Name", + "HeaderName": "\u540d\u7a31", "HeaderDate": "\u65e5\u671f", "HeaderPremiereDate": "Premiere Date", "HeaderDateAdded": "Date Added", @@ -153,8 +153,8 @@ "HeaderAlbums": "Albums", "HeaderDisc": "Disc", "HeaderTrack": "Track", - "HeaderAudio": "Audio", - "HeaderVideo": "Video", + "HeaderAudio": "\u97f3\u8a0a", + "HeaderVideo": "\u5f71\u7247", "HeaderEmbeddedImage": "Embedded image", "HeaderResolution": "Resolution", "HeaderSubtitles": "Subtitles", diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 7d2d74140..75b903c99 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -232,6 +232,7 @@ <Compile Include="Localization\LocalizationManager.cs" /> <Compile Include="Logging\PatternsLogger.cs" /> <Compile Include="MediaEncoder\EncodingManager.cs" /> + <Compile Include="Notifications\IConfigurableNotificationService.cs" /> <Compile Include="Persistence\BaseSqliteRepository.cs" /> <Compile Include="Persistence\CleanDatabaseScheduledTask.cs" /> <Compile Include="Social\SharingManager.cs" /> diff --git a/MediaBrowser.Server.Implementations/Notifications/IConfigurableNotificationService.cs b/MediaBrowser.Server.Implementations/Notifications/IConfigurableNotificationService.cs new file mode 100644 index 000000000..5c4f400b0 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Notifications/IConfigurableNotificationService.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Notifications +{ + public interface IConfigurableNotificationService + { + bool IsHidden { get; } + bool IsEnabled(string notificationType); + } +} diff --git a/MediaBrowser.Server.Implementations/Notifications/InternalNotificationService.cs b/MediaBrowser.Server.Implementations/Notifications/InternalNotificationService.cs index 56cb52f10..4a625f0fb 100644 --- a/MediaBrowser.Server.Implementations/Notifications/InternalNotificationService.cs +++ b/MediaBrowser.Server.Implementations/Notifications/InternalNotificationService.cs @@ -3,10 +3,11 @@ using MediaBrowser.Controller.Notifications; using MediaBrowser.Model.Notifications; using System.Threading; using System.Threading.Tasks; +using System; namespace MediaBrowser.Server.Implementations.Notifications { - public class InternalNotificationService : INotificationService + public class InternalNotificationService : INotificationService, IConfigurableNotificationService { private readonly INotificationsRepository _repo; @@ -36,6 +37,24 @@ namespace MediaBrowser.Server.Implementations.Notifications public bool IsEnabledForUser(User user) { + return user.Policy.IsAdministrator; + } + + public bool IsHidden + { + get { return true; } + } + + public bool IsEnabled(string notificationType) + { + if (notificationType.IndexOf("playback", StringComparison.OrdinalIgnoreCase) != -1) + { + return false; + } + if (notificationType.IndexOf("newlibrarycontent", StringComparison.OrdinalIgnoreCase) != -1) + { + return false; + } return true; } } diff --git a/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs b/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs index 1ff928cd5..f19ff8a5f 100644 --- a/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs +++ b/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs @@ -230,8 +230,19 @@ namespace MediaBrowser.Server.Implementations.Notifications private bool IsEnabled(INotificationService service, string notificationType) { - return string.IsNullOrEmpty(notificationType) || - GetConfiguration().IsServiceEnabled(service.Name, notificationType); + if (string.IsNullOrEmpty(notificationType)) + { + return true; + } + + var configurable = service as IConfigurableNotificationService; + + if (configurable != null) + { + return configurable.IsEnabled(notificationType); + } + + return GetConfiguration().IsServiceEnabled(service.Name, notificationType); } public void AddParts(IEnumerable<INotificationService> services, IEnumerable<INotificationTypeFactory> notificationTypeFactories) @@ -268,7 +279,13 @@ namespace MediaBrowser.Server.Implementations.Notifications public IEnumerable<NotificationServiceInfo> GetNotificationServices() { - return _services.Select(i => new NotificationServiceInfo + return _services.Where(i => + { + var configurable = i as IConfigurableNotificationService; + + return configurable == null || !configurable.IsHidden; + + }).Select(i => new NotificationServiceInfo { Name = i.Name, Id = i.Name.GetMD5().ToString("N") diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index c9f7165cb..709ed5ec9 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -184,15 +184,24 @@ namespace MediaBrowser.Server.Implementations.Persistence try { - if (!_fileSystem.FileExists(path) && !_fileSystem.DirectoryExists(path)) + if (_fileSystem.FileExists(path) || _fileSystem.DirectoryExists(path)) { - var libraryItem = _libraryManager.GetItemById(item.Item1); + continue; + } + + var libraryItem = _libraryManager.GetItemById(item.Item1); - await _libraryManager.DeleteItem(libraryItem, new DeleteOptions - { - DeleteFileLocation = false - }); + if (Folder.IsPathOffline(path)) + { + libraryItem.IsOffline = true; + await libraryItem.UpdateToRepository(ItemUpdateType.None, cancellationToken).ConfigureAwait(false); + continue; } + + await _libraryManager.DeleteItem(libraryItem, new DeleteOptions + { + DeleteFileLocation = false + }); } catch (OperationCanceledException) { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 3c06973b4..adadea894 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deletePeopleCommand; private IDbCommand _savePersonCommand; - private const int LatestSchemaVersion = 7; + private const int LatestSchemaVersion = 9; /// <summary> /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class. @@ -177,6 +177,11 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "IsOffline", "BIT"); _connection.AddColumn(_logger, "TypedBaseItems", "LocationType", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "IsSeries", "BIT"); + _connection.AddColumn(_logger, "TypedBaseItems", "IsLive", "BIT"); + _connection.AddColumn(_logger, "TypedBaseItems", "IsNews", "BIT"); + _connection.AddColumn(_logger, "TypedBaseItems", "IsPremiere", "BIT"); + PrepareStatements(); _mediaStreamsRepository.Initialize(); @@ -199,6 +204,10 @@ namespace MediaBrowser.Server.Implementations.Persistence "IsMovie", "IsSports", "IsKids", + "IsSeries", + "IsLive", + "IsNews", + "IsPremiere", "CommunityRating", "CustomRating", "IndexNumber", @@ -222,6 +231,10 @@ namespace MediaBrowser.Server.Implementations.Persistence "IsKids", "IsMovie", "IsSports", + "IsSeries", + "IsLive", + "IsNews", + "IsPremiere", "CommunityRating", "CustomRating", "IndexNumber", @@ -369,12 +382,20 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsKids; _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsMovie; _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsSports; + _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsSeries; + _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsLive; + _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsNews; + _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsPremiere; } else { _saveItemCommand.GetParameter(index++).Value = null; _saveItemCommand.GetParameter(index++).Value = null; _saveItemCommand.GetParameter(index++).Value = null; + _saveItemCommand.GetParameter(index++).Value = null; + _saveItemCommand.GetParameter(index++).Value = null; + _saveItemCommand.GetParameter(index++).Value = null; + _saveItemCommand.GetParameter(index++).Value = null; } _saveItemCommand.GetParameter(index++).Value = item.CommunityRating; @@ -563,26 +584,46 @@ namespace MediaBrowser.Server.Implementations.Persistence { hasProgramAttributes.IsKids = reader.GetBoolean(8); } + + if (!reader.IsDBNull(9)) + { + hasProgramAttributes.IsSeries = reader.GetBoolean(9); + } + + if (!reader.IsDBNull(10)) + { + hasProgramAttributes.IsLive = reader.GetBoolean(10); + } + + if (!reader.IsDBNull(11)) + { + hasProgramAttributes.IsNews = reader.GetBoolean(11); + } + + if (!reader.IsDBNull(12)) + { + hasProgramAttributes.IsPremiere = reader.GetBoolean(12); + } } - if (!reader.IsDBNull(9)) + if (!reader.IsDBNull(13)) { - item.CommunityRating = reader.GetFloat(9); + item.CommunityRating = reader.GetFloat(13); } - if (!reader.IsDBNull(10)) + if (!reader.IsDBNull(14)) { - item.CustomRating = reader.GetString(10); + item.CustomRating = reader.GetString(14); } - if (!reader.IsDBNull(11)) + if (!reader.IsDBNull(15)) { - item.IndexNumber = reader.GetInt32(11); + item.IndexNumber = reader.GetInt32(15); } - if (!reader.IsDBNull(12)) + if (!reader.IsDBNull(16)) { - item.IsLocked = reader.GetBoolean(12); + item.IsLocked = reader.GetBoolean(16); } return item; diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 70a4cb439..d9c3ed7a6 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1322,8 +1322,9 @@ namespace MediaBrowser.Server.Implementations.Session if (existing.Items.Length > 0) { - _logger.Debug("Reissuing access token"); - return existing.Items[0].AccessToken; + var token = existing.Items[0].AccessToken; + _logger.Debug("Reissuing access token: " + token); + return token; } var newToken = new AuthenticationInfo diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index 968172bc3..80b7d230a 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -513,23 +513,19 @@ namespace MediaBrowser.ServerApplication if (!_isRunningAsService) { - _logger.Info("Hiding server notify icon"); - _serverNotifyIcon.Visible = false; + //_logger.Info("Hiding server notify icon"); + //_serverNotifyIcon.Visible = false; _logger.Info("Starting new instance"); //Application.Restart(); Process.Start(_appHost.ServerConfigurationManager.ApplicationPaths.ApplicationPath); - _logger.Info("Calling Environment.Exit"); - Environment.Exit(0); + ShutdownWindowsApplication(); } } private static void ShutdownWindowsApplication() { - _logger.Info("Hiding server notify icon"); - _serverNotifyIcon.Visible = false; - _logger.Info("Calling Application.Exit"); Application.Exit(); diff --git a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs index 3501c8c27..dd9e5d5f0 100644 --- a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs +++ b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs @@ -140,6 +140,19 @@ namespace MediaBrowser.ServerApplication } notifyIcon1.DoubleClick += notifyIcon1_DoubleClick; + Application.ApplicationExit += Application_ApplicationExit; + } + + void Application_ApplicationExit(object sender, EventArgs e) + { + try + { + notifyIcon1.Visible = false; + } + catch + { + + } } void notifyIcon1_DoubleClick(object sender, EventArgs e) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 233a1f3ba..57e52a254 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -173,6 +173,12 @@ <Content Include="dashboard-ui\components\imageuploader\imageuploader.template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\components\metadataeditor\metadataeditor.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="dashboard-ui\components\metadataeditor\metadataeditor.template.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\components\paperdialoghelper.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -185,6 +191,10 @@ <Content Include="dashboard-ui\cordova\fileupload.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\cordova\ios\backgroundfetch.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="dashboard-ui\cordova\ios\tabbar.js" />
<Content Include="dashboard-ui\cordova\ios\vlcplayer.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -592,9 +602,6 @@ <Content Include="dashboard-ui\cordova\android\androidcredentials.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\cordova\android\filesystem.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\cordova\android\iap.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -608,9 +615,6 @@ <Content Include="dashboard-ui\cordova\externalplayer.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\cordova\filesystem.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\cordova\generaldevice.js" />
<Content Include="dashboard-ui\cordova\iap.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -948,9 +952,6 @@ <Content Include="dashboard-ui\edititemmetadata.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\episodes.html">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\gamegenres.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -1194,9 +1195,6 @@ <Content Include="dashboard-ui\thirdparty\cast_sender.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\filesystem.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\thirdparty\fontawesome\css\font-awesome.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -1836,9 +1834,6 @@ <Content Include="dashboard-ui\thirdparty\jstree\themes\default\throbber.gif">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\tvupcoming.html">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\userlibraryaccess.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -2018,22 +2013,7 @@ <Content Include="dashboard-ui\scripts\tvstudios.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\tvgenres.html">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\tvlatest.html">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\tvpeople.html">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\tvrecommended.html">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\tvshows.html">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\tvstudios.html">
+ <Content Include="dashboard-ui\tv.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\userprofiles.html">
@@ -2693,6 +2673,9 @@ <None Include="dashboard-ui\strings\html\zh-HK.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
+ <None Include="dashboard-ui\strings\javascript\zh-HK.json">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
<None Include="dashboard-ui\thirdparty\fontawesome\css\font-awesome.css.map">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index c172cf40c..4709403c1 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common.Internal</id> - <version>3.0.634</version> + <version>3.0.635</version> <title>MediaBrowser.Common.Internal</title> <authors>Luke</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description> <copyright>Copyright © Emby 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.634" /> + <dependency id="MediaBrowser.Common" version="3.0.635" /> <dependency id="NLog" version="3.2.1" /> <dependency id="SimpleInjector" version="3.0.5" /> </dependencies> diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 978661b6e..fe8dfd91d 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common</id> - <version>3.0.634</version> + <version>3.0.635</version> <title>MediaBrowser.Common</title> <authors>Emby Team</authors> <owners>ebr,Luke,scottisafool</owners> diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 767117167..3870f66dc 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Model.Signed</id> - <version>3.0.634</version> + <version>3.0.635</version> <title>MediaBrowser.Model - Signed Edition</title> <authors>Emby Team</authors> <owners>ebr,Luke,scottisafool</owners> diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 29c9509eb..7de0a2f17 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>MediaBrowser.Server.Core</id> - <version>3.0.634</version> + <version>3.0.635</version> <title>Media Browser.Server.Core</title> <authors>Emby Team</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains core components required to build plugins for Emby Server.</description> <copyright>Copyright © Emby 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.634" /> + <dependency id="MediaBrowser.Common" version="3.0.635" /> <dependency id="Interfaces.IO" version="1.0.0.5" /> </dependencies> </metadata> diff --git a/SharedVersion.cs b/SharedVersion.cs index 3bb5b51cd..5b09ef084 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; [assembly: AssemblyVersion("3.0.*")] -//[assembly: AssemblyVersion("3.0.5724.4")] +//[assembly: AssemblyVersion("3.0.5724.5")] |
