diff --git a/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs index 46cf4dd98c..2b1e2f21d6 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs @@ -59,6 +59,12 @@ namespace MediaBrowser.Controller.LiveTv /// The clients. public List Clients { get; set; } + /// + /// Gets or sets a value indicating whether this instance can reset. + /// + /// true if this instance can reset; otherwise, false. + public bool CanReset { get; set; } + public LiveTvTunerInfo() { Clients = new List(); diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index ced36f3aa5..8d1b4057b6 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -934,7 +934,13 @@ namespace MediaBrowser.MediaEncoding.Encoder _mediaEncoder._runningProcesses.Remove(this); } - process.Dispose(); + try + { + process.Dispose(); + } + catch (Exception ex) + { + } } private bool _disposed; diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index ec51bc9674..07f1d45783 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -496,6 +496,26 @@ namespace MediaBrowser.MediaEncoding.Probing } } + var lyricist = FFProbeHelpers.GetDictionaryValue(tags, "lyricist"); + + if (!string.IsNullOrWhiteSpace(lyricist)) + { + foreach (var person in Split(lyricist, false)) + { + audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Lyricist }); + } + } + // Check for writer some music is tagged that way as alternative to composer/lyricist + var writer = FFProbeHelpers.GetDictionaryValue(tags, "writer"); + + if (!string.IsNullOrWhiteSpace(writer)) + { + foreach (var person in Split(writer, false)) + { + audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Writer }); + } + } + audio.Album = FFProbeHelpers.GetDictionaryValue(tags, "album"); var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists"); diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index d59974a2e8..57d9e0f1b2 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -48,11 +48,17 @@ namespace MediaBrowser.Model.Configuration public bool HidePlayedInLatest { get; set; } public bool DisplayChannelsInline { get; set; } + public bool RememberAudioSelections { get; set; } + public bool RememberSubtitleSelections { get; set; } + /// /// Initializes a new instance of the class. /// public UserConfiguration() { + RememberAudioSelections = true; + RememberSubtitleSelections = true; + HidePlayedInLatest = true; PlayDefaultAudioTrack = true; diff --git a/MediaBrowser.Model/Entities/PersonType.cs b/MediaBrowser.Model/Entities/PersonType.cs index bdf8460952..bc274972da 100644 --- a/MediaBrowser.Model/Entities/PersonType.cs +++ b/MediaBrowser.Model/Entities/PersonType.cs @@ -34,5 +34,9 @@ namespace MediaBrowser.Model.Entities /// The conductor /// public const string Conductor = "Conductor"; + /// + /// The lyricist + /// + public const string Lyricist = "Lyricist"; } } diff --git a/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs b/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs index fcb19427ba..9af96df434 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs @@ -64,6 +64,12 @@ namespace MediaBrowser.Model.LiveTv /// The clients. public List Clients { get; set; } + /// + /// Gets or sets a value indicating whether this instance can reset. + /// + /// true if this instance can reset; otherwise, false. + public bool CanReset { get; set; } + public LiveTvTunerInfoDto() { Clients = new List(); diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 9d43dabcde..51642cf5dc 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -502,7 +502,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - return series ?? new Series(); + return series; } /// diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index caddeec0db..e4a085f421 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -276,7 +276,7 @@ namespace MediaBrowser.Server.Implementations.Library private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user) { - if (userData.SubtitleStreamIndex.HasValue) + if (userData.SubtitleStreamIndex.HasValue && user.Configuration.RememberSubtitleSelections) { var index = userData.SubtitleStreamIndex.Value; // Make sure the saved index is still valid @@ -307,7 +307,7 @@ namespace MediaBrowser.Server.Implementations.Library private void SetDefaultAudioStreamIndex(MediaSourceInfo source, UserItemData userData, User user) { - if (userData.AudioStreamIndex.HasValue) + if (userData.AudioStreamIndex.HasValue && user.Configuration.RememberAudioSelections) { var index = userData.AudioStreamIndex.Value; // Make sure the saved index is still valid diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 04f99cdce9..81ad6a3877 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -178,7 +178,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv SourceType = info.SourceType, Status = info.Status, ChannelName = channelName, - Url = info.Url + Url = info.Url, + CanReset = info.CanReset }; if (!string.IsNullOrEmpty(info.ChannelId)) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 7c26f5675a..cd21dc21af 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -801,11 +801,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv { if (!string.IsNullOrWhiteSpace(info.ImagePath)) { - item.SetImagePath(ImageType.Primary, info.ImagePath); + item.SetImage(new ItemImageInfo + { + Path = info.ImagePath, + Type = ImageType.Primary, + IsPlaceholder = true + }, 0); } else if (!string.IsNullOrWhiteSpace(info.ImageUrl)) { - item.SetImagePath(ImageType.Primary, info.ImageUrl); + item.SetImage(new ItemImageInfo + { + Path = info.ImageUrl, + Type = ImageType.Primary, + IsPlaceholder = true + }, 0); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 8f5a4a0951..9ec5809a9e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using CommonIO; @@ -51,7 +52,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts string channnelName = null; string channelNumber = null; string line; - + string imageUrl = null; while ((line = reader.ReadLine()) != null) { line = line.Trim(); @@ -70,8 +71,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts line = line.Substring(8); _logger.Info("Found m3u channel: {0}", line); var parts = line.Split(new[] { ',' }, 2); - channelNumber = parts[0]; - channnelName = parts[1]; + channelNumber = parts[0].Trim().Split(' ')[0] ?? "0"; + channnelName = FindProperty("tvg-name", line, parts[1]); + imageUrl = FindProperty("tvg-logo", line, null); } else if (!string.IsNullOrWhiteSpace(channelNumber)) { @@ -80,23 +82,34 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts Name = channnelName, Number = channelNumber, Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"), - Path = line + ImageUrl = imageUrl }); + imageUrl = null; channelNumber = null; channnelName = null; } } return channels; } + public string FindProperty(string property, string properties, string defaultResult = "") + { + var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase); + var matches = reg.Matches(properties); + foreach (Match match in matches) + { + if (match.Groups[1].Value == property) + { + return match.Groups[2].Value; + } + } + return defaultResult; + } } + public class M3UChannel : ChannelInfo { public string Path { get; set; } - - public M3UChannel() - { - } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index 48337b9238..6781e498ac 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -98,7 +99,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp } catch (NotImplementedException) { - + } catch (Exception ex) { @@ -195,12 +196,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp break; } + case "friendlyName": + { + info.FriendlyName = reader.ReadElementContentAsString(); + break; + } + case "satip:X_SATIPCAP": case "X_SATIPCAP": { // DVBS2-2 - var value = reader.ReadElementContentAsString(); - // TODO + var value = reader.ReadElementContentAsString() ?? string.Empty; + var parts = value.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries); + if (parts.Length == 2) + { + int intValue; + if (int.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out intValue)) + { + info.TunersAvailable = intValue; + } + + if (int.TryParse(parts[0].Substring(parts[0].Length - 1), NumberStyles.Any, CultureInfo.InvariantCulture, out intValue)) + { + info.Tuners = intValue; + } + } break; } @@ -226,5 +246,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp public int Tuners { get; set; } public int TunersAvailable { get; set; } public string M3UUrl { get; set; } + public string FriendlyName { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs index 480f0edd04..976041bcc3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -140,17 +141,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp public Task> GetTunerInfos(CancellationToken cancellationToken) { var list = GetTunerHosts() - .Select(i => new LiveTvTunerInfo() - { - Name = Name, - SourceType = Type, - Status = LiveTvTunerStatus.Available, - Id = i.Url.GetMD5().ToString("N"), - Url = i.Url - }) + .SelectMany(i => GetTunerInfos(i, cancellationToken)) .ToList(); return Task.FromResult(list); } + + public List GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken) + { + var satInfo = (SatIpTunerHostInfo) info; + + var list = new List(); + + for (var i = 0; i < satInfo.Tuners; i++) + { + list.Add(new LiveTvTunerInfo + { + Name = satInfo.FriendlyName ?? Name, + SourceType = Type, + Status = LiveTvTunerStatus.Available, + Id = info.Url.GetMD5().ToString("N") + i.ToString(CultureInfo.InvariantCulture), + Url = info.Url + }); + } + + return list; + } } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index a858729512..697ec22716 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1014,7 +1014,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (!reader.IsDBNull(31)) { - item.OfficialRating = reader.GetString(31); + item.OfficialRatingDescription = reader.GetString(31); } if (!reader.IsDBNull(32)) diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 70f60f31a8..1074796c09 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -680,7 +680,7 @@ namespace MediaBrowser.Server.Implementations.Session foreach (var user in users) { - await OnPlaybackProgress(user.Id, key, libraryItem, info).ConfigureAwait(false); + await OnPlaybackProgress(user, key, libraryItem, info).ConfigureAwait(false); } } @@ -712,9 +712,9 @@ namespace MediaBrowser.Server.Implementations.Session StartIdleCheckTimer(); } - private async Task OnPlaybackProgress(Guid userId, string userDataKey, BaseItem item, PlaybackProgressInfo info) + private async Task OnPlaybackProgress(User user, string userDataKey, BaseItem item, PlaybackProgressInfo info) { - var data = _userDataRepository.GetUserData(userId, userDataKey); + var data = _userDataRepository.GetUserData(user.Id, userDataKey); var positionTicks = info.PositionTicks; @@ -722,16 +722,31 @@ namespace MediaBrowser.Server.Implementations.Session { _userDataRepository.UpdatePlayState(item, data, positionTicks.Value); - UpdatePlaybackSettings(info, data); + UpdatePlaybackSettings(user, info, data); - await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false); + await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false); } } - private void UpdatePlaybackSettings(PlaybackProgressInfo info, UserItemData data) + private void UpdatePlaybackSettings(User user, PlaybackProgressInfo info, UserItemData data) { - data.AudioStreamIndex = info.AudioStreamIndex; - data.SubtitleStreamIndex = info.SubtitleStreamIndex; + if (user.Configuration.RememberAudioSelections) + { + data.AudioStreamIndex = info.AudioStreamIndex; + } + else + { + data.AudioStreamIndex = null; + } + + if (user.Configuration.RememberSubtitleSelections) + { + data.SubtitleStreamIndex = info.SubtitleStreamIndex; + } + else + { + data.SubtitleStreamIndex = null; + } } /// diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 95934908da..39779ecf2a 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -19,6 +19,7 @@ using MediaBrowser.Model.Sync; using MoreLinq; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -125,7 +126,23 @@ namespace MediaBrowser.Server.Implementations.Sync private string GetSyncJobItemName(BaseItem item) { - return item.Name; + var name = item.Name; + var episode = item as Episode; + + if (episode != null) + { + if (episode.IndexNumber.HasValue) + { + name = "E" + episode.IndexNumber.Value.ToString(CultureInfo.InvariantCulture) + " - " + name; + } + + if (episode.ParentIndexNumber.HasValue) + { + name = "S" + episode.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture) + ", " + name; + } + } + + return name; } public Task UpdateJobStatus(string id) @@ -699,7 +716,7 @@ namespace MediaBrowser.Server.Implementations.Sync var path = Path.Combine(temporaryPath, filename); - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, cancellationToken).ConfigureAwait(false)) { diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 832944aade..7b5d144317 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -281,9 +281,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest