From 77afd4ba544abf2c92cd6d098e997dfc2d9b39c9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 24 Jul 2015 11:20:11 -0400 Subject: update live tv --- MediaBrowser.Model/Session/GeneralCommandType.cs | 4 +++- MediaBrowser.Model/Session/PlaybackProgressInfo.cs | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Model/Session') diff --git a/MediaBrowser.Model/Session/GeneralCommandType.cs b/MediaBrowser.Model/Session/GeneralCommandType.cs index f8773a246..dcb3b20ca 100644 --- a/MediaBrowser.Model/Session/GeneralCommandType.cs +++ b/MediaBrowser.Model/Session/GeneralCommandType.cs @@ -33,6 +33,8 @@ ToggleFullscreen = 25, DisplayContent = 26, GoToSearch = 27, - DisplayMessage = 28 + DisplayMessage = 28, + SetRepeatAll = 29, + SetRepeatOne = 30 } } \ No newline at end of file diff --git a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs index a7ca09c15..345931a62 100644 --- a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs +++ b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs @@ -88,5 +88,17 @@ namespace MediaBrowser.Model.Session /// /// The play session identifier. public string PlaySessionId { get; set; } + /// + /// Gets or sets the repeat mode. + /// + /// The repeat mode. + public RepeatMode RepeatMode { get; set; } + } + + public enum RepeatMode + { + RepeatNone = 0, + RepeatAll = 1, + RepeatOne = 2 } } \ No newline at end of file -- cgit v1.2.3 From 1bf9c446d93f5b9aae9a8f24439690beb0be3295 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 26 Jul 2015 17:02:23 -0400 Subject: update hdhomerun --- .../Configuration/ServerConfiguration.cs | 138 ++++++++++++++++++++- MediaBrowser.Model/Session/GeneralCommandType.cs | 3 +- MediaBrowser.Model/Users/UserPolicy.cs | 4 + .../LiveTv/Listings/SchedulesDirect.cs | 98 ++++++++------- .../Localization/Server/server.json | 5 +- 5 files changed, 198 insertions(+), 50 deletions(-) (limited to 'MediaBrowser.Model/Session') diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 19403a55e..0a2fabc1b 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -283,7 +283,59 @@ namespace MediaBrowser.Model.Configuration { new ImageOption { - Limit = 2, + Limit = 1, + MinWidth = 1280, + Type = ImageType.Backdrop + }, + + // Don't download this by default as it's rarely used. + new ImageOption + { + Limit = 0, + Type = ImageType.Art + }, + + // Don't download this by default as it's rarely used. + new ImageOption + { + Limit = 0, + Type = ImageType.Disc + }, + + new ImageOption + { + Limit = 1, + Type = ImageType.Primary + }, + + new ImageOption + { + Limit = 0, + Type = ImageType.Banner + }, + + new ImageOption + { + Limit = 1, + Type = ImageType.Thumb + }, + + new ImageOption + { + Limit = 1, + Type = ImageType.Logo + } + } + }, + + new MetadataOptions(1, 1280) + { + ItemType = "MusicVideo", + ImageOptions = new [] + { + new ImageOption + { + Limit = 1, MinWidth = 1280, Type = ImageType.Backdrop }, @@ -335,7 +387,7 @@ namespace MediaBrowser.Model.Configuration { new ImageOption { - Limit = 2, + Limit = 1, MinWidth = 1280, Type = ImageType.Backdrop }, @@ -432,9 +484,89 @@ namespace MediaBrowser.Model.Configuration } }, + new MetadataOptions(1, 1280) + { + ItemType = "BoxSet", + ImageOptions = new [] + { + new ImageOption + { + Limit = 1, + MinWidth = 1280, + Type = ImageType.Backdrop + }, + + new ImageOption + { + Limit = 1, + Type = ImageType.Primary + }, + + new ImageOption + { + Limit = 1, + Type = ImageType.Thumb + }, + + new ImageOption + { + Limit = 1, + Type = ImageType.Logo + }, + + // Don't download this by default as it's rarely used. + new ImageOption + { + Limit = 0, + Type = ImageType.Art + }, + + // Don't download this by default as it's rarely used. + new ImageOption + { + Limit = 0, + Type = ImageType.Disc + }, + + // Don't download this by default as it's rarely used. + new ImageOption + { + Limit = 0, + Type = ImageType.Banner + } + } + }, + new MetadataOptions(0, 1280) { - ItemType = "Season" + ItemType = "Season", + ImageOptions = new [] + { + new ImageOption + { + Limit = 0, + MinWidth = 1280, + Type = ImageType.Backdrop + }, + + new ImageOption + { + Limit = 1, + Type = ImageType.Primary + }, + + new ImageOption + { + Limit = 0, + Type = ImageType.Banner + }, + + new ImageOption + { + Limit = 0, + Type = ImageType.Thumb + } + } } }; } diff --git a/MediaBrowser.Model/Session/GeneralCommandType.cs b/MediaBrowser.Model/Session/GeneralCommandType.cs index dcb3b20ca..79220f066 100644 --- a/MediaBrowser.Model/Session/GeneralCommandType.cs +++ b/MediaBrowser.Model/Session/GeneralCommandType.cs @@ -34,7 +34,6 @@ DisplayContent = 26, GoToSearch = 27, DisplayMessage = 28, - SetRepeatAll = 29, - SetRepeatOne = 30 + SetRepeatMode = 29 } } \ No newline at end of file diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index b3040d6f8..16b4b673d 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -80,6 +80,10 @@ namespace MediaBrowser.Model.Users EnableLiveTvManagement = true; EnableLiveTvAccess = true; + // Without this on by default, admins won't be able to do this + // Improve in the future + EnableLiveTvManagement = true; + EnableSharedDeviceControl = true; BlockedTags = new string[] { }; diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 5fd9745a1..64599bc58 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -151,65 +151,72 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings public async Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken) { + if (string.IsNullOrWhiteSpace(info.ListingsId)) + { + throw new Exception("ListingsId required"); + } + var token = await GetToken(info, cancellationToken); + if (string.IsNullOrWhiteSpace(token)) + { + throw new Exception("token required"); + } + _channelPair.Clear(); - if (!String.IsNullOrWhiteSpace(token) && !String.IsNullOrWhiteSpace(info.ListingsId)) + var httpOptions = new HttpRequestOptions() { - var httpOptions = new HttpRequestOptions() - { - Url = ApiUrl + "/lineups/" + info.ListingsId, - UserAgent = UserAgent, - CancellationToken = cancellationToken - }; + Url = ApiUrl + "/lineups/" + info.ListingsId, + UserAgent = UserAgent, + CancellationToken = cancellationToken + }; - httpOptions.RequestHeaders["token"] = token; - - using (var response = await _httpClient.Get(httpOptions)) + httpOptions.RequestHeaders["token"] = token; + + using (var response = await _httpClient.Get(httpOptions)) + { + var root = _jsonSerializer.DeserializeFromStream(response); + _logger.Info("Found " + root.map.Count() + " channels on the lineup on ScheduleDirect"); + _logger.Info("Mapping Stations to Channel"); + foreach (ScheduleDirect.Map map in root.map) { - var root = _jsonSerializer.DeserializeFromStream(response); - _logger.Info("Found " + root.map.Count() + " channels on the lineup on ScheduleDirect"); - _logger.Info("Mapping Stations to Channel"); - foreach (ScheduleDirect.Map map in root.map) - { - var channel = (map.channel ?? (map.atscMajor + "." + map.atscMinor)).TrimStart('0'); - _logger.Debug("Found channel: " + channel + " in Schedules Direct"); - var schChannel = root.stations.FirstOrDefault(item => item.stationID == map.stationID); + var channel = (map.channel ?? (map.atscMajor + "." + map.atscMinor)).TrimStart('0'); + _logger.Debug("Found channel: " + channel + " in Schedules Direct"); + var schChannel = root.stations.FirstOrDefault(item => item.stationID == map.stationID); - if (!_channelPair.ContainsKey(channel) && channel != "0.0" && schChannel != null) - { - _channelPair.TryAdd(channel, schChannel); - } + if (!_channelPair.ContainsKey(channel) && channel != "0.0" && schChannel != null) + { + _channelPair.TryAdd(channel, schChannel); } - _logger.Info("Added " + _channelPair.Count() + " channels to the dictionary"); + } + _logger.Info("Added " + _channelPair.Count() + " channels to the dictionary"); - foreach (ChannelInfo channel in channels) + foreach (ChannelInfo channel in channels) + { + // Helper.logger.Info("Modifyin channel " + channel.Number); + if (_channelPair.ContainsKey(channel.Number)) { - // Helper.logger.Info("Modifyin channel " + channel.Number); - if (_channelPair.ContainsKey(channel.Number)) + string channelName; + if (_channelPair[channel.Number].logo != null) { - string channelName; - if (_channelPair[channel.Number].logo != null) - { - channel.ImageUrl = _channelPair[channel.Number].logo.URL; - channel.HasImage = true; - } - if (_channelPair[channel.Number].affiliate != null) - { - channelName = _channelPair[channel.Number].affiliate; - } - else - { - channelName = _channelPair[channel.Number].name; - } - channel.Name = channelName; + channel.ImageUrl = _channelPair[channel.Number].logo.URL; + channel.HasImage = true; + } + if (_channelPair[channel.Number].affiliate != null) + { + channelName = _channelPair[channel.Number].affiliate; } else { - _logger.Info("Schedules Direct doesnt have data for channel: " + channel.Number + " " + - channel.Name); + channelName = _channelPair[channel.Number].name; } + channel.Name = channelName; + } + else + { + _logger.Info("Schedules Direct doesnt have data for channel: " + channel.Number + " " + + channel.Name); } } } @@ -572,6 +579,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings var token = await GetToken(info, cancellationToken); + if (string.IsNullOrWhiteSpace(token)) + { + throw new Exception("token required"); + } + _logger.Info("Headends on account "); var options = new HttpRequestOptions() diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index e5a36b12f..e06bcea34 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1459,7 +1459,7 @@ "ButtonUnlockGuide": "Unlock Guide", "LabelEnableFullScreen": "Enable fullscreen mode", "LabelEnableChromecastAc3Passthrough": "Enable Chromecast AC3 Passthrough", - "LabelSyncPath": "Synced content path:", + "OptionSyncToSDCard": "Synced to external SD card", "LabelEmail": "Email:", "LabelUsername": "Username:", "HeaderSignUp": "Sign Up", @@ -1491,5 +1491,6 @@ "LabelLineup": "Lineup:", "MessageTunerDeviceNotListed": "Is your tuner device not listed? Try installing an external service provider for more Live TV options.", "LabelImportOnlyFavoriteChannels": "Restrict to channels marked as favorite", - "ImportFavoriteChannelsHelp": "If enabled, only channels that are marked as favorite on the tuner device will be imported." + "ImportFavoriteChannelsHelp": "If enabled, only channels that are marked as favorite on the tuner device will be imported.", + "ButtonRepeat": "Repeat" } -- cgit v1.2.3 From a2b9ee8ac6c760c02cd1cc42d0fe56137b77802e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 30 Jul 2015 10:34:46 -0400 Subject: update startup wizard --- MediaBrowser.Api/UserLibrary/PlaystateService.cs | 6 +++++- MediaBrowser.Model/Session/PlayerStateInfo.cs | 6 ++++++ MediaBrowser.Server.Implementations/Session/SessionManager.cs | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Model/Session') diff --git a/MediaBrowser.Api/UserLibrary/PlaystateService.cs b/MediaBrowser.Api/UserLibrary/PlaystateService.cs index 5f32725d8..7002a3703 100644 --- a/MediaBrowser.Api/UserLibrary/PlaystateService.cs +++ b/MediaBrowser.Api/UserLibrary/PlaystateService.cs @@ -185,6 +185,9 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "PlaySessionId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] public string PlaySessionId { get; set; } + + [ApiMember(Name = "RepeatMode", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + public RepeatMode RepeatMode { get; set; } } /// @@ -325,7 +328,8 @@ namespace MediaBrowser.Api.UserLibrary VolumeLevel = request.VolumeLevel, PlayMethod = request.PlayMethod, PlaySessionId = request.PlaySessionId, - LiveStreamId = request.LiveStreamId + LiveStreamId = request.LiveStreamId, + RepeatMode = request.RepeatMode }); } diff --git a/MediaBrowser.Model/Session/PlayerStateInfo.cs b/MediaBrowser.Model/Session/PlayerStateInfo.cs index c9afef8e0..f78842e29 100644 --- a/MediaBrowser.Model/Session/PlayerStateInfo.cs +++ b/MediaBrowser.Model/Session/PlayerStateInfo.cs @@ -55,5 +55,11 @@ /// /// The play method. public PlayMethod? PlayMethod { get; set; } + + /// + /// Gets or sets the repeat mode. + /// + /// The repeat mode. + public RepeatMode RepeatMode { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 560d203db..c2160f48a 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -366,6 +366,7 @@ namespace MediaBrowser.Server.Implementations.Session session.PlayState.AudioStreamIndex = info.AudioStreamIndex; session.PlayState.SubtitleStreamIndex = info.SubtitleStreamIndex; session.PlayState.PlayMethod = info.PlayMethod; + session.PlayState.RepeatMode = info.RepeatMode; } /// -- cgit v1.2.3 From 1f1f7642c3df2f9ec67bbdbdb4d5ed66e126f3ab Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 16 Aug 2015 11:53:30 -0400 Subject: update subtitle escaping --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 4 ++-- MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs | 7 +++++++ MediaBrowser.Controller/Session/SessionInfo.cs | 6 ++++++ MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 4 ++-- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 5 +++++ MediaBrowser.Model/Session/SessionInfoDto.cs | 6 ++++++ .../Session/SessionManager.cs | 2 ++ .../MediaBrowser.WebDashboard.csproj | 17 +++-------------- 8 files changed, 33 insertions(+), 18 deletions(-) (limited to 'MediaBrowser.Model/Session') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 8f5301642..6fba6052f 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -619,7 +619,7 @@ namespace MediaBrowser.Api.Playback // TODO: Perhaps also use original_size=1920x800 ?? return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB", - subtitlePath.Replace('\\', '/').Replace(":/", "\\:/"), + MediaEncoder.EscapeSubtitleFilterPath(subtitlePath), charsetParam, seconds.ToString(UsCulture)); } @@ -627,7 +627,7 @@ namespace MediaBrowser.Api.Playback var mediaPath = state.MediaPath ?? string.Empty; return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB", - mediaPath.Replace('\\', '/').Replace(":/", "\\:/"), + MediaEncoder.EscapeSubtitleFilterPath(mediaPath), state.InternalSubtitleStreamOffset.ToString(UsCulture), seconds.ToString(UsCulture)); } diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 5bec7980a..23285b612 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -116,5 +116,12 @@ namespace MediaBrowser.Controller.MediaEncoding Task EncodeVideo(EncodingJobOptions options, IProgress progress, CancellationToken cancellationToken); + + /// + /// Escapes the subtitle filter path. + /// + /// The path. + /// System.String. + string EscapeSubtitleFilterPath(string path); } } diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index 64b20c13e..b3e82f925 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -125,6 +125,12 @@ namespace MediaBrowser.Controller.Session /// The session controller. public ISessionController SessionController { get; set; } + /// + /// Gets or sets the application icon URL. + /// + /// The application icon URL. + public string AppIconUrl { get; set; } + /// /// Gets or sets the supported commands. /// diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index dd88512fb..181f147b4 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -865,13 +865,13 @@ namespace MediaBrowser.MediaEncoding.Encoder // TODO: Perhaps also use original_size=1920x800 ?? return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB", - subtitlePath.Replace('\\', '/').Replace(":/", "\\:/"), + MediaEncoder.EscapeSubtitleFilterPath(subtitlePath), charsetParam, seconds.ToString(UsCulture)); } return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB", - state.MediaPath.Replace('\\', '/').Replace(":/", "\\:/"), + MediaEncoder.EscapeSubtitleFilterPath(state.MediaPath), state.InternalSubtitleStreamOffset.ToString(UsCulture), seconds.ToString(UsCulture)); } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index c059a8b54..50b6a94aa 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -765,6 +765,11 @@ namespace MediaBrowser.MediaEncoding.Encoder } } + public string EscapeSubtitleFilterPath(string path) + { + return path.Replace('\\', '/').Replace(":/", "\\:/").Replace("'", "'\\\\\\'"); + } + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// diff --git a/MediaBrowser.Model/Session/SessionInfoDto.cs b/MediaBrowser.Model/Session/SessionInfoDto.cs index 98df3efe5..da8ab9b8a 100644 --- a/MediaBrowser.Model/Session/SessionInfoDto.cs +++ b/MediaBrowser.Model/Session/SessionInfoDto.cs @@ -99,6 +99,12 @@ namespace MediaBrowser.Model.Session /// /// The device id. public string DeviceId { get; set; } + + /// + /// Gets or sets the application icon URL. + /// + /// The application icon URL. + public string AppIconUrl { get; set; } /// /// Gets or sets a value indicating whether [supports remote control]. diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index c2160f48a..70a4cb439 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -161,6 +161,7 @@ namespace MediaBrowser.Server.Implementations.Session if (capabilities != null) { + info.AppIconUrl = capabilities.IconUrl; ReportCapabilities(info, capabilities, false); } } @@ -1476,6 +1477,7 @@ namespace MediaBrowser.Server.Implementations.Session NowPlayingItem = session.NowPlayingItem, SupportsRemoteControl = session.SupportsMediaControl, PlayState = session.PlayState, + AppIconUrl = session.AppIconUrl, TranscodingInfo = session.NowPlayingItem == null ? null : session.TranscodingInfo }; diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 42a9c5c1b..a90fbaec8 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -156,6 +156,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -565,12 +568,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -802,9 +799,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -2207,11 +2201,6 @@ PreserveNewest - - - PreserveNewest - - PreserveNewest -- cgit v1.2.3