浏览代码

fixes #844 - Support remote control commands to change streams with Dlna

Luke Pulverenti 11 年之前
父节点
当前提交
e666fee20d

+ 2 - 0
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;

+ 121 - 20
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; }

+ 3 - 1
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