diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs index fae0742bc0..84c61f4777 100644 --- a/MediaBrowser.Dlna/PlayTo/Device.cs +++ b/MediaBrowser.Dlna/PlayTo/Device.cs @@ -270,6 +270,8 @@ namespace MediaBrowser.Dlna.PlayTo public async Task SetAvTransport(string url, string header, string metaData) { + _logger.Debug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", Properties.Name, url, header); + var command = AvCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetAVTransportURI"); if (command == null) return; diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs index 54045a3d58..fd8b9060eb 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs @@ -279,21 +279,7 @@ namespace MediaBrowser.Dlna.PlayTo case PlaystateCommand.Seek: { - var media = _device.CurrentMediaInfo; - - if (media != null) - { - var info = StreamParams.ParseFromUrl(media.Url, _libraryManager); - - if (info.Item != null && !info.IsDirectStream) - { - var user = _session.UserId.HasValue ? _userManager.GetUserById(_session.UserId.Value) : null; - var newItem = CreatePlaylistItem(info.Item, user, command.SeekPositionTicks ?? 0, GetServerAddress(), info.MediaSourceId, info.AudioStreamIndex, info.SubtitleStreamIndex); - - return _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl); - } - } - return _device.Seek(TimeSpan.FromTicks(command.SeekPositionTicks ?? 0)); + return Seek(command.SeekPositionTicks ?? 0); } case PlaystateCommand.NextTrack: @@ -306,6 +292,33 @@ namespace MediaBrowser.Dlna.PlayTo return Task.FromResult(true); } + private async Task Seek(long newPosition) + { + var media = _device.CurrentMediaInfo; + + if (media != null) + { + var info = StreamParams.ParseFromUrl(media.Url, _libraryManager); + + if (info.Item != null && !info.IsDirectStream) + { + var user = _session.UserId.HasValue ? _userManager.GetUserById(_session.UserId.Value) : null; + var newItem = CreatePlaylistItem(info.Item, user, newPosition, GetServerAddress(), info.MediaSourceId, info.AudioStreamIndex, info.SubtitleStreamIndex); + + await _device.SetStop(); + + await _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl).ConfigureAwait(false); + + if (newItem.StreamInfo.IsDirectStream) + { + await _device.Seek(TimeSpan.FromTicks(newPosition)).ConfigureAwait(false); + } + return; + } + await _device.Seek(TimeSpan.FromTicks(newPosition)).ConfigureAwait(false); + } + } + public Task SendUserDataChangeInfo(UserDataChangeInfo info, CancellationToken cancellationToken) { return Task.FromResult(true); @@ -542,8 +555,6 @@ namespace MediaBrowser.Dlna.PlayTo var dlnaheaders = GetDlnaHeaders(nextTrack); - _logger.Debug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", _device.Properties.Name, nextTrack.StreamUrl, dlnaheaders); - await _device.SetAvTransport(nextTrack.StreamUrl, dlnaheaders, nextTrack.Didl); var streamInfo = nextTrack.StreamInfo; @@ -622,15 +633,51 @@ namespace MediaBrowser.Dlna.PlayTo return _device.Unmute(); case GeneralCommandType.ToggleMute: return _device.ToggleMute(); + case GeneralCommandType.SetAudioStreamIndex: + { + string arg; + + if (command.Arguments.TryGetValue("Index", out arg)) + { + int val; + + if (Int32.TryParse(arg, NumberStyles.Any, _usCulture, out val)) + { + return SetAudioStreamIndex(val); + } + + throw new ArgumentException("Unsupported SetAudioStreamIndex value supplied."); + } + + throw new ArgumentException("SetAudioStreamIndex argument cannot be null"); + } + case GeneralCommandType.SetSubtitleStreamIndex: + { + string arg; + + if (command.Arguments.TryGetValue("Index", out arg)) + { + int val; + + if (Int32.TryParse(arg, NumberStyles.Any, _usCulture, out val)) + { + return SetSubtitleStreamIndex(val); + } + + throw new ArgumentException("Unsupported SetSubtitleStreamIndex value supplied."); + } + + throw new ArgumentException("SetSubtitleStreamIndex argument cannot be null"); + } case GeneralCommandType.SetVolume: { - string volumeArg; + string arg; - if (command.Arguments.TryGetValue("Volume", out volumeArg)) + if (command.Arguments.TryGetValue("Volume", out arg)) { int volume; - if (Int32.TryParse(volumeArg, NumberStyles.Any, _usCulture, out volume)) + if (Int32.TryParse(arg, NumberStyles.Any, _usCulture, out volume)) { return _device.SetVolume(volume); } @@ -648,6 +695,60 @@ namespace MediaBrowser.Dlna.PlayTo return Task.FromResult(true); } + private async Task SetAudioStreamIndex(int? newIndex) + { + var media = _device.CurrentMediaInfo; + + if (media != null) + { + var info = StreamParams.ParseFromUrl(media.Url, _libraryManager); + + if (info.Item != null && !info.IsDirectStream) + { + var newPosition = _device.Position.Ticks; + + var user = _session.UserId.HasValue ? _userManager.GetUserById(_session.UserId.Value) : null; + var newItem = CreatePlaylistItem(info.Item, user, newPosition, GetServerAddress(), info.MediaSourceId, newIndex, info.SubtitleStreamIndex); + + await _device.SetStop(); + + await _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl).ConfigureAwait(false); + + if (newItem.StreamInfo.IsDirectStream) + { + await _device.Seek(TimeSpan.FromTicks(newPosition)).ConfigureAwait(false); + } + } + } + } + + private async Task SetSubtitleStreamIndex(int? newIndex) + { + var media = _device.CurrentMediaInfo; + + if (media != null) + { + var info = StreamParams.ParseFromUrl(media.Url, _libraryManager); + + if (info.Item != null && !info.IsDirectStream) + { + var newPosition = _device.Position.Ticks; + + var user = _session.UserId.HasValue ? _userManager.GetUserById(_session.UserId.Value) : null; + var newItem = CreatePlaylistItem(info.Item, user, newPosition, GetServerAddress(), info.MediaSourceId, info.AudioStreamIndex, newIndex); + + await _device.SetStop(); + + await _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl).ConfigureAwait(false); + + if (newItem.StreamInfo.IsDirectStream) + { + await _device.Seek(TimeSpan.FromTicks(newPosition)).ConfigureAwait(false); + } + } + } + } + private class StreamParams { public string ItemId { get; set; } diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index d4beee8d4e..1a161e9721 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -301,7 +301,9 @@ namespace MediaBrowser.Dlna.PlayTo GeneralCommandType.Mute.ToString(), GeneralCommandType.Unmute.ToString(), GeneralCommandType.ToggleMute.ToString(), - GeneralCommandType.SetVolume.ToString() + GeneralCommandType.SetVolume.ToString(), + GeneralCommandType.SetAudioStreamIndex.ToString(), + GeneralCommandType.SetSubtitleStreamIndex.ToString() }, SupportsMediaControl = true