diff options
| author | Tim Hobbs <jesus.tesh@gmail.com> | 2014-03-13 06:36:39 -0700 |
|---|---|---|
| committer | Tim Hobbs <jesus.tesh@gmail.com> | 2014-03-13 06:36:39 -0700 |
| commit | 9976857e785d7e76807e02798480a063f9f3defa (patch) | |
| tree | 0335c9e5ffabc49fd88150b297860af4fe04a0d6 /MediaBrowser.Dlna | |
| parent | a402d3ea9232799b136b0dc8e9936ebfb286b7f5 (diff) | |
| parent | b7bcc2450694105de9f9fc8cc07d2cfc4d9d7c96 (diff) | |
Merge remote-tracking branch 'upstream/master' into ribbons
Diffstat (limited to 'MediaBrowser.Dlna')
| -rw-r--r-- | MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 2 | ||||
| -rw-r--r-- | MediaBrowser.Dlna/PlayTo/Configuration/PlayToConfiguration.cs (renamed from MediaBrowser.Dlna/PlayTo/Configuration/PluginConfiguration.cs) | 21 | ||||
| -rw-r--r-- | MediaBrowser.Dlna/PlayTo/Configuration/TranscodeSetting.cs | 15 | ||||
| -rw-r--r-- | MediaBrowser.Dlna/PlayTo/Device.cs | 96 | ||||
| -rw-r--r-- | MediaBrowser.Dlna/PlayTo/DlnaController.cs | 11 | ||||
| -rw-r--r-- | MediaBrowser.Dlna/PlayTo/PlayToServerEntryPoint.cs | 91 | ||||
| -rw-r--r-- | MediaBrowser.Dlna/PlayTo/PlaylistItem.cs | 15 | ||||
| -rw-r--r-- | MediaBrowser.Dlna/PlayTo/StreamHelper.cs | 14 |
8 files changed, 211 insertions, 54 deletions
diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 59420c5a1d..622ccefbc6 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -53,7 +53,7 @@ </Compile> <Compile Include="PlayTo\Argument.cs" /> <Compile Include="PlayTo\Configuration\DlnaProfile.cs" /> - <Compile Include="PlayTo\Configuration\PluginConfiguration.cs" /> + <Compile Include="PlayTo\Configuration\PlayToConfiguration.cs" /> <Compile Include="PlayTo\Configuration\TranscodeSetting.cs" /> <Compile Include="PlayTo\CurrentIdEventArgs.cs" /> <Compile Include="PlayTo\Device.cs"> diff --git a/MediaBrowser.Dlna/PlayTo/Configuration/PluginConfiguration.cs b/MediaBrowser.Dlna/PlayTo/Configuration/PlayToConfiguration.cs index 1bd8781bb2..d3fcb24ada 100644 --- a/MediaBrowser.Dlna/PlayTo/Configuration/PluginConfiguration.cs +++ b/MediaBrowser.Dlna/PlayTo/Configuration/PlayToConfiguration.cs @@ -29,7 +29,12 @@ FriendlyName = "^TV$", ModelNumber = @"1\.0", ModelName = "Samsung DTV DMR", - TranscodeSettings = TranscodeSettings.GetDefaultTranscodingSettings() + TranscodeSettings = new[] + { + new TranscodeSettings {Container = "mkv", MimeType = "x-mkv"}, + new TranscodeSettings {Container = "flac", TargetContainer = "mp3"}, + new TranscodeSettings {Container = "m4a", TargetContainer = "mp3"} + } }; var profile1 = new DlnaProfile @@ -38,7 +43,12 @@ ClientType = "DLNA", FriendlyName = @"(^\[TV\][A-Z]{2}\d{2}(E|F)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung", ModelNumber = @"(1\.0)|(AllShare1\.0)", - TranscodeSettings = TranscodeSettings.GetDefaultTranscodingSettings() + TranscodeSettings = new[] + { + new TranscodeSettings {Container = "mkv", MimeType = "x-mkv"}, + new TranscodeSettings {Container = "flac", TargetContainer = "mp3"}, + new TranscodeSettings {Container = "m4a", TargetContainer = "mp3"} + } }; var profile2 = new DlnaProfile @@ -47,7 +57,12 @@ ClientType = "DLNA", FriendlyName = @"(^TV-\d{2}C\d{3}.*)|(^\[TV\][A-Z]{2}\d{2}(D)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung", ModelNumber = @"(1\.0)|(AllShare1\.0)", - TranscodeSettings = TranscodeSettings.GetDefaultTranscodingSettings() + TranscodeSettings = new[] + { + new TranscodeSettings {Container = "mkv", MimeType = "x-mkv"}, + new TranscodeSettings {Container = "flac", TargetContainer = "mp3"}, + new TranscodeSettings {Container = "m4a", TargetContainer = "mp3"} + } }; var profile3 = new DlnaProfile diff --git a/MediaBrowser.Dlna/PlayTo/Configuration/TranscodeSetting.cs b/MediaBrowser.Dlna/PlayTo/Configuration/TranscodeSetting.cs index f5cceaaaaa..4713dc3859 100644 --- a/MediaBrowser.Dlna/PlayTo/Configuration/TranscodeSetting.cs +++ b/MediaBrowser.Dlna/PlayTo/Configuration/TranscodeSetting.cs @@ -1,4 +1,5 @@ using System; +using System.Text.RegularExpressions; namespace MediaBrowser.Dlna.PlayTo.Configuration { @@ -21,6 +22,14 @@ namespace MediaBrowser.Dlna.PlayTo.Configuration public string TargetContainer { get; set; } /// <summary> + /// Gets or sets the Mimetype to enforce + /// </summary> + /// <value> + /// The MimeType. + /// </value> + public string MimeType { get; set; } + + /// <summary> /// The default transcoding settings /// </summary> private static readonly TranscodeSettings[] DefaultTranscodingSettings = @@ -46,19 +55,19 @@ namespace MediaBrowser.Dlna.PlayTo.Configuration { if (!string.IsNullOrEmpty(profile.FriendlyName)) { - if (!string.Equals(deviceProperties.Name, profile.FriendlyName, StringComparison.OrdinalIgnoreCase)) + if (!Regex.IsMatch(deviceProperties.Name, profile.FriendlyName)) continue; } if (!string.IsNullOrEmpty(profile.ModelNumber)) { - if (!string.Equals(deviceProperties.ModelNumber, profile.ModelNumber, StringComparison.OrdinalIgnoreCase)) + if (!Regex.IsMatch(deviceProperties.ModelNumber, profile.ModelNumber)) continue; } if (!string.IsNullOrEmpty(profile.ModelName)) { - if (!string.Equals(deviceProperties.ModelName, profile.ModelName, StringComparison.OrdinalIgnoreCase)) + if (!Regex.IsMatch(deviceProperties.ModelName, profile.ModelName)) continue; } diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs index 9c2859a363..690f7525bb 100644 --- a/MediaBrowser.Dlna/PlayTo/Device.cs +++ b/MediaBrowser.Dlna/PlayTo/Device.cs @@ -76,8 +76,8 @@ namespace MediaBrowser.Dlna.PlayTo _transportState = value; - if (value == "PLAYING" || value == "STOPPED") - NotifyPlaybackChanged(value == "STOPPED"); + if (value == TRANSPORTSTATE.PLAYING || value == TRANSPORTSTATE.STOPPED) + NotifyPlaybackChanged(value == TRANSPORTSTATE.STOPPED); } } @@ -85,7 +85,7 @@ namespace MediaBrowser.Dlna.PlayTo { get { - return TransportState == "PLAYING"; + return TransportState == TRANSPORTSTATE.PLAYING; } } @@ -93,7 +93,7 @@ namespace MediaBrowser.Dlna.PlayTo { get { - return (TransportState == "TRANSITIONING"); + return (TransportState == TRANSPORTSTATE.TRANSITIONING); } } @@ -101,7 +101,7 @@ namespace MediaBrowser.Dlna.PlayTo { get { - return TransportState == "PAUSED" || TransportState == "PAUSED_PLAYBACK"; + return TransportState == TRANSPORTSTATE.PAUSED || TransportState == TRANSPORTSTATE.PAUSED_PLAYBACK; } } @@ -109,7 +109,7 @@ namespace MediaBrowser.Dlna.PlayTo { get { - return (TransportState == "STOPPED"); + return TransportState == TRANSPORTSTATE.STOPPED; } } @@ -127,23 +127,39 @@ namespace MediaBrowser.Dlna.PlayTo _logger = logger; } - private int GetTimerIntervalMs() + private int GetPlaybackTimerIntervalMs() { - return 10000; + return 2000; + } + + private int GetInactiveTimerIntervalMs() + { + return 20000; } public void Start() { UpdateTime = DateTime.UtcNow; - var interval = GetTimerIntervalMs(); + var interval = GetPlaybackTimerIntervalMs(); _timer = new Timer(TimerCallback, null, interval, interval); } private void RestartTimer() { - var interval = GetTimerIntervalMs(); + var interval = GetPlaybackTimerIntervalMs(); + + _timer.Change(interval, interval); + } + + + /// <summary> + /// Restarts the timer in inactive mode. + /// </summary> + private void RestartTimerInactive() + { + var interval = GetInactiveTimerIntervalMs(); _timer.Change(interval, interval); } @@ -230,11 +246,9 @@ namespace MediaBrowser.Dlna.PlayTo { StopTimer(); - TransportState = "STOPPED"; + await SetStop().ConfigureAwait(false); CurrentId = "0"; - await Task.Delay(50).ConfigureAwait(false); - var command = AvCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetAVTransportURI"); if (command == null) return false; @@ -261,7 +275,7 @@ namespace MediaBrowser.Dlna.PlayTo await SetPlay().ConfigureAwait(false); } - _count = 5; + _lapsCount = GetLapsCount(); RestartTimer(); return true; @@ -322,7 +336,7 @@ namespace MediaBrowser.Dlna.PlayTo var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, 1)) .ConfigureAwait(false); - _count = 5; + _lapsCount = GetLapsCount(); return true; } @@ -338,7 +352,6 @@ namespace MediaBrowser.Dlna.PlayTo .ConfigureAwait(false); await Task.Delay(50).ConfigureAwait(false); - _count = 4; return true; } @@ -362,8 +375,13 @@ namespace MediaBrowser.Dlna.PlayTo #region Get data - // TODO: What is going on here - int _count = 5; + private int GetLapsCount() + { + // No need to get all data every lap, just every X time. + return 10; + } + + int _lapsCount = 0; private async void TimerCallback(object sender) { @@ -374,18 +392,24 @@ namespace MediaBrowser.Dlna.PlayTo try { - var hasTrack = await GetPositionInfo().ConfigureAwait(false); + await GetTransportInfo().ConfigureAwait(false); - // TODO: Why make these requests if hasTrack==false? - if (_count > 5) + //If we're not playing anything no need to get additional data + if (TransportState != TRANSPORTSTATE.STOPPED) { - await GetTransportInfo().ConfigureAwait(false); - if (!hasTrack) + var hasTrack = await GetPositionInfo().ConfigureAwait(false); + + // TODO: Why make these requests if hasTrack==false? + // TODO ANSWER Some vendors don't include track in GetPositionInfo, use GetMediaInfo instead. + if (_lapsCount > GetLapsCount()) { - await GetMediaInfo().ConfigureAwait(false); + if (!hasTrack) + { + await GetMediaInfo().ConfigureAwait(false); + } + await GetVolume().ConfigureAwait(false); + _lapsCount = 0; } - await GetVolume().ConfigureAwait(false); - _count = 0; } } catch (Exception ex) @@ -393,11 +417,16 @@ namespace MediaBrowser.Dlna.PlayTo _logger.ErrorException("Error updating device info", ex); } - _count++; + _lapsCount++; + if (_disposed) return; - RestartTimer(); + //If we're not playing anything make sure we don't get data more often than neccessry to keep the Session alive + if (TransportState != TRANSPORTSTATE.STOPPED) + RestartTimer(); + else + RestartTimerInactive(); } private async Task GetVolume() @@ -747,5 +776,16 @@ namespace MediaBrowser.Dlna.PlayTo { return String.Format("{0} - {1}", Properties.Name, Properties.BaseUrl); } + + private class TRANSPORTSTATE + { + public const string STOPPED = "STOPPED"; + public const string PLAYING = "PLAYING"; + public const string TRANSITIONING = "TRANSITIONING"; + public const string PAUSED_PLAYBACK = "PAUSED_PLAYBACK"; + public const string PAUSED = "PAUSED"; + } + } } + diff --git a/MediaBrowser.Dlna/PlayTo/DlnaController.cs b/MediaBrowser.Dlna/PlayTo/DlnaController.cs index 894e32599d..2be82b9853 100644 --- a/MediaBrowser.Dlna/PlayTo/DlnaController.cs +++ b/MediaBrowser.Dlna/PlayTo/DlnaController.cs @@ -17,7 +17,7 @@ using Timer = System.Timers.Timer; namespace MediaBrowser.Dlna.PlayTo { - public class PlayToController : ISessionController + public class PlayToController : ISessionController, IDisposable { private Device _device; private BaseItem _currentItem = null; @@ -131,6 +131,14 @@ namespace MediaBrowser.Dlna.PlayTo ((Timer)sender).Stop(); + + if (!IsSessionActive) + { + //Session is inactive, mark it for Disposal and don't start the elapsed timer. + await _sessionManager.ReportSessionEnded(this._session.Id); + return; + } + await ReportProgress().ConfigureAwait(false); if (!_disposed && IsSessionActive) @@ -479,3 +487,4 @@ namespace MediaBrowser.Dlna.PlayTo } } } + diff --git a/MediaBrowser.Dlna/PlayTo/PlayToServerEntryPoint.cs b/MediaBrowser.Dlna/PlayTo/PlayToServerEntryPoint.cs index b1afeb0f4a..a6746cfc50 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToServerEntryPoint.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToServerEntryPoint.cs @@ -1,40 +1,107 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; +using System; namespace MediaBrowser.Dlna.PlayTo { public class PlayToServerEntryPoint : IServerEntryPoint { - private bool _disposed; + private PlayToManager _manager; + private readonly IServerConfigurationManager _config; + private readonly ILogger _logger; + private readonly ISessionManager _sessionManager; + private readonly IHttpClient _httpClient; + private readonly IItemRepository _itemRepo; + private readonly ILibraryManager _libraryManager; + private readonly INetworkManager _networkManager; + private readonly IUserManager _userManager; - private readonly PlayToManager _manager; - - public PlayToServerEntryPoint(ILogManager logManager, ISessionManager sessionManager, IUserManager userManager, IHttpClient httpClient, INetworkManager networkManager, IItemRepository itemRepository, ILibraryManager libraryManager) + public PlayToServerEntryPoint(ILogManager logManager, IServerConfigurationManager config, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepo, ILibraryManager libraryManager, INetworkManager networkManager, IUserManager userManager) { - _manager = new PlayToManager(logManager.GetLogger("PlayTo"), sessionManager, httpClient, itemRepository, libraryManager, networkManager, userManager); + _config = config; + _sessionManager = sessionManager; + _httpClient = httpClient; + _itemRepo = itemRepo; + _libraryManager = libraryManager; + _networkManager = networkManager; + _userManager = userManager; + _logger = logManager.GetLogger("PlayTo"); } public void Run() { - //_manager.Start(); + _config.ConfigurationUpdated += ConfigurationUpdated; + ReloadPlayToManager(); } - #region Dispose + void ConfigurationUpdated(object sender, EventArgs e) + { + ReloadPlayToManager(); + } - public void Dispose() + private void ReloadPlayToManager() + { + var isStarted = _manager != null; + + if (_config.Configuration.DlnaOptions.EnablePlayTo && !isStarted) + { + StartPlayToManager(); + } + else if (!_config.Configuration.DlnaOptions.EnablePlayTo && isStarted) + { + DisposePlayToManager(); + } + } + + private readonly object _syncLock = new object(); + private void StartPlayToManager() + { + lock (_syncLock) + { + try + { + _manager = new PlayToManager(_logger, _sessionManager, _httpClient, _itemRepo, _libraryManager, _networkManager, _userManager); + _manager.Start(); + } + catch (Exception ex) + { + _logger.ErrorException("Error starting PlayTo manager", ex); + } + } + } + + private void DisposePlayToManager() { - if (!_disposed) + lock (_syncLock) { - _disposed = true; - _manager.Stop(); - _manager.Dispose(); + if (_manager != null) + { + try + { + _manager.Stop(); + _manager.Dispose(); + } + catch (Exception ex) + { + _logger.ErrorException("Error disposing PlayTo manager", ex); + } + _manager = null; + } } } + #region Dispose + + public void Dispose() + { + DisposePlayToManager(); + } + #endregion } } diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs index d2d04c4a8e..6523eb9f52 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs @@ -16,6 +16,8 @@ namespace MediaBrowser.Dlna.PlayTo public string FileFormat { get; set; } + public string MimeType { get; set; } + public int PlayState { get; set; } public string StreamUrl { get; set; } @@ -51,10 +53,21 @@ namespace MediaBrowser.Dlna.PlayTo { if (string.IsNullOrWhiteSpace(transcodeSetting.Container)) continue; - if (path.EndsWith(transcodeSetting.Container)) + if (path.EndsWith(transcodeSetting.Container) && !string.IsNullOrWhiteSpace(transcodeSetting.TargetContainer)) { playlistItem.Transcode = true; playlistItem.FileFormat = transcodeSetting.TargetContainer; + + if (string.IsNullOrWhiteSpace(transcodeSetting.MimeType)) + playlistItem.MimeType = transcodeSetting.MimeType; + + return playlistItem; + } + if (path.EndsWith(transcodeSetting.Container) && !string.IsNullOrWhiteSpace(transcodeSetting.MimeType)) + { + playlistItem.Transcode = false; + playlistItem.FileFormat = transcodeSetting.Container; + playlistItem.MimeType = transcodeSetting.MimeType; return playlistItem; } } diff --git a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs index eed0bb7d77..3492ed182e 100644 --- a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs +++ b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs @@ -96,9 +96,12 @@ namespace MediaBrowser.Dlna.PlayTo /// <returns>The url to send to the device</returns> internal static string GetVideoUrl(DeviceProperties deviceProperties, PlaylistItem item, List<MediaStream> streams, string serverAddress) { + string dlnaCommand = string.Empty; if (!item.Transcode) - return string.Format("{0}/Videos/{1}/stream.{2}?Static=True", serverAddress, item.ItemId, item.FileFormat); - + { + dlnaCommand = BuildDlnaUrl(deviceProperties.UUID, !item.Transcode, null, null, null, null, null, null, null, null, null, null, item.MimeType); + return string.Format("{0}/Videos/{1}/stream.{2}?{3}", serverAddress, item.ItemId, item.FileFormat, dlnaCommand); + } var videostream = streams.Where(m => m.Type == MediaStreamType.Video).OrderBy(m => m.IsDefault).FirstOrDefault(); var audiostream = streams.Where(m => m.Type == MediaStreamType.Audio).OrderBy(m => m.IsDefault).FirstOrDefault(); @@ -117,7 +120,7 @@ namespace MediaBrowser.Dlna.PlayTo audioChannels = 2; } - string dlnaCommand = BuildDlnaUrl(deviceProperties.UUID, videoCodec, audioCodec, null, null, videoBitrate, audioChannels, audioBitrate, item.StartPositionTicks, "baseline", "3"); + dlnaCommand = BuildDlnaUrl(deviceProperties.UUID, !item.Transcode, videoCodec, audioCodec, null, null, videoBitrate, audioChannels, audioBitrate, item.StartPositionTicks, "baseline", "3", item.MimeType); return string.Format("{0}/Videos/{1}/stream.{2}?{3}", serverAddress, item.ItemId, item.FileFormat, dlnaCommand); } @@ -162,12 +165,12 @@ namespace MediaBrowser.Dlna.PlayTo /// <summary> /// Builds the dlna URL. /// </summary> - private static string BuildDlnaUrl(string deviceID, VideoCodecs? videoCodec, AudioCodecs? audioCodec, int? subtitleIndex, int? audiostreamIndex, int? videoBitrate, int? audiochannels, int? audioBitrate, long? startPositionTicks, string profile, string videoLevel) + private static string BuildDlnaUrl(string deviceID, bool isStatic, VideoCodecs? videoCodec, AudioCodecs? audioCodec, int? subtitleIndex, int? audiostreamIndex, int? videoBitrate, int? audiochannels, int? audioBitrate, long? startPositionTicks, string profile, string videoLevel, string mimeType) { var usCulture = new CultureInfo("en-US"); var dlnaparam = string.Format("Params={0};", deviceID); - + dlnaparam += isStatic ? "true;" : "false;"; dlnaparam += videoCodec.HasValue ? videoCodec.Value + ";" : ";"; dlnaparam += audioCodec.HasValue ? audioCodec.Value + ";" : ";"; dlnaparam += audiostreamIndex.HasValue ? audiostreamIndex.Value.ToString(usCulture) + ";" : ";"; @@ -178,6 +181,7 @@ namespace MediaBrowser.Dlna.PlayTo dlnaparam += startPositionTicks.HasValue ? startPositionTicks.Value.ToString(usCulture) + ";" : ";"; dlnaparam += profile + ";"; dlnaparam += videoLevel + ";"; + dlnaparam += mimeType + ";"; return dlnaparam; } |
