Browse Source

Merge pull request #1653 from MediaBrowser/beta

Beta
Luke 9 years ago
parent
commit
18dbdb194b
100 changed files with 214 additions and 1515 deletions
  1. 1 2
      Emby.Drawing/Common/ImageHeader.cs
  2. 1 2
      Emby.Drawing/GDI/DynamicImageHelpers.cs
  3. 0 1
      Emby.Drawing/ImageMagick/PlayedIndicatorDrawer.cs
  4. 6 7
      Emby.Drawing/ImageMagick/StripCollageBuilder.cs
  5. 0 1
      Emby.Drawing/ImageMagick/UnplayedCountIndicator.cs
  6. 0 1
      Emby.Drawing/ImageProcessor.cs
  7. 0 1
      Emby.Drawing/Properties/AssemblyInfo.cs
  8. 1 2
      MediaBrowser.Api/ApiEntryPoint.cs
  9. 0 1
      MediaBrowser.Api/BaseApiService.cs
  10. 1 3
      MediaBrowser.Api/ConfigurationService.cs
  11. 0 1
      MediaBrowser.Api/DisplayPreferencesService.cs
  12. 0 1
      MediaBrowser.Api/Images/ImageByNameService.cs
  13. 0 1
      MediaBrowser.Api/Images/RemoteImageService.cs
  14. 10 6
      MediaBrowser.Api/ItemLookupService.cs
  15. 0 1
      MediaBrowser.Api/ItemRefreshService.cs
  16. 1 1
      MediaBrowser.Api/ItemUpdateService.cs
  17. 1 2
      MediaBrowser.Api/Library/LibraryHelpers.cs
  18. 0 4
      MediaBrowser.Api/Library/LibraryService.cs
  19. 1 2
      MediaBrowser.Api/Library/LibraryStructureService.cs
  20. 15 1
      MediaBrowser.Api/LiveTv/LiveTvService.cs
  21. 0 2
      MediaBrowser.Api/MediaBrowser.Api.csproj
  22. 0 3
      MediaBrowser.Api/Movies/MoviesService.cs
  23. 0 8
      MediaBrowser.Api/Movies/TrailersService.cs
  24. 0 1
      MediaBrowser.Api/Music/AlbumsService.cs
  25. 39 37
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  26. 0 224
      MediaBrowser.Api/Playback/Dash/ManifestBuilder.cs
  27. 0 548
      MediaBrowser.Api/Playback/Dash/MpegDashService.cs
  28. 23 41
      MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
  29. 28 10
      MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
  30. 0 19
      MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
  31. 3 15
      MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
  32. 19 2
      MediaBrowser.Api/Playback/MediaInfoService.cs
  33. 1 3
      MediaBrowser.Api/Playback/Progressive/AudioService.cs
  34. 1 3
      MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
  35. 1 2
      MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
  36. 1 5
      MediaBrowser.Api/Playback/Progressive/VideoService.cs
  37. 3 4
      MediaBrowser.Api/Playback/StreamRequest.cs
  38. 1 14
      MediaBrowser.Api/Playback/StreamState.cs
  39. 0 1
      MediaBrowser.Api/PluginService.cs
  40. 0 3
      MediaBrowser.Api/Reports/Activities/ReportActivitiesBuilder.cs
  41. 0 4
      MediaBrowser.Api/Reports/Common/HeaderActivitiesMetadata.cs
  42. 0 4
      MediaBrowser.Api/Reports/Common/HeaderMetadata.cs
  43. 0 4
      MediaBrowser.Api/Reports/Common/ItemViewType.cs
  44. 1 4
      MediaBrowser.Api/Reports/Common/ReportBuilderBase.cs
  45. 0 4
      MediaBrowser.Api/Reports/Common/ReportDisplayType.cs
  46. 0 4
      MediaBrowser.Api/Reports/Common/ReportExportType.cs
  47. 0 4
      MediaBrowser.Api/Reports/Common/ReportFieldType.cs
  48. 0 4
      MediaBrowser.Api/Reports/Common/ReportHeaderIdType.cs
  49. 0 4
      MediaBrowser.Api/Reports/Common/ReportIncludeItemTypes.cs
  50. 0 4
      MediaBrowser.Api/Reports/Common/ReportViewType.cs
  51. 3 12
      MediaBrowser.Api/Reports/Data/ReportBuilder.cs
  52. 1 4
      MediaBrowser.Api/Reports/Data/ReportExport.cs
  53. 1 6
      MediaBrowser.Api/Reports/Data/ReportOptions.cs
  54. 1 5
      MediaBrowser.Api/Reports/Model/ReportGroup.cs
  55. 1 8
      MediaBrowser.Api/Reports/Model/ReportHeader.cs
  56. 1 7
      MediaBrowser.Api/Reports/Model/ReportItem.cs
  57. 1 5
      MediaBrowser.Api/Reports/Model/ReportRow.cs
  58. 0 3
      MediaBrowser.Api/Reports/ReportRequests.cs
  59. 1 12
      MediaBrowser.Api/Reports/ReportsService.cs
  60. 0 3
      MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs
  61. 1 5
      MediaBrowser.Api/Reports/Stat/ReportStatGroup.cs
  62. 1 7
      MediaBrowser.Api/Reports/Stat/ReportStatItem.cs
  63. 1 5
      MediaBrowser.Api/Reports/Stat/ReportStatResult.cs
  64. 1 2
      MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
  65. 0 2
      MediaBrowser.Api/SearchService.cs
  66. 0 1
      MediaBrowser.Api/Subtitles/SubtitleService.cs
  67. 1 2
      MediaBrowser.Api/System/SystemInfoWebSocketListener.cs
  68. 0 2
      MediaBrowser.Api/System/SystemService.cs
  69. 21 3
      MediaBrowser.Api/TvShowsService.cs
  70. 2 3
      MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
  71. 0 1
      MediaBrowser.Api/UserLibrary/GameGenresService.cs
  72. 0 2
      MediaBrowser.Api/UserLibrary/ItemsService.cs
  73. 0 2
      MediaBrowser.Api/UserLibrary/MusicGenresService.cs
  74. 1 1
      MediaBrowser.Api/UserLibrary/PlaystateService.cs
  75. 0 2
      MediaBrowser.Api/UserLibrary/StudiosService.cs
  76. 0 2
      MediaBrowser.Api/UserLibrary/YearsService.cs
  77. 0 1
      MediaBrowser.Api/UserService.cs
  78. 1 2
      MediaBrowser.Api/VideosService.cs
  79. 0 2
      MediaBrowser.Common.Implementations/Archiving/ZipClient.cs
  80. 2 3
      MediaBrowser.Common.Implementations/BaseApplicationHost.cs
  81. 0 1
      MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs
  82. 0 1
      MediaBrowser.Common.Implementations/Devices/DeviceId.cs
  83. 0 1
      MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
  84. 0 1
      MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
  85. 1 3
      MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
  86. 2 2
      MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs
  87. 2 2
      MediaBrowser.Common.Implementations/Security/MbAdmin.cs
  88. 3 3
      MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
  89. 1 2
      MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs
  90. 0 1
      MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
  91. 0 2
      MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs
  92. 2 3
      MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
  93. 1 1
      MediaBrowser.Common/IO/ProgressStream.cs
  94. 0 1
      MediaBrowser.Common/Security/ISecurityManager.cs
  95. 1 1
      MediaBrowser.Controller/Channels/Channel.cs
  96. 0 102
      MediaBrowser.Controller/Channels/ChannelAudioItem.cs
  97. 0 90
      MediaBrowser.Controller/Channels/ChannelFolderItem.cs
  98. 0 128
      MediaBrowser.Controller/Channels/ChannelVideoItem.cs
  99. 0 11
      MediaBrowser.Controller/Channels/IChannelItem.cs
  100. 0 18
      MediaBrowser.Controller/Channels/IChannelMediaItem.cs

+ 1 - 2
Emby.Drawing/Common/ImageHeader.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.Drawing;
+using MediaBrowser.Model.Drawing;
 using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;

+ 1 - 2
Emby.Drawing/GDI/DynamicImageHelpers.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.IO;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Drawing;
 using System.Drawing.Drawing2D;
 using System.Drawing.Imaging;

+ 0 - 1
Emby.Drawing/ImageMagick/PlayedIndicatorDrawer.cs

@@ -6,7 +6,6 @@ using System;
 using System.IO;
 using System.Threading.Tasks;
 using CommonIO;
-using MediaBrowser.Common.IO;
 
 namespace Emby.Drawing.ImageMagick
 {

+ 6 - 7
Emby.Drawing/ImageMagick/StripCollageBuilder.cs

@@ -3,7 +3,6 @@ using MediaBrowser.Common.Configuration;
 using System;
 using System.Collections.Generic;
 using CommonIO;
-using MediaBrowser.Common.IO;
 
 namespace Emby.Drawing.ImageMagick
 {
@@ -296,9 +295,9 @@ namespace Emby.Drawing.ImageMagick
                 wand.OpenImage("gradient:#111111-#111111");
                 using (var draw = new DrawingWand())
                 {
-                    var iSlice = Convert.ToInt32(width * .1166666667 * 2);
+                    var iSlice = Convert.ToInt32(width * 0.24125);
                     int iTrans = Convert.ToInt32(height * .25);
-                    int iHeight = Convert.ToInt32(height * .62);
+                    int iHeight = Convert.ToInt32(height * .70);
                     var horizontalImagePadding = Convert.ToInt32(width * 0.0125);
 
                     foreach (var element in wandImages.ImageList)
@@ -340,7 +339,7 @@ namespace Emby.Drawing.ImageMagick
 
                                         wandList.AddImage(mwr);
                                         int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
-                                        wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * .085));
+                                        wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * .045));
                                     }
                                 }
                             }
@@ -361,9 +360,9 @@ namespace Emby.Drawing.ImageMagick
                 wand.OpenImage("gradient:#111111-#111111");
                 using (var draw = new DrawingWand())
                 {
-                    var iSlice = Convert.ToInt32(width * .3);
+                    var iSlice = Convert.ToInt32(width * .32);
                     int iTrans = Convert.ToInt32(height * .25);
-                    int iHeight = Convert.ToInt32(height * .63);
+                    int iHeight = Convert.ToInt32(height * .68);
                     var horizontalImagePadding = Convert.ToInt32(width * 0.02);
 
                     foreach (var element in wandImages.ImageList)
@@ -405,7 +404,7 @@ namespace Emby.Drawing.ImageMagick
 
                                         wandList.AddImage(mwr);
                                         int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
-                                        wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * .07));
+                                        wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * .03));
                                     }
                                 }
                             }

+ 0 - 1
Emby.Drawing/ImageMagick/UnplayedCountIndicator.cs

@@ -1,6 +1,5 @@
 using ImageMagickSharp;
 using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Model.Drawing;
 using System.Globalization;
 using CommonIO;

+ 0 - 1
Emby.Drawing/ImageProcessor.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Entities;

+ 0 - 1
Emby.Drawing/Properties/AssemblyInfo.cs

@@ -1,5 +1,4 @@
 using System.Reflection;
-using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 // General Information about an assembly is controlled through the following 

+ 1 - 2
MediaBrowser.Api/ApiEntryPoint.cs

@@ -1,6 +1,5 @@
 using MediaBrowser.Api.Playback;
 using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Plugins;
@@ -350,7 +349,7 @@ namespace MediaBrowser.Api
 
             if (job.Type != TranscodingJobType.Progressive)
             {
-                timerDuration = 1800000;
+                timerDuration = 60000;
             }
 
             job.PingTimeout = timerDuration;

+ 0 - 1
MediaBrowser.Api/BaseApiService.cs

@@ -9,7 +9,6 @@ using MediaBrowser.Model.Logging;
 using ServiceStack.Text.Controller;
 using ServiceStack.Web;
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 

+ 1 - 3
MediaBrowser.Api/ConfigurationService.cs

@@ -1,6 +1,4 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Providers;

+ 0 - 1
MediaBrowser.Api/DisplayPreferencesService.cs

@@ -3,7 +3,6 @@ using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Serialization;
 using ServiceStack;
-using System;
 using System.Threading;
 using System.Threading.Tasks;
 

+ 0 - 1
MediaBrowser.Api/Images/ImageByNameService.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Net;

+ 0 - 1
MediaBrowser.Api/Images/RemoteImageService.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Dto;

+ 10 - 6
MediaBrowser.Api/ItemLookupService.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
@@ -203,14 +202,19 @@ namespace MediaBrowser.Api
             //    }
             //}
             Logger.Info("Setting provider id's to item {0}-{1}: {2}", item.Id, item.Name, _json.SerializeToString(request.ProviderIds));
+
+            // Since the refresh process won't erase provider Ids, we need to set this explicitly now.
             item.ProviderIds = request.ProviderIds;
+            //item.ProductionYear = request.ProductionYear;
+            //item.Name = request.Name;
 
-			var task = _providerManager.RefreshFullItem(item, new MetadataRefreshOptions(_fileSystem)
+            var task = _providerManager.RefreshFullItem(item, new MetadataRefreshOptions(_fileSystem)
             {
                 MetadataRefreshMode = MetadataRefreshMode.FullRefresh,
                 ImageRefreshMode = ImageRefreshMode.FullRefresh,
                 ReplaceAllMetadata = true,
-                ReplaceAllImages = request.ReplaceAllImages
+                ReplaceAllImages = request.ReplaceAllImages,
+                SearchResult = request
 
             }, CancellationToken.None);
             Task.WaitAll(task);
@@ -235,7 +239,7 @@ namespace MediaBrowser.Api
                     contentPath = await reader.ReadToEndAsync().ConfigureAwait(false);
                 }
 
-				if (_fileSystem.FileExists(contentPath))
+                if (_fileSystem.FileExists(contentPath))
                 {
                     return ToStaticFileResult(contentPath);
                 }
@@ -276,7 +280,7 @@ namespace MediaBrowser.Api
 
             var fullCachePath = GetFullCachePath(urlHash + "." + ext);
 
-			_fileSystem.CreateDirectory(Path.GetDirectoryName(fullCachePath));
+            _fileSystem.CreateDirectory(Path.GetDirectoryName(fullCachePath));
             using (var stream = result.Content)
             {
                 using (var filestream = _fileSystem.GetFileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, true))
@@ -285,7 +289,7 @@ namespace MediaBrowser.Api
                 }
             }
 
-			_fileSystem.CreateDirectory(Path.GetDirectoryName(pointerCachePath));
+            _fileSystem.CreateDirectory(Path.GetDirectoryName(pointerCachePath));
             using (var writer = new StreamWriter(pointerCachePath))
             {
                 await writer.WriteAsync(fullCachePath).ConfigureAwait(false);

+ 0 - 1
MediaBrowser.Api/ItemRefreshService.cs

@@ -5,7 +5,6 @@ using MediaBrowser.Controller.Providers;
 using ServiceStack;
 using System.Threading;
 using CommonIO;
-using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Api
 {

+ 1 - 1
MediaBrowser.Api/ItemUpdateService.cs

@@ -331,7 +331,7 @@ namespace MediaBrowser.Api
                 hasAspectRatio.AspectRatio = request.AspectRatio;
             }
 
-            item.IsLocked = (request.LockData ?? false);
+            item.IsLocked = request.LockData ?? false;
 
             if (request.LockedFields != null)
             {

+ 1 - 2
MediaBrowser.Api/Library/LibraryHelpers.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller;
+using MediaBrowser.Controller;
 using System;
 using System.IO;
 using System.Linq;

+ 0 - 4
MediaBrowser.Api/Library/LibraryService.cs

@@ -1,7 +1,6 @@
 using MediaBrowser.Api.Movies;
 using MediaBrowser.Api.Music;
 using MediaBrowser.Controller.Activity;
-using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
@@ -14,13 +13,11 @@ using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.TV;
 using MediaBrowser.Model.Activity;
-using MediaBrowser.Model.Channels;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
 using ServiceStack;
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
@@ -28,7 +25,6 @@ using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
-using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Api.Library
 {

+ 1 - 2
MediaBrowser.Api/Library/LibraryStructureService.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller;
+using MediaBrowser.Controller;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Entities;

+ 15 - 1
MediaBrowser.Api/LiveTv/LiveTvService.cs

@@ -482,7 +482,14 @@ namespace MediaBrowser.Api.LiveTv
     [Authenticated(AllowBeforeStartupWizard = true)]
     public class GetSatIniMappings : IReturn<List<NameValuePair>>
     {
-        
+
+    }
+
+    [Route("/LiveTv/TunerHosts/Satip/ChannelScan", "GET", Summary = "Scans for available channels")]
+    [Authenticated(AllowBeforeStartupWizard = true)]
+    public class GetSatChannnelScanResult : TunerHostInfo
+    {
+
     }
 
     public class LiveTvService : BaseApiService
@@ -504,6 +511,13 @@ namespace MediaBrowser.Api.LiveTv
             _dtoService = dtoService;
         }
 
+        public async Task<object> Get(GetSatChannnelScanResult request)
+        {
+            var result = await _liveTvManager.GetSatChannelScanResult(request, CancellationToken.None).ConfigureAwait(false);
+
+            return ToOptimizedResult(result);
+        }
+
         public async Task<object> Get(GetLiveTvRegistrationInfo request)
         {
             var result = await _liveTvManager.GetRegistrationInfo(request.ChannelId, request.ProgramId, request.Feature).ConfigureAwait(false);

+ 0 - 2
MediaBrowser.Api/MediaBrowser.Api.csproj

@@ -80,8 +80,6 @@
     <Compile Include="FilterService.cs" />
     <Compile Include="IHasDtoOptions.cs" />
     <Compile Include="Library\ChapterService.cs" />
-    <Compile Include="Playback\Dash\ManifestBuilder.cs" />
-    <Compile Include="Playback\Dash\MpegDashService.cs" />
     <Compile Include="Playback\MediaInfoService.cs" />
     <Compile Include="Playback\TranscodingThrottler.cs" />
     <Compile Include="PlaylistService.cs" />

+ 0 - 3
MediaBrowser.Api/Movies/MoviesService.cs

@@ -1,12 +1,10 @@
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Channels;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
@@ -15,7 +13,6 @@ using ServiceStack;
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Threading;
 using System.Threading.Tasks;
 
 namespace MediaBrowser.Api.Movies

+ 0 - 8
MediaBrowser.Api/Movies/TrailersService.cs

@@ -1,17 +1,9 @@
 using MediaBrowser.Api.UserLibrary;
-using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Channels;
-using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
 using ServiceStack;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
 using MediaBrowser.Controller.Collections;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Model.Serialization;

+ 0 - 1
MediaBrowser.Api/Music/AlbumsService.cs

@@ -4,7 +4,6 @@ using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Querying;
 using ServiceStack;
 using System;
 using System.Collections.Generic;

+ 39 - 37
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -1,12 +1,10 @@
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
@@ -290,11 +288,9 @@ namespace MediaBrowser.Api.Playback
         {
             if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
             {
-                // It's currently failing on live tv
-                if (state.RunTimeTicks.HasValue)
-                {
+                
                     return "h264_qsv";
-                }
+               
             }
 
             return "libx264";
@@ -442,6 +438,8 @@ namespace MediaBrowser.Api.Playback
                             param += " -level " + state.VideoRequest.Level;
                             break;
                     }
+
+                    return param;
                 }
                 else
                 {
@@ -616,7 +614,7 @@ namespace MediaBrowser.Api.Playback
 
                 if (!string.IsNullOrEmpty(state.SubtitleStream.Language))
                 {
-                    var charenc = SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath, state.MediaSource.Protocol, CancellationToken.None).Result;
+                    var charenc = SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath, state.SubtitleStream.Language, state.MediaSource.Protocol, CancellationToken.None).Result;
 
                     if (!string.IsNullOrEmpty(charenc))
                     {
@@ -997,7 +995,17 @@ namespace MediaBrowser.Api.Playback
             var commandLineLogMessage = process.StartInfo.FileName + " " + process.StartInfo.Arguments;
             Logger.Info(commandLineLogMessage);
 
-            var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, "transcode-" + Guid.NewGuid() + ".txt");
+            var logFilePrefix = "transcode";
+            if (state.VideoRequest != null && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase))
+            {
+                logFilePrefix = "directstream";
+            }
+            else if (state.VideoRequest != null && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
+            {
+                logFilePrefix = "remux";
+            }
+
+            var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, logFilePrefix + "-" + Guid.NewGuid() + ".txt");
             FileSystem.CreateDirectory(Path.GetDirectoryName(logFilePath));
 
             // FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
@@ -1028,7 +1036,7 @@ namespace MediaBrowser.Api.Playback
             StartStreamingLog(transcodingJob, state, process.StandardError.BaseStream, state.LogFileStream);
 
             // Wait for the file to exist before proceeeding
-			while (!FileSystem.FileExists(state.WaitForPath ?? outputPath) && !transcodingJob.HasExited)
+            while (!FileSystem.FileExists(state.WaitForPath ?? outputPath) && !transcodingJob.HasExited)
             {
                 await Task.Delay(100, cancellationTokenSource.Token).ConfigureAwait(false);
             }
@@ -1454,10 +1462,7 @@ namespace MediaBrowser.Api.Playback
                 }
                 else if (i == 19)
                 {
-                    if (videoRequest != null)
-                    {
-                        videoRequest.Cabac = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
-                    }
+                    // cabac no longer used
                 }
                 else if (i == 20)
                 {
@@ -1548,7 +1553,7 @@ namespace MediaBrowser.Api.Playback
                 double digit;
                 if (double.TryParse(time, NumberStyles.Any, UsCulture, out digit))
                 {
-                    secondsSum += (digit * timeFactor);
+                    secondsSum += digit * timeFactor;
                 }
                 else
                 {
@@ -1656,9 +1661,9 @@ namespace MediaBrowser.Api.Playback
                 if (state.OutputVideoBitrate.HasValue)
                 {
                     var resolution = ResolutionNormalizer.Normalize(
-						state.VideoStream == null ? (int?)null : state.VideoStream.BitRate,
-						state.OutputVideoBitrate.Value,
-						state.VideoStream == null ? null : state.VideoStream.Codec,
+                        state.VideoStream == null ? (int?)null : state.VideoStream.BitRate,
+                        state.OutputVideoBitrate.Value,
+                        state.VideoStream == null ? null : state.VideoStream.Codec,
                         state.OutputVideoCodec,
                         videoRequest.MaxWidth,
                         videoRequest.MaxHeight);
@@ -1682,12 +1687,12 @@ namespace MediaBrowser.Api.Playback
 
         private void TryStreamCopy(StreamState state, VideoStreamRequest videoRequest)
         {
-            if (state.VideoStream != null && CanStreamCopyVideo(videoRequest, state.VideoStream))
+            if (state.VideoStream != null && CanStreamCopyVideo(state))
             {
                 state.OutputVideoCodec = "copy";
             }
 
-            if (state.AudioStream != null && CanStreamCopyAudio(videoRequest, state.AudioStream, state.SupportedAudioCodecs))
+            if (state.AudioStream != null && CanStreamCopyAudio(state, state.SupportedAudioCodecs))
             {
                 state.OutputAudioCodec = "copy";
             }
@@ -1775,8 +1780,11 @@ namespace MediaBrowser.Api.Playback
             state.MediaSource = mediaSource;
         }
 
-        protected virtual bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream)
+        protected virtual bool CanStreamCopyVideo(StreamState state)
         {
+            var request = state.VideoRequest;
+            var videoStream = state.VideoStream;
+
             if (videoStream.IsInterlaced)
             {
                 return false;
@@ -1786,7 +1794,7 @@ namespace MediaBrowser.Api.Playback
             {
                 return false;
             }
-            
+
             // Can't stream copy if we're burning in subtitles
             if (request.SubtitleStreamIndex.HasValue)
             {
@@ -1807,10 +1815,10 @@ namespace MediaBrowser.Api.Playback
             {
                 if (string.IsNullOrEmpty(videoStream.Profile))
                 {
-                    return false;
+                    //return false;
                 }
 
-                if (!string.Equals(request.Profile, videoStream.Profile, StringComparison.OrdinalIgnoreCase))
+                if (!string.IsNullOrEmpty(videoStream.Profile) && !string.Equals(request.Profile, videoStream.Profile, StringComparison.OrdinalIgnoreCase))
                 {
                     var currentScore = GetVideoProfileScore(videoStream.Profile);
                     var requestedScore = GetVideoProfileScore(request.Profile);
@@ -1886,24 +1894,16 @@ namespace MediaBrowser.Api.Playback
                 {
                     if (!videoStream.Level.HasValue)
                     {
-                        return false;
+                        //return false;
                     }
 
-                    if (videoStream.Level.Value > requestLevel)
+                    if (videoStream.Level.HasValue && videoStream.Level.Value > requestLevel)
                     {
                         return false;
                     }
                 }
             }
 
-            if (request.Cabac.HasValue && request.Cabac.Value)
-            {
-                if (videoStream.IsCabac.HasValue && !videoStream.IsCabac.Value)
-                {
-                    return false;
-                }
-            }
-
             return request.EnableAutoStreamCopy;
         }
 
@@ -1923,8 +1923,11 @@ namespace MediaBrowser.Api.Playback
             return Array.FindIndex(list.ToArray(), t => string.Equals(t, profile, StringComparison.OrdinalIgnoreCase));
         }
 
-        protected virtual bool CanStreamCopyAudio(VideoStreamRequest request, MediaStream audioStream, List<string> supportedAudioCodecs)
+        protected virtual bool CanStreamCopyAudio(StreamState state, List<string> supportedAudioCodecs)
         {
+            var request = state.VideoRequest;
+            var audioStream = state.AudioStream;
+
             // Source and target codecs must match
             if (string.IsNullOrEmpty(audioStream.Codec) || !supportedAudioCodecs.Contains(audioStream.Codec, StringComparer.OrdinalIgnoreCase))
             {
@@ -2030,7 +2033,6 @@ namespace MediaBrowser.Api.Playback
                 state.TargetPacketLength,
                 state.TargetTimestamp,
                 state.IsTargetAnamorphic,
-                state.IsTargetCabac,
                 state.TargetRefFrames,
                 state.TargetVideoStreamCount,
                 state.TargetAudioStreamCount,
@@ -2056,6 +2058,7 @@ namespace MediaBrowser.Api.Playback
                     if (state.VideoRequest != null)
                     {
                         state.VideoRequest.CopyTimestamps = transcodingProfile.CopyTimestamps;
+                        state.VideoRequest.ForceLiveStream = transcodingProfile.ForceLiveStream;
                     }
                 }
             }
@@ -2133,7 +2136,6 @@ namespace MediaBrowser.Api.Playback
                     state.TargetPacketLength,
                     state.TranscodeSeekInfo,
                     state.IsTargetAnamorphic,
-                    state.IsTargetCabac,
                     state.TargetRefFrames,
                     state.TargetVideoStreamCount,
                     state.TargetAudioStreamCount,
@@ -2225,7 +2227,7 @@ namespace MediaBrowser.Api.Playback
                     inputModifier += " -noaccurate_seek";
                 }
             }
-            
+
             return inputModifier;
         }
 

+ 0 - 224
MediaBrowser.Api/Playback/Dash/ManifestBuilder.cs

@@ -1,224 +0,0 @@
-using System;
-using System.Globalization;
-using System.Security;
-using System.Text;
-
-namespace MediaBrowser.Api.Playback.Dash
-{
-    public class ManifestBuilder
-    {
-        protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
-        public string GetManifestText(StreamState state, string playlistUrl)
-        {
-            var builder = new StringBuilder();
-
-            var time = TimeSpan.FromTicks(state.RunTimeTicks.Value);
-
-            var duration = "PT" + time.Hours.ToString("00", UsCulture) + "H" + time.Minutes.ToString("00", UsCulture) + "M" + time.Seconds.ToString("00", UsCulture) + ".00S";
-
-            builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-
-            builder.AppendFormat(
-                "<MPD xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mpeg:dash:schema:mpd:2011\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" type=\"static\" mediaPresentationDuration=\"{0}\" minBufferTime=\"PT5.0S\">",
-                duration);
-
-            builder.Append("<ProgramInformation>");
-            builder.Append("</ProgramInformation>");
-
-            builder.Append("<Period start=\"PT0S\">");
-            builder.Append(GetVideoAdaptationSet(state, playlistUrl));
-            builder.Append(GetAudioAdaptationSet(state, playlistUrl));
-            builder.Append("</Period>");
-
-            builder.Append("</MPD>");
-
-            return builder.ToString();
-        }
-
-        private string GetVideoAdaptationSet(StreamState state, string playlistUrl)
-        {
-            var builder = new StringBuilder();
-
-            builder.Append("<AdaptationSet id=\"video\" segmentAlignment=\"true\" bitstreamSwitching=\"true\">");
-            builder.Append(GetVideoRepresentationOpenElement(state));
-
-            AppendSegmentList(state, builder, "0", playlistUrl);
-
-            builder.Append("</Representation>");
-            builder.Append("</AdaptationSet>");
-
-            return builder.ToString();
-        }
-
-        private string GetAudioAdaptationSet(StreamState state, string playlistUrl)
-        {
-            var builder = new StringBuilder();
-
-            builder.Append("<AdaptationSet id=\"audio\" segmentAlignment=\"true\" bitstreamSwitching=\"true\">");
-            builder.Append(GetAudioRepresentationOpenElement(state));
-
-            builder.Append("<AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"6\" />");
-
-            AppendSegmentList(state, builder, "1", playlistUrl);
-
-            builder.Append("</Representation>");
-            builder.Append("</AdaptationSet>");
-
-            return builder.ToString();
-        }
-
-        private string GetVideoRepresentationOpenElement(StreamState state)
-        {
-            var codecs = GetVideoCodecDescriptor(state);
-
-            var mime = "video/mp4";
-
-            var xml = "<Representation id=\"0\" mimeType=\"" + mime + "\" codecs=\"" + codecs + "\"";
-
-            if (state.OutputWidth.HasValue)
-            {
-                xml += " width=\"" + state.OutputWidth.Value.ToString(UsCulture) + "\"";
-            }
-            if (state.OutputHeight.HasValue)
-            {
-                xml += " height=\"" + state.OutputHeight.Value.ToString(UsCulture) + "\"";
-            }
-            if (state.OutputVideoBitrate.HasValue)
-            {
-                xml += " bandwidth=\"" + state.OutputVideoBitrate.Value.ToString(UsCulture) + "\"";
-            }
-
-            xml += ">";
-
-            return xml;
-        }
-
-        private string GetAudioRepresentationOpenElement(StreamState state)
-        {
-            var codecs = GetAudioCodecDescriptor(state);
-
-            var mime = "audio/mp4";
-
-            var xml = "<Representation id=\"1\" mimeType=\"" + mime + "\" codecs=\"" + codecs + "\"";
-
-            if (state.OutputAudioSampleRate.HasValue)
-            {
-                xml += " audioSamplingRate=\"" + state.OutputAudioSampleRate.Value.ToString(UsCulture) + "\"";
-            }
-            if (state.OutputAudioBitrate.HasValue)
-            {
-                xml += " bandwidth=\"" + state.OutputAudioBitrate.Value.ToString(UsCulture) + "\"";
-            }
-
-            xml += ">";
-
-            return xml;
-        }
-
-        private string GetVideoCodecDescriptor(StreamState state)
-        {
-            // https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html
-            // http://www.chipwreck.de/blog/2010/02/25/html-5-video-tag-and-attributes/
-
-            var level = state.TargetVideoLevel ?? 0;
-            var profile = state.TargetVideoProfile ?? string.Empty;
-
-            if (profile.IndexOf("high", StringComparison.OrdinalIgnoreCase) != -1)
-            {
-                if (level >= 4.1)
-                {
-                    return "avc1.640028";
-                }
-
-                if (level >= 4)
-                {
-                    return "avc1.640028";
-                }
-
-                return "avc1.64001f";
-            }
-
-            if (profile.IndexOf("main", StringComparison.OrdinalIgnoreCase) != -1)
-            {
-                if (level >= 4)
-                {
-                    return "avc1.4d0028";
-                }
-
-                if (level >= 3.1)
-                {
-                    return "avc1.4d001f";
-                }
-
-                return "avc1.4d001e";
-            }
-
-            if (level >= 3.1)
-            {
-                return "avc1.42001f";
-            }
-
-            return "avc1.42E01E";
-        }
-
-        private string GetAudioCodecDescriptor(StreamState state)
-        {
-            // https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html
-
-            if (string.Equals(state.OutputAudioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
-            {
-                return "mp4a.40.34";
-            }
-
-            // AAC 5ch
-            if (state.OutputAudioChannels.HasValue && state.OutputAudioChannels.Value >= 5)
-            {
-                return "mp4a.40.5";
-            }
-
-            // AAC 2ch
-            return "mp4a.40.2";
-        }
-
-        private void AppendSegmentList(StreamState state, StringBuilder builder, string type, string playlistUrl)
-        {
-            var extension = ".m4s";
-
-            var seconds = TimeSpan.FromTicks(state.RunTimeTicks ?? 0).TotalSeconds;
-
-            var queryStringIndex = playlistUrl.IndexOf('?');
-            var queryString = queryStringIndex == -1 ? string.Empty : playlistUrl.Substring(queryStringIndex);
-
-            var index = 0;
-            var duration = 1000000 * state.SegmentLength;
-            builder.AppendFormat("<SegmentList timescale=\"1000000\" duration=\"{0}\" startNumber=\"1\">", duration.ToString(CultureInfo.InvariantCulture));
-
-            while (seconds > 0)
-            {
-                var filename = index == 0
-                    ? "init"
-                    : (index - 1).ToString(UsCulture);
-
-                var segmentUrl = string.Format("dash/{3}/{0}{1}{2}",
-                    filename,
-                    extension,
-                    SecurityElement.Escape(queryString),
-                    type);
-
-                if (index == 0)
-                {
-                    builder.AppendFormat("<Initialization sourceURL=\"{0}\"/>", segmentUrl);
-                }
-                else
-                {
-                    builder.AppendFormat("<SegmentURL media=\"{0}\"/>", segmentUrl);
-                }
-
-                seconds -= state.SegmentLength;
-                index++;
-            }
-            builder.Append("</SegmentList>");
-        }
-    }
-}

+ 0 - 548
MediaBrowser.Api/Playback/Dash/MpegDashService.cs

@@ -1,548 +0,0 @@
-using MediaBrowser.Api.Playback.Hls;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Devices;
-using MediaBrowser.Controller.Dlna;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Serialization;
-using ServiceStack;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using CommonIO;
-using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
-
-namespace MediaBrowser.Api.Playback.Dash
-{
-    /// <summary>
-    /// Options is needed for chromecast. Threw Head in there since it's related
-    /// </summary>
-    [Route("/Videos/{Id}/master.mpd", "GET", Summary = "Gets a video stream using Mpeg dash.")]
-    [Route("/Videos/{Id}/master.mpd", "HEAD", Summary = "Gets a video stream using Mpeg dash.")]
-    public class GetMasterManifest : VideoStreamRequest
-    {
-        public bool EnableAdaptiveBitrateStreaming { get; set; }
-
-        public GetMasterManifest()
-        {
-            EnableAdaptiveBitrateStreaming = true;
-        }
-    }
-
-    [Route("/Videos/{Id}/dash/{RepresentationId}/{SegmentId}.m4s", "GET")]
-    public class GetDashSegment : VideoStreamRequest
-    {
-        /// <summary>
-        /// Gets or sets the segment id.
-        /// </summary>
-        /// <value>The segment id.</value>
-        public string SegmentId { get; set; }
-
-        /// <summary>
-        /// Gets or sets the representation identifier.
-        /// </summary>
-        /// <value>The representation identifier.</value>
-        public string RepresentationId { get; set; }
-    }
-
-    public class MpegDashService : BaseHlsService
-    {
-        public MpegDashService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer)
-        {
-            NetworkManager = networkManager;
-        }
-
-        protected INetworkManager NetworkManager { get; private set; }
-
-        public object Get(GetMasterManifest request)
-        {
-            var result = GetAsync(request, "GET").Result;
-
-            return result;
-        }
-
-        public object Head(GetMasterManifest request)
-        {
-            var result = GetAsync(request, "HEAD").Result;
-
-            return result;
-        }
-
-        protected override bool EnableOutputInSubFolder
-        {
-            get
-            {
-                return true;
-            }
-        }
-
-        private async Task<object> GetAsync(GetMasterManifest request, string method)
-        {
-            if (string.IsNullOrEmpty(request.MediaSourceId))
-            {
-                throw new ArgumentException("MediaSourceId is required");
-            }
-
-            var state = await GetState(request, CancellationToken.None).ConfigureAwait(false);
-
-            var playlistText = string.Empty;
-
-            if (string.Equals(method, "GET", StringComparison.OrdinalIgnoreCase))
-            {
-                playlistText = new ManifestBuilder().GetManifestText(state, Request.RawUrl);
-            }
-
-            return ResultFactory.GetResult(playlistText, MimeTypes.GetMimeType("playlist.mpd"), new Dictionary<string, string>());
-        }
-
-        public object Get(GetDashSegment request)
-        {
-            return GetDynamicSegment(request, request.SegmentId, request.RepresentationId).Result;
-        }
-
-        private async Task<object> GetDynamicSegment(VideoStreamRequest request, string segmentId, string representationId)
-        {
-            if ((request.StartTimeTicks ?? 0) > 0)
-            {
-                throw new ArgumentException("StartTimeTicks is not allowed.");
-            }
-
-            var cancellationTokenSource = new CancellationTokenSource();
-            var cancellationToken = cancellationTokenSource.Token;
-
-            var requestedIndex = string.Equals(segmentId, "init", StringComparison.OrdinalIgnoreCase) ?
-                -1 :
-                int.Parse(segmentId, NumberStyles.Integer, UsCulture);
-
-            var state = await GetState(request, cancellationToken).ConfigureAwait(false);
-
-            var playlistPath = Path.ChangeExtension(state.OutputFilePath, ".mpd");
-
-            var segmentExtension = GetSegmentFileExtension(state);
-
-            var segmentPath = FindSegment(playlistPath, representationId, segmentExtension, requestedIndex);
-            var segmentLength = state.SegmentLength;
-
-            TranscodingJob job = null;
-
-            if (!string.IsNullOrWhiteSpace(segmentPath))
-            {
-                job = ApiEntryPoint.Instance.GetTranscodingJob(playlistPath, TranscodingJobType);
-                return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job, cancellationToken).ConfigureAwait(false);
-            }
-
-            await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
-            try
-            {
-                segmentPath = FindSegment(playlistPath, representationId, segmentExtension, requestedIndex);
-                if (!string.IsNullOrWhiteSpace(segmentPath))
-                {
-                    job = ApiEntryPoint.Instance.GetTranscodingJob(playlistPath, TranscodingJobType);
-                    return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job, cancellationToken).ConfigureAwait(false);
-                }
-                else
-                {
-                    if (string.Equals(representationId, "0", StringComparison.OrdinalIgnoreCase))
-                    {
-                        job = ApiEntryPoint.Instance.GetTranscodingJob(playlistPath, TranscodingJobType);
-                        var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath, segmentExtension);
-                        var segmentGapRequiringTranscodingChange = 24 / state.SegmentLength;
-                        Logger.Debug("Current transcoding index is {0}. requestedIndex={1}. segmentGapRequiringTranscodingChange={2}", currentTranscodingIndex ?? -2, requestedIndex, segmentGapRequiringTranscodingChange);
-                        if (currentTranscodingIndex == null || requestedIndex < currentTranscodingIndex.Value || (requestedIndex - currentTranscodingIndex.Value) > segmentGapRequiringTranscodingChange)
-                        {
-                            // If the playlist doesn't already exist, startup ffmpeg
-                            try
-                            {
-                                ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.PlaySessionId, p => false);
-
-                                if (currentTranscodingIndex.HasValue)
-                                {
-                                    DeleteLastTranscodedFiles(playlistPath, 0);
-                                }
-
-                                var positionTicks = GetPositionTicks(state, requestedIndex);
-                                request.StartTimeTicks = positionTicks;
-
-                                var startNumber = GetStartNumber(state);
-
-                                var workingDirectory = Path.Combine(Path.GetDirectoryName(playlistPath), (startNumber == -1 ? 0 : startNumber).ToString(CultureInfo.InvariantCulture));
-                                state.WaitForPath = Path.Combine(workingDirectory, Path.GetFileName(playlistPath));
-                                FileSystem.CreateDirectory(workingDirectory);
-                                job = await StartFfMpeg(state, playlistPath, cancellationTokenSource, workingDirectory).ConfigureAwait(false);
-                                await WaitForMinimumDashSegmentCount(Path.Combine(workingDirectory, Path.GetFileName(playlistPath)), 1, cancellationTokenSource.Token).ConfigureAwait(false);
-                            }
-                            catch
-                            {
-                                state.Dispose();
-                                throw;
-                            }
-                        }
-                    }
-                }
-            }
-            finally
-            {
-                ApiEntryPoint.Instance.TranscodingStartLock.Release();
-            }
-
-            while (string.IsNullOrWhiteSpace(segmentPath))
-            {
-                segmentPath = FindSegment(playlistPath, representationId, segmentExtension, requestedIndex);
-                await Task.Delay(50, cancellationToken).ConfigureAwait(false);
-            }
-
-            Logger.Info("returning {0}", segmentPath);
-            return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job ?? ApiEntryPoint.Instance.GetTranscodingJob(playlistPath, TranscodingJobType), cancellationToken).ConfigureAwait(false);
-        }
-
-        private long GetPositionTicks(StreamState state, int requestedIndex)
-        {
-            if (requestedIndex <= 0)
-            {
-                return 0;
-            }
-
-            var startSeconds = requestedIndex * state.SegmentLength;
-            return TimeSpan.FromSeconds(startSeconds).Ticks;
-        }
-
-        protected  Task WaitForMinimumDashSegmentCount(string playlist, int segmentCount, CancellationToken cancellationToken)
-        {
-            return WaitForSegment(playlist, "stream0-" + segmentCount.ToString("00000", CultureInfo.InvariantCulture) + ".m4s", cancellationToken);
-        }
-
-        private async Task<object> GetSegmentResult(string playlistPath,
-            string segmentPath,
-            int segmentIndex,
-            int segmentLength,
-            TranscodingJob transcodingJob,
-            CancellationToken cancellationToken)
-        {
-            // If all transcoding has completed, just return immediately
-            if (transcodingJob != null && transcodingJob.HasExited)
-            {
-                return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob);
-            }
-
-            // Wait for the file to stop being written to, then stream it
-            var length = new FileInfo(segmentPath).Length;
-            var eofCount = 0;
-
-            while (eofCount < 10)
-            {
-                var info = new FileInfo(segmentPath);
-
-                if (!info.Exists)
-                {
-                    break;
-                }
-
-                var newLength = info.Length;
-
-                if (newLength == length)
-                {
-                    eofCount++;
-                }
-                else
-                {
-                    eofCount = 0;
-                }
-
-                length = newLength;
-                await Task.Delay(100, cancellationToken).ConfigureAwait(false);
-            }
-
-            return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob);
-        }
-
-        private object GetSegmentResult(string segmentPath, int index, int segmentLength, TranscodingJob transcodingJob)
-        {
-            var segmentEndingSeconds = (1 + index) * segmentLength;
-            var segmentEndingPositionTicks = TimeSpan.FromSeconds(segmentEndingSeconds).Ticks;
-
-            return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
-            {
-                Path = segmentPath,
-                FileShare = FileShare.ReadWrite,
-                OnComplete = () =>
-                {
-                    if (transcodingJob != null)
-                    {
-                        transcodingJob.DownloadPositionTicks = Math.Max(transcodingJob.DownloadPositionTicks ?? segmentEndingPositionTicks, segmentEndingPositionTicks);
-                    }
-
-                }
-            });
-        }
-
-        public int? GetCurrentTranscodingIndex(string playlist, string segmentExtension)
-        {
-            var job = ApiEntryPoint.Instance.GetTranscodingJob(playlist, TranscodingJobType);
-
-            if (job == null || job.HasExited)
-            {
-                return null;
-            }
-
-            var file = GetLastTranscodingFiles(playlist, segmentExtension, FileSystem, 1).FirstOrDefault();
-
-            if (file == null)
-            {
-                return null;
-            }
-
-            return GetIndex(file.FullName);
-        }
-
-        public int GetIndex(string segmentPath)
-        {
-            var indexString = Path.GetFileNameWithoutExtension(segmentPath).Split('-').LastOrDefault();
-
-            if (string.Equals(indexString, "init", StringComparison.OrdinalIgnoreCase))
-            {
-                return -1;
-            }
-            var startNumber = int.Parse(Path.GetFileNameWithoutExtension(Path.GetDirectoryName(segmentPath)), NumberStyles.Integer, UsCulture);
-
-            return startNumber + int.Parse(indexString, NumberStyles.Integer, UsCulture) - 1;
-        }
-
-        private void DeleteLastTranscodedFiles(string playlistPath, int retryCount)
-        {
-            if (retryCount >= 5)
-            {
-                return;
-            }
-        }
-
-        private static List<FileSystemMetadata> GetLastTranscodingFiles(string playlist, string segmentExtension, IFileSystem fileSystem, int count)
-        {
-            var folder = Path.GetDirectoryName(playlist);
-
-            try
-            {
-				return fileSystem.GetFiles(folder)
-                    .Where(i => string.Equals(i.Extension, segmentExtension, StringComparison.OrdinalIgnoreCase))
-                    .OrderByDescending(fileSystem.GetLastWriteTimeUtc)
-                    .Take(count)
-                    .ToList();
-            }
-            catch (DirectoryNotFoundException)
-            {
-                return new List<FileSystemMetadata>();
-            }
-        }
-
-        private string FindSegment(string playlist, string representationId, string segmentExtension, int requestedIndex)
-        {
-            var folder = Path.GetDirectoryName(playlist);
-
-            if (requestedIndex == -1)
-            {
-                var path = Path.Combine(folder, "0", "stream" + representationId + "-" + "init" + segmentExtension);
-				return FileSystem.FileExists(path) ? path : null;
-            }
-
-            try
-            {
-                foreach (var subfolder in FileSystem.GetDirectoryPaths(folder).ToList())
-                {
-                    var subfolderName = Path.GetFileNameWithoutExtension(subfolder);
-                    int startNumber;
-                    if (int.TryParse(subfolderName, NumberStyles.Any, UsCulture, out startNumber))
-                    {
-                        var segmentIndex = requestedIndex - startNumber + 1;
-                        var path = Path.Combine(folder, subfolderName, "stream" + representationId + "-" + segmentIndex.ToString("00000", CultureInfo.InvariantCulture) + segmentExtension);
-						if (FileSystem.FileExists(path))
-                        {
-                            return path;
-                        }
-                    }
-                }
-            }
-            catch (DirectoryNotFoundException)
-            {
-                
-            }
-
-            return null;
-        }
-
-        protected override string GetAudioArguments(StreamState state)
-        {
-            var codec = GetAudioEncoder(state);
-
-            if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase))
-            {
-                return "-codec:a:0 copy";
-            }
-
-            var args = "-codec:a:0 " + codec;
-
-            var channels = state.OutputAudioChannels;
-
-            if (channels.HasValue)
-            {
-                args += " -ac " + channels.Value;
-            }
-
-            var bitrate = state.OutputAudioBitrate;
-
-            if (bitrate.HasValue)
-            {
-                args += " -ab " + bitrate.Value.ToString(UsCulture);
-            }
-
-            args += " " + GetAudioFilterParam(state, true);
-
-            return args;
-        }
-
-        protected override string GetVideoArguments(StreamState state)
-        {
-            var codec = GetVideoEncoder(state);
-
-            var args = "-codec:v:0 " + codec;
-
-            if (state.EnableMpegtsM2TsMode)
-            {
-                args += " -mpegts_m2ts_mode 1";
-            }
-
-            // See if we can save come cpu cycles by avoiding encoding
-            if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
-            {
-                return state.VideoStream != null && IsH264(state.VideoStream) ?
-                    args + " -bsf:v h264_mp4toannexb" :
-                    args;
-            }
-
-            var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",
-                state.SegmentLength.ToString(UsCulture));
-
-            var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream;
-
-            args += " " + GetVideoQualityParam(state, GetH264Encoder(state)) + keyFrameArg;
-
-            // Add resolution params, if specified
-            if (!hasGraphicalSubs)
-            {
-                args += GetOutputSizeParam(state, codec, false);
-            }
-
-            // This is for internal graphical subs
-            if (hasGraphicalSubs)
-            {
-                args += GetGraphicalSubtitleParam(state, codec);
-            }
-
-            return args;
-        }
-
-        protected override string GetCommandLineArguments(string outputPath, StreamState state, bool isEncoding)
-        {
-            // test url http://192.168.1.2:8096/videos/233e8905d559a8f230db9bffd2ac9d6d/master.mpd?mediasourceid=233e8905d559a8f230db9bffd2ac9d6d&videocodec=h264&audiocodec=aac&maxwidth=1280&videobitrate=500000&audiobitrate=128000&profile=baseline&level=3
-            // Good info on i-frames http://blog.streamroot.io/encode-multi-bitrate-videos-mpeg-dash-mse-based-media-players/
-
-            var threads = GetNumberOfThreads(state, false);
-
-            var inputModifier = GetInputModifier(state);
-
-            var initSegmentName = "stream$RepresentationID$-init.m4s";
-            var segmentName = "stream$RepresentationID$-$Number%05d$.m4s";
-
-            var args = string.Format("{0} {1} -map_metadata -1 -threads {2} {3} {4} -copyts {5} -f dash -init_seg_name \"{6}\" -media_seg_name \"{7}\" -use_template 0 -use_timeline 1 -min_seg_duration {8} -y \"{9}\"",
-                inputModifier,
-                GetInputArgument(state),
-                threads,
-                GetMapArgs(state),
-                GetVideoArguments(state),
-                GetAudioArguments(state),
-                initSegmentName,
-                segmentName,
-                (state.SegmentLength * 1000000).ToString(CultureInfo.InvariantCulture),
-                state.WaitForPath
-                ).Trim();
-
-            return args;
-        }
-
-        protected override int GetStartNumber(StreamState state)
-        {
-            return GetStartNumber(state.VideoRequest);
-        }
-
-        private int GetStartNumber(VideoStreamRequest request)
-        {
-            var segmentId = "0";
-
-            var segmentRequest = request as GetDashSegment;
-            if (segmentRequest != null)
-            {
-                segmentId = segmentRequest.SegmentId;
-            }
-
-            if (string.Equals(segmentId, "init", StringComparison.OrdinalIgnoreCase))
-            {
-                return -1;
-            }
-
-            return int.Parse(segmentId, NumberStyles.Integer, UsCulture);
-        }
-
-        /// <summary>
-        /// Gets the segment file extension.
-        /// </summary>
-        /// <param name="state">The state.</param>
-        /// <returns>System.String.</returns>
-        protected override string GetSegmentFileExtension(StreamState state)
-        {
-            return ".m4s";
-        }
-
-        protected override TranscodingJobType TranscodingJobType
-        {
-            get
-            {
-                return TranscodingJobType.Dash;
-            }
-        }
-
-        private async Task WaitForSegment(string playlist, string segment, CancellationToken cancellationToken)
-        {
-            var segmentFilename = Path.GetFileName(segment);
-
-            Logger.Debug("Waiting for {0} in {1}", segmentFilename, playlist);
-
-            while (true)
-            {
-                // Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written
-                using (var fileStream = GetPlaylistFileStream(playlist))
-                {
-                    using (var reader = new StreamReader(fileStream))
-                    {
-                        while (!reader.EndOfStream)
-                        {
-                            var line = await reader.ReadLineAsync().ConfigureAwait(false);
-
-                            if (line.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1)
-                            {
-                                Logger.Debug("Finished waiting for {0} in {1}", segmentFilename, playlist);
-                                return;
-                            }
-                        }
-                        await Task.Delay(100, cancellationToken).ConfigureAwait(false);
-                    }
-                }
-            }
-        }
-    }
-}

+ 23 - 41
MediaBrowser.Api/Playback/Hls/BaseHlsService.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Library;
@@ -84,11 +83,6 @@ namespace MediaBrowser.Api.Playback.Hls
 
             var state = await GetState(request, cancellationTokenSource.Token).ConfigureAwait(false);
 
-            if (isLive)
-            {
-                state.Request.StartTimeTicks = null;
-            }
-
             TranscodingJob job = null;
             var playlist = state.OutputFilePath;
 
@@ -138,13 +132,6 @@ namespace MediaBrowser.Api.Playback.Hls
             var appendBaselineStream = false;
             var baselineStreamBitrate = 64000;
 
-            var hlsVideoRequest = state.VideoRequest as GetHlsVideoStreamLegacy;
-            if (hlsVideoRequest != null)
-            {
-                appendBaselineStream = hlsVideoRequest.AppendBaselineStream;
-                baselineStreamBitrate = hlsVideoRequest.BaselineStreamAudioBitRate ?? baselineStreamBitrate;
-            }
-
             var playlistText = GetMasterPlaylistFileText(playlist, videoBitrate + audioBitrate, appendBaselineStream, baselineStreamBitrate);
 
             job = job ?? ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType);
@@ -249,11 +236,7 @@ namespace MediaBrowser.Api.Playback.Hls
 
         protected override string GetCommandLineArguments(string outputPath, StreamState state, bool isEncoding)
         {
-            var hlsVideoRequest = state.VideoRequest as GetHlsVideoStreamLegacy;
-
-            var itsOffsetMs = hlsVideoRequest == null
-                                       ? 0
-                                       : hlsVideoRequest.TimeStampOffsetMs;
+            var itsOffsetMs = 0;
 
             var itsOffset = itsOffsetMs == 0 ? string.Empty : string.Format("-itsoffset {0} ", TimeSpan.FromMilliseconds(itsOffsetMs).TotalSeconds.ToString(UsCulture));
 
@@ -287,26 +270,6 @@ namespace MediaBrowser.Api.Playback.Hls
                 outputPath
                 ).Trim();
 
-            if (hlsVideoRequest != null)
-            {
-                if (hlsVideoRequest.AppendBaselineStream)
-                {
-                    var lowBitratePath = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath) + "-low.m3u8");
-
-                    var bitrate = hlsVideoRequest.BaselineStreamAudioBitRate ?? 64000;
-
-                    var lowBitrateParams = string.Format(" -threads {0} -vn -codec:a:0 libmp3lame -ac 2 -ab {1} -hls_time {2} -start_number {3} -hls_list_size {4} -y \"{5}\"",
-                        threads,
-                        bitrate / 2,
-                        state.SegmentLength.ToString(UsCulture),
-                        startNumberParam,
-                        state.HlsListSize.ToString(UsCulture),
-                        lowBitratePath);
-
-                    args += " " + lowBitrateParams;
-                }
-            }
-
             return args;
         }
 
@@ -315,9 +278,28 @@ namespace MediaBrowser.Api.Playback.Hls
             return 0;
         }
 
-        protected override bool CanStreamCopyAudio(VideoStreamRequest request, MediaStream audioStream, List<string> supportedAudioCodecs)
+        protected bool IsLiveStream(StreamState state)
         {
-            return false;
+            var isLiveStream = (state.RunTimeTicks ?? 0) == 0;
+
+            if (state.VideoRequest.ForceLiveStream)
+            {
+                return true;
+            }
+
+            return isLiveStream;
+        }
+
+        protected override bool CanStreamCopyAudio(StreamState state, List<string> supportedAudioCodecs)
+        {
+            var isLiveStream = IsLiveStream(state);
+
+            if (!isLiveStream)
+            {
+                return false;
+            }
+
+            return base.CanStreamCopyAudio(state, supportedAudioCodecs);
         }
     }
 }

+ 28 - 10
MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs

@@ -199,9 +199,9 @@ namespace MediaBrowser.Api.Playback.Hls
                         Logger.Debug("Starting transcoding because requestedIndex={0} and currentTranscodingIndex={1}", requestedIndex, currentTranscodingIndex);
                         startTranscoding = true;
                     }
-                    else if ((requestedIndex - currentTranscodingIndex.Value) > segmentGapRequiringTranscodingChange)
+                    else if (requestedIndex - currentTranscodingIndex.Value > segmentGapRequiringTranscodingChange)
                     {
-                        Logger.Debug("Starting transcoding because segmentGap is {0} and max allowed gap is {1}. requestedIndex={2}", (requestedIndex - currentTranscodingIndex.Value), segmentGapRequiringTranscodingChange, requestedIndex);
+                        Logger.Debug("Starting transcoding because segmentGap is {0} and max allowed gap is {1}. requestedIndex={2}", requestedIndex - currentTranscodingIndex.Value, segmentGapRequiringTranscodingChange, requestedIndex);
                         startTranscoding = true;
                     }
                     if (startTranscoding)
@@ -500,13 +500,25 @@ namespace MediaBrowser.Api.Playback.Hls
             return ResultFactory.GetResult(playlistText, MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>());
         }
 
+        private bool IsLiveStream(StreamState state)
+        {
+            var isLiveStream = (state.RunTimeTicks ?? 0) == 0;
+
+            if (state.VideoRequest.ForceLiveStream)
+            {
+                return true;
+            }
+
+            return isLiveStream;
+        }
+
         private string GetMasterPlaylistFileText(StreamState state, int totalBitrate)
         {
             var builder = new StringBuilder();
 
             builder.AppendLine("#EXTM3U");
 
-            var isLiveStream = (state.RunTimeTicks ?? 0) == 0;
+            var isLiveStream = IsLiveStream(state);
 
             var queryStringIndex = Request.RawUrl.IndexOf('?');
             var queryString = queryStringIndex == -1 ? string.Empty : Request.RawUrl.Substring(queryStringIndex);
@@ -524,7 +536,7 @@ namespace MediaBrowser.Api.Playback.Hls
                 .ToList();
 
             var subtitleGroup = subtitleStreams.Count > 0 &&
-                (request is GetMasterHlsVideoPlaylist) &&
+                request is GetMasterHlsVideoPlaylist &&
                 ((GetMasterHlsVideoPlaylist)request).SubtitleMethod == SubtitleDeliveryMethod.Hls ?
                 "subs" :
                 null;
@@ -544,12 +556,12 @@ namespace MediaBrowser.Api.Playback.Hls
                 var variation = GetBitrateVariation(totalBitrate);
 
                 var newBitrate = totalBitrate - variation;
-                var variantUrl = ReplaceBitrate(playlistUrl, requestedVideoBitrate, (requestedVideoBitrate - variation));
+                var variantUrl = ReplaceBitrate(playlistUrl, requestedVideoBitrate, requestedVideoBitrate - variation);
                 AppendPlaylist(builder, state, variantUrl, newBitrate, subtitleGroup);
 
                 variation *= 2;
                 newBitrate = totalBitrate - variation;
-                variantUrl = ReplaceBitrate(playlistUrl, requestedVideoBitrate, (requestedVideoBitrate - variation));
+                variantUrl = ReplaceBitrate(playlistUrl, requestedVideoBitrate, requestedVideoBitrate - variation);
                 AppendPlaylist(builder, state, variantUrl, newBitrate, subtitleGroup);
             }
 
@@ -703,7 +715,7 @@ namespace MediaBrowser.Api.Playback.Hls
             builder.AppendLine("#EXTM3U");
             builder.AppendLine("#EXT-X-PLAYLIST-TYPE:VOD");
             builder.AppendLine("#EXT-X-VERSION:3");
-            builder.AppendLine("#EXT-X-TARGETDURATION:" + Math.Ceiling((segmentLengths.Length > 0 ? segmentLengths.Max() : state.SegmentLength)).ToString(UsCulture));
+            builder.AppendLine("#EXT-X-TARGETDURATION:" + Math.Ceiling(segmentLengths.Length > 0 ? segmentLengths.Max() : state.SegmentLength).ToString(UsCulture));
             builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0");
 
             var queryStringIndex = Request.RawUrl.IndexOf('?');
@@ -929,10 +941,16 @@ namespace MediaBrowser.Api.Playback.Hls
             return isOutputVideo ? ".ts" : ".ts";
         }
 
-        protected override bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream)
+        protected override bool CanStreamCopyVideo(StreamState state)
         {
-            return false;
-            //return base.CanStreamCopyVideo(request, videoStream);
+            var isLiveStream = IsLiveStream(state);
+
+            if (!isLiveStream)
+            {
+                return false;
+            }
+
+            return base.CanStreamCopyVideo(state);
         }
     }
 }

+ 0 - 19
MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs

@@ -31,25 +31,6 @@ namespace MediaBrowser.Api.Playback.Hls
         public string SegmentId { get; set; }
     }
 
-    /// <summary>
-    /// Class GetHlsVideoStream
-    /// </summary>
-    [Route("/Videos/{Id}/stream.m3u8", "GET")]
-    [Api(Description = "Gets a video stream using HTTP live streaming.")]
-    public class GetHlsVideoStreamLegacy : VideoStreamRequest
-    {
-        // TODO: Deprecate with new iOS app
-
-        [ApiMember(Name = "BaselineStreamAudioBitRate", Description = "Optional. Specify the audio bitrate for the baseline stream.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
-        public int? BaselineStreamAudioBitRate { get; set; }
-
-        [ApiMember(Name = "AppendBaselineStream", Description = "Optional. Whether or not to include a baseline audio-only stream in the master playlist.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
-        public bool AppendBaselineStream { get; set; }
-
-        [ApiMember(Name = "TimeStampOffsetMs", Description = "Optional. Alter the timestamps in the playlist by a given amount, in ms. Default is 1000.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
-        public int TimeStampOffsetMs { get; set; }
-    }
-
     /// <summary>
     /// Class GetHlsVideoSegment
     /// </summary>

+ 3 - 15
MediaBrowser.Api/Playback/Hls/VideoHlsService.cs

@@ -1,4 +1,3 @@
-using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Dlna;
@@ -28,16 +27,6 @@ namespace MediaBrowser.Api.Playback.Hls
         {
         }
 
-        /// <summary>
-        /// Gets the specified request.
-        /// </summary>
-        /// <param name="request">The request.</param>
-        /// <returns>System.Object.</returns>
-        public object Get(GetHlsVideoStreamLegacy request)
-        {
-            return ProcessRequest(request, false);
-        }
-
         public object Get(GetLiveHlsStream request)
         {
             return ProcessRequest(request, true);
@@ -97,11 +86,10 @@ namespace MediaBrowser.Api.Playback.Hls
             // See if we can save come cpu cycles by avoiding encoding
             if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
             {
-                return state.VideoStream != null && IsH264(state.VideoStream) ?
-                    args + " -bsf:v h264_mp4toannexb" :
-                    args;
+                // if h264_mp4toannexb is ever added, do not use it for live tv
+                return args;
             }
-            
+
             var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
                 state.SegmentLength.ToString(UsCulture));
 

+ 19 - 2
MediaBrowser.Api/Playback/MediaInfoService.cs

@@ -227,7 +227,7 @@ namespace MediaBrowser.Api.Playback
                 SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, result.PlaySessionId);
             }
 
-            SortMediaSources(result);
+            SortMediaSources(result, maxBitrate);
         }
 
         private void SetDeviceSpecificData(BaseItem item,
@@ -375,7 +375,7 @@ namespace MediaBrowser.Api.Playback
             }
         }
 
-        private void SortMediaSources(PlaybackInfoResponse result)
+        private void SortMediaSources(PlaybackInfoResponse result, int? maxBitrate)
         {
             var originalList = result.MediaSources.ToList();
 
@@ -409,6 +409,23 @@ namespace MediaBrowser.Api.Playback
                         return 1;
                 }
 
+            }).ThenBy(i =>
+            {
+                if (maxBitrate.HasValue)
+                {
+                    if (i.Bitrate.HasValue)
+                    {
+                        if (i.Bitrate.Value <= maxBitrate.Value)
+                        {
+                            return 0;
+                        }
+
+                        return 2;
+                    }
+                }
+
+                return 1;
+
             }).ThenBy(originalList.IndexOf)
             .ToList();
         }

+ 1 - 3
MediaBrowser.Api/Playback/Progressive/AudioService.cs

@@ -1,11 +1,9 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Serialization;

+ 1 - 3
MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Dlna;
@@ -14,7 +13,6 @@ using ServiceStack.Web;
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;

+ 1 - 2
MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Logging;
 using ServiceStack.Web;
 using System;
 using System.Collections.Generic;

+ 1 - 5
MediaBrowser.Api/Playback/Progressive/VideoService.cs

@@ -1,4 +1,3 @@
-using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
@@ -10,7 +9,6 @@ using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Serialization;
 using ServiceStack;
 using System;
-using System.Globalization;
 using System.IO;
 using CommonIO;
 using MediaBrowser.Model.Dlna;
@@ -139,12 +137,10 @@ namespace MediaBrowser.Api.Playback.Progressive
                 args += " -mpegts_m2ts_mode 1";
             }
 
-            var isOutputMkv = string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase);
-
             if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase))
             {
                 if (state.VideoStream != null && IsH264(state.VideoStream) &&
-                    (string.Equals(state.OutputContainer, "ts", StringComparison.OrdinalIgnoreCase) || isOutputMkv))
+                    (string.Equals(state.OutputContainer, "ts", StringComparison.OrdinalIgnoreCase)))
                 {
                     args += " -bsf:v h264_mp4toannexb";
                 }

+ 3 - 4
MediaBrowser.Api/Playback/StreamRequest.cs

@@ -189,10 +189,9 @@ namespace MediaBrowser.Api.Playback
 
         [ApiMember(Name = "CopyTimestamps", Description = "Whether or not to copy timestamps when transcoding with an offset. Defaults to false.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
         public bool CopyTimestamps { get; set; }
-        
-        [ApiMember(Name = "Cabac", Description = "Enable if cabac encoding is required", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
-        public bool? Cabac { get; set; }
-        
+
+        public bool ForceLiveStream { get; set; }
+
         public VideoStreamRequest()
         {
             EnableAutoStreamCopy = true;

+ 1 - 14
MediaBrowser.Api/Playback/StreamState.cs

@@ -185,7 +185,7 @@ namespace MediaBrowser.Api.Playback
 
         private async void DisposeLiveStream()
         {
-            if ((MediaSource.RequiresClosing) && string.IsNullOrWhiteSpace(Request.LiveStreamId))
+            if (MediaSource.RequiresClosing && string.IsNullOrWhiteSpace(Request.LiveStreamId))
             {
                 try
                 {
@@ -480,18 +480,5 @@ namespace MediaBrowser.Api.Playback
                 return false;
             }
         }
-
-        public bool? IsTargetCabac
-        {
-            get
-            {
-                if (Request.Static)
-                {
-                    return VideoStream == null ? null : VideoStream.IsCabac;
-                }
-
-                return true;
-            }
-        }
     }
 }

+ 0 - 1
MediaBrowser.Api/PluginService.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common;
-using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Security;
 using MediaBrowser.Common.Updates;

+ 0 - 3
MediaBrowser.Api/Reports/Activities/ReportActivitiesBuilder.cs

@@ -1,10 +1,7 @@
 using MediaBrowser.Model.Activity;
 using MediaBrowser.Model.Querying;
-using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using MediaBrowser.Controller.Library;
 namespace MediaBrowser.Api.Reports
 {

+ 0 - 4
MediaBrowser.Api/Reports/Common/HeaderActivitiesMetadata.cs

@@ -1,7 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
 namespace MediaBrowser.Api.Reports
 {
     public enum HeaderActivitiesMetadata

+ 0 - 4
MediaBrowser.Api/Reports/Common/HeaderMetadata.cs

@@ -1,7 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
 namespace MediaBrowser.Api.Reports
 {
 	public enum HeaderMetadata

+ 0 - 4
MediaBrowser.Api/Reports/Common/ItemViewType.cs

@@ -1,7 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
 namespace MediaBrowser.Api.Reports
 {
     public enum ItemViewType

+ 1 - 4
MediaBrowser.Api/Reports/Common/ReportBuilderBase.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Channels;
@@ -8,8 +7,6 @@ using MediaBrowser.Model.Entities;
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace MediaBrowser.Api.Reports
 {
@@ -327,7 +324,7 @@ namespace MediaBrowser.Api.Reports
             if (stream != null && stream.Width != null)
                 return string.Format("{0} * {1}",
                         stream.Width,
-                        (stream.Height != null ? stream.Height.ToString() : "-"));
+                        stream.Height != null ? stream.Height.ToString() : "-");
 
             return string.Empty;
         }

+ 0 - 4
MediaBrowser.Api/Reports/Common/ReportDisplayType.cs

@@ -1,7 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
 namespace MediaBrowser.Api.Reports
 {
     public enum ReportDisplayType

+ 0 - 4
MediaBrowser.Api/Reports/Common/ReportExportType.cs

@@ -1,7 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
 namespace MediaBrowser.Api.Reports
 {
 	public enum ReportExportType

+ 0 - 4
MediaBrowser.Api/Reports/Common/ReportFieldType.cs

@@ -1,7 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
 namespace MediaBrowser.Api.Reports
 {
 	public enum ReportFieldType

+ 0 - 4
MediaBrowser.Api/Reports/Common/ReportHeaderIdType.cs

@@ -1,7 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
 namespace MediaBrowser.Api.Reports
 {
 	public enum ReportHeaderIdType

+ 0 - 4
MediaBrowser.Api/Reports/Common/ReportIncludeItemTypes.cs

@@ -1,7 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
 namespace MediaBrowser.Api.Reports
 {
 	public enum ReportIncludeItemTypes

+ 0 - 4
MediaBrowser.Api/Reports/Common/ReportViewType.cs

@@ -1,7 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
 namespace MediaBrowser.Api.Reports
 {
 	public enum ReportViewType

+ 3 - 12
MediaBrowser.Api/Reports/Data/ReportBuilder.cs

@@ -1,19 +1,10 @@
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Localization;
-using MediaBrowser.Model.Channels;
-using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Querying;
-using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Linq.Expressions;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace MediaBrowser.Api.Reports
 {
@@ -616,9 +607,9 @@ namespace MediaBrowser.Api.Reports
                 Id = item.Id.ToString("N"),
                 HasLockData = item.IsLocked,
                 HasLocalTrailer = hasTrailers != null ? hasTrailers.GetTrailerIds().Count() > 0 : false,
-                HasImageTagsPrimary = (item.ImageInfos != null && item.ImageInfos.Count(n => n.Type == ImageType.Primary) > 0),
-                HasImageTagsBackdrop = (item.ImageInfos != null && item.ImageInfos.Count(n => n.Type == ImageType.Backdrop) > 0),
-                HasImageTagsLogo = (item.ImageInfos != null && item.ImageInfos.Count(n => n.Type == ImageType.Logo) > 0),
+                HasImageTagsPrimary = item.ImageInfos != null && item.ImageInfos.Count(n => n.Type == ImageType.Primary) > 0,
+                HasImageTagsBackdrop = item.ImageInfos != null && item.ImageInfos.Count(n => n.Type == ImageType.Backdrop) > 0,
+                HasImageTagsLogo = item.ImageInfos != null && item.ImageInfos.Count(n => n.Type == ImageType.Logo) > 0,
                 HasSpecials = hasSpecialFeatures != null ? hasSpecialFeatures.SpecialFeatureIds.Count > 0 : false,
                 HasSubtitles = video != null ? video.HasSubtitles : false,
                 RowType = ReportHelper.GetRowType(item.GetClientTypeName())

+ 1 - 4
MediaBrowser.Api/Reports/Data/ReportExport.cs

@@ -1,8 +1,5 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using System.Linq;
 using System.Text;
-using System.Threading.Tasks;
 
 namespace MediaBrowser.Api.Reports
 {

+ 1 - 6
MediaBrowser.Api/Reports/Data/ReportOptions.cs

@@ -1,9 +1,4 @@
-using MediaBrowser.Controller.Entities;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System;
 
 namespace MediaBrowser.Api.Reports
 {

+ 1 - 5
MediaBrowser.Api/Reports/Model/ReportGroup.cs

@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
 
 namespace MediaBrowser.Api.Reports
 {

+ 1 - 8
MediaBrowser.Api/Reports/Model/ReportHeader.cs

@@ -1,11 +1,4 @@
-using MediaBrowser.Controller.Entities;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Api.Reports
+namespace MediaBrowser.Api.Reports
 {
 	/// <summary> A report header. </summary>
 	public class ReportHeader

+ 1 - 7
MediaBrowser.Api/Reports/Model/ReportItem.cs

@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Api.Reports
+namespace MediaBrowser.Api.Reports
 {
 	/// <summary> A report item. </summary>
 	public class ReportItem

+ 1 - 5
MediaBrowser.Api/Reports/Model/ReportRow.cs

@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
 
 namespace MediaBrowser.Api.Reports
 {

+ 0 - 3
MediaBrowser.Api/Reports/ReportRequests.cs

@@ -1,9 +1,6 @@
 using MediaBrowser.Api.UserLibrary;
-using MediaBrowser.Model.Entities;
 using ServiceStack;
-using System;
 using System.Collections.Generic;
-using System.Linq;
 
 namespace MediaBrowser.Api.Reports
 {

+ 1 - 12
MediaBrowser.Api/Reports/ReportsService.cs

@@ -1,26 +1,15 @@
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Querying;
 using System.Collections.Generic;
 using System.Threading.Tasks;
 using System.Globalization;
 using System.Linq;
-using MediaBrowser.Model.Dto;
 using MediaBrowser.Controller.Localization;
-using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Api.UserLibrary;
-using MediaBrowser.Controller.Collections;
-using MediaBrowser.Controller.Entities.TV;
 using System;
-using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Model.Entities;
-using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Activity;
 using MediaBrowser.Controller.Activity;
-using System.IO;
-using System.Text;
 
 namespace MediaBrowser.Api.Reports
 {

+ 0 - 3
MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs

@@ -1,11 +1,8 @@
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Entities;
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace MediaBrowser.Api.Reports
 {

+ 1 - 5
MediaBrowser.Api/Reports/Stat/ReportStatGroup.cs

@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
 
 namespace MediaBrowser.Api.Reports
 {

+ 1 - 7
MediaBrowser.Api/Reports/Stat/ReportStatItem.cs

@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Api.Reports
+namespace MediaBrowser.Api.Reports
 {
 	/// <summary> A report stat item. </summary>
 	public class ReportStatItem

+ 1 - 5
MediaBrowser.Api/Reports/Stat/ReportStatResult.cs

@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
 
 namespace MediaBrowser.Api.Reports
 {

+ 1 - 2
MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.ScheduledTasks;
+using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Events;
 using MediaBrowser.Model.Logging;

+ 0 - 2
MediaBrowser.Api/SearchService.cs

@@ -4,12 +4,10 @@ using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Search;
 using ServiceStack;
-using System;
 using System.Linq;
 using System.Threading.Tasks;
 

+ 0 - 1
MediaBrowser.Api/Subtitles/SubtitleService.cs

@@ -17,7 +17,6 @@ using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
 using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
-using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Api.Subtitles
 {

+ 1 - 2
MediaBrowser.Api/System/SystemInfoWebSocketListener.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller;
+using MediaBrowser.Controller;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.System;

+ 0 - 2
MediaBrowser.Api/System/SystemService.cs

@@ -1,10 +1,8 @@
 using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Security;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.System;
 using ServiceStack;
 using System;

+ 21 - 3
MediaBrowser.Api/TvShowsService.cs

@@ -123,7 +123,7 @@ namespace MediaBrowser.Api
     }
 
     [Route("/Shows/{Id}/Episodes", "GET", Summary = "Gets episodes for a tv season")]
-    public class GetEpisodes : IReturn<ItemsResult>, IHasItemFields
+    public class GetEpisodes : IReturn<ItemsResult>, IHasItemFields, IHasDtoOptions
     {
         /// <summary>
         /// Gets or sets the user id.
@@ -173,10 +173,19 @@ namespace MediaBrowser.Api
         /// <value>The limit.</value>
         [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
         public int? Limit { get; set; }
+
+        [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
+        public bool? EnableImages { get; set; }
+
+        [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+        public int? ImageTypeLimit { get; set; }
+
+        [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+        public string EnableImageTypes { get; set; }
     }
 
     [Route("/Shows/{Id}/Seasons", "GET", Summary = "Gets seasons for a tv series")]
-    public class GetSeasons : IReturn<ItemsResult>, IHasItemFields
+    public class GetSeasons : IReturn<ItemsResult>, IHasItemFields, IHasDtoOptions
     {
         /// <summary>
         /// Gets or sets the user id.
@@ -206,6 +215,15 @@ namespace MediaBrowser.Api
 
         [ApiMember(Name = "AdjacentTo", Description = "Optional. Return items that are siblings of a supplied item.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
         public string AdjacentTo { get; set; }
+
+        [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
+        public bool? EnableImages { get; set; }
+
+        [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+        public int? ImageTypeLimit { get; set; }
+
+        [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+        public string EnableImageTypes { get; set; }
     }
 
     /// <summary>
@@ -273,7 +291,7 @@ namespace MediaBrowser.Api
         {
             var user = _userManager.GetUserById(request.UserId);
 
-            var minPremiereDate = DateTime.Now.Date.ToUniversalTime();
+            var minPremiereDate = DateTime.Now.Date.ToUniversalTime().AddDays(-1);
 
             var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId };
 

+ 2 - 3
MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs

@@ -2,7 +2,6 @@
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
 using ServiceStack;
@@ -332,7 +331,7 @@ namespace MediaBrowser.Api.UserLibrary
                     {
                         return false;
                     }
-                    if (!(tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase))))
+                    if (!tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
                     {
                         return false;
                     }
@@ -347,7 +346,7 @@ namespace MediaBrowser.Api.UserLibrary
 
                 // Apply genre filter
                 var genres = request.GetGenres();
-                if (genres.Length > 0 && !(genres.Any(v => i.Genres.Contains(v, StringComparer.OrdinalIgnoreCase))))
+                if (genres.Length > 0 && !genres.Any(v => i.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)))
                 {
                     return false;
                 }

+ 0 - 1
MediaBrowser.Api/UserLibrary/GameGenresService.cs

@@ -5,7 +5,6 @@ using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Querying;
 using ServiceStack;
 using System;
 using System.Collections.Generic;

+ 0 - 2
MediaBrowser.Api/UserLibrary/ItemsService.cs

@@ -1,8 +1,6 @@
 using MediaBrowser.Controller.Collections;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Net;

+ 0 - 2
MediaBrowser.Api/UserLibrary/MusicGenresService.cs

@@ -5,9 +5,7 @@ using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Querying;
 using ServiceStack;
-using System;
 using System.Collections.Generic;
 using System.Linq;
 

+ 1 - 1
MediaBrowser.Api/UserLibrary/PlaystateService.cs

@@ -285,7 +285,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         public void Post(OnPlaybackStart request)
         {
-            var queueableMediaTypes = (request.QueueableMediaTypes ?? string.Empty);
+            var queueableMediaTypes = request.QueueableMediaTypes ?? string.Empty;
 
             Post(new ReportPlaybackStart
             {

+ 0 - 2
MediaBrowser.Api/UserLibrary/StudiosService.cs

@@ -4,9 +4,7 @@ using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Querying;
 using ServiceStack;
-using System;
 using System.Collections.Generic;
 using System.Linq;
 

+ 0 - 2
MediaBrowser.Api/UserLibrary/YearsService.cs

@@ -4,9 +4,7 @@ using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Querying;
 using ServiceStack;
-using System;
 using System.Collections.Generic;
 using System.Linq;
 

+ 0 - 1
MediaBrowser.Api/UserService.cs

@@ -2,7 +2,6 @@
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Devices;
-using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Session;

+ 1 - 2
MediaBrowser.Api/VideosService.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;

+ 0 - 2
MediaBrowser.Common.Implementations/Archiving/ZipClient.cs

@@ -5,10 +5,8 @@ using SharpCompress.Archive.Tar;
 using SharpCompress.Common;
 using SharpCompress.Reader;
 using SharpCompress.Reader.Zip;
-using System;
 using System.IO;
 using CommonIO;
-using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Common.Implementations.Archiving
 {

+ 2 - 3
MediaBrowser.Common.Implementations/BaseApplicationHost.cs

@@ -7,7 +7,6 @@ using MediaBrowser.Common.Implementations.ScheduledTasks;
 using MediaBrowser.Common.Implementations.Security;
 using MediaBrowser.Common.Implementations.Serialization;
 using MediaBrowser.Common.Implementations.Updates;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Plugins;
 using MediaBrowser.Common.Progress;
@@ -251,7 +250,7 @@ namespace MediaBrowser.Common.Implementations
             progress.Report(15);
 
             var innerProgress = new ActionableProgress<double>();
-            innerProgress.RegisterAction(p => progress.Report((.8 * p) + 15));
+            innerProgress.RegisterAction(p => progress.Report(.8 * p + 15));
 
             await RegisterResources(innerProgress).ConfigureAwait(false);
 
@@ -661,7 +660,7 @@ namespace MediaBrowser.Common.Implementations
         {
             try
             {
-                return Assembly.Load(File.ReadAllBytes((file)));
+                return Assembly.Load(File.ReadAllBytes(file));
             }
             catch (Exception ex)
             {

+ 0 - 1
MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs

@@ -2,7 +2,6 @@
 using System;
 using System.IO;
 using System.Linq;
-using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Common.Implementations.Configuration
 {

+ 0 - 1
MediaBrowser.Common.Implementations/Devices/DeviceId.cs

@@ -4,7 +4,6 @@ using System;
 using System.IO;
 using System.Text;
 using CommonIO;
-using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Common.Implementations.Devices
 {

+ 0 - 1
MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs

@@ -11,7 +11,6 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using CommonIO;
-using MediaBrowser.Common.IO;
 using Microsoft.Win32;
 
 namespace MediaBrowser.Common.Implementations.ScheduledTasks

+ 0 - 1
MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Model.Logging;
 using System;

+ 1 - 3
MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs

@@ -1,9 +1,7 @@
 using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Common.ScheduledTasks;
 using System;
 using System.Collections.Generic;
-using System.IO;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -57,7 +55,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         {
             // Delete log files more than n days old
-            var minDateModified = DateTime.UtcNow.AddDays(-(ConfigurationManager.CommonConfiguration.LogFileRetentionDays));
+            var minDateModified = DateTime.UtcNow.AddDays(-ConfigurationManager.CommonConfiguration.LogFileRetentionDays);
 
 			var filesToDelete = _fileSystem.GetFiles(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath, true)
                           .Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)

+ 2 - 2
MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs

@@ -103,11 +103,11 @@ namespace MediaBrowser.Common.Implementations.Security
                 }
                 catch (DirectoryNotFoundException)
                 {
-                    (File.Create(licenseFile)).Close();
+                    File.Create(licenseFile).Close();
                 }
                 catch (FileNotFoundException)
                 {
-					(File.Create(licenseFile)).Close();
+					File.Create(licenseFile).Close();
                 }
             }
             if (contents != null && contents.Length > 0)

+ 2 - 2
MediaBrowser.Common.Implementations/Security/MbAdmin.cs

@@ -3,11 +3,11 @@ namespace MediaBrowser.Common.Implementations.Security
 {
     public class MbAdmin
     {
-        public const string HttpUrl = "http://www.mb3admin.com/admin/";
+        public const string HttpUrl = "https://www.mb3admin.com/admin/";
         
         /// <summary>
         /// Leaving as http for now until we get it squared away
         /// </summary>
-        public const string HttpsUrl = "http://www.mb3admin.com/admin/";
+        public const string HttpsUrl = "https://www.mb3admin.com/admin/";
     }
 }

+ 3 - 3
MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs

@@ -21,7 +21,7 @@ namespace MediaBrowser.Common.Implementations.Security
     public class PluginSecurityManager : ISecurityManager
     {
         private const string MBValidateUrl = MbAdmin.HttpsUrl + "service/registration/validate";
-        private const string AppstoreRegUrl = /*MbAdmin.HttpsUrl*/ "http://mb3admin.com/admin/service/appstore/register";
+        private const string AppstoreRegUrl = /*MbAdmin.HttpsUrl*/ "https://mb3admin.com/admin/service/appstore/register";
 
         /// <summary>
         /// The _is MB supporter
@@ -299,7 +299,7 @@ namespace MediaBrowser.Common.Implementations.Security
             };
 
             record.TrialVersion = IsInTrial(reg.expDate, record.RegChecked, record.IsRegistered);
-            record.IsValid = !record.RegChecked || (record.IsRegistered || record.TrialVersion);
+            record.IsValid = !record.RegChecked || record.IsRegistered || record.TrialVersion;
 
             return record;
         }
@@ -314,7 +314,7 @@ namespace MediaBrowser.Common.Implementations.Security
 
             var isInTrial = expirationDate > DateTime.UtcNow;
 
-            return (isInTrial && !isRegistered);
+            return isInTrial && !isRegistered;
         }
 
         /// <summary>

+ 1 - 2
MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Serialization;
 using System;
 using System.IO;
 using CommonIO;

+ 0 - 1
MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs

@@ -4,7 +4,6 @@ using System.Collections.Concurrent;
 using System.IO;
 using System.Xml;
 using CommonIO;
-using MediaBrowser.Common.IO;
 
 namespace MediaBrowser.Common.Implementations.Serialization
 {

+ 0 - 2
MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs

@@ -2,8 +2,6 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
-using System.Reflection;
-using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Common.Net;

+ 2 - 3
MediaBrowser.Common.Implementations/Updates/InstallationManager.cs

@@ -1,7 +1,6 @@
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Events;
 using MediaBrowser.Common.Implementations.Security;
-using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Plugins;
 using MediaBrowser.Common.Progress;
@@ -200,7 +199,7 @@ namespace MediaBrowser.Common.Implementations.Updates
                 {
                     var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList();
 
-                    if ((DateTime.UtcNow - _lastPackageUpdateTime) > GetCacheLength())
+                    if (DateTime.UtcNow - _lastPackageUpdateTime > GetCacheLength())
                     {
                         UpdateCachedPackages(CancellationToken.None, false);
                     }
@@ -233,7 +232,7 @@ namespace MediaBrowser.Common.Implementations.Updates
 
             try
             {
-                if ((DateTime.UtcNow - _lastPackageUpdateTime) < GetCacheLength())
+                if (DateTime.UtcNow - _lastPackageUpdateTime < GetCacheLength())
                 {
                     return;
                 }

+ 1 - 1
MediaBrowser.Common/IO/ProgressStream.cs

@@ -147,7 +147,7 @@ namespace MediaBrowser.Common.IO
             BytesProcessed += read;
 
             double percent = BytesProcessed;
-            percent /= (ReadLength ?? BaseStream.Length);
+            percent /= ReadLength ?? BaseStream.Length;
             percent *= 100;
 
             ProgressAction(percent);

+ 0 - 1
MediaBrowser.Common/Security/ISecurityManager.cs

@@ -1,4 +1,3 @@
-using System;
 using MediaBrowser.Model.Entities;
 using System.Threading.Tasks;
 

+ 1 - 1
MediaBrowser.Controller/Channels/Channel.cs

@@ -38,7 +38,7 @@ namespace MediaBrowser.Controller.Channels
             set { }
         }
 
-        public override async Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
+        protected override async Task<QueryResult<BaseItem>> GetItemsInternal(InternalItemsQuery query)
         {
             try
             {

+ 0 - 102
MediaBrowser.Controller/Channels/ChannelAudioItem.cs

@@ -1,102 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Model.Channels;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Threading;
-
-namespace MediaBrowser.Controller.Channels
-{
-    public class ChannelAudioItem : Audio
-    {
-        public ChannelMediaContentType ContentType { get; set; }
-
-        public List<ChannelMediaInfo> ChannelMediaSources { get; set; }
-
-        public override UnratedItem GetBlockUnratedType()
-        {
-            return UnratedItem.ChannelContent;
-        }
-
-        protected override string CreateUserDataKey()
-        {
-            return ExternalId;
-        }
-
-        [IgnoreDataMember]
-        public override bool SupportsLocalMetadata
-        {
-            get
-            {
-                return false;
-            }
-        }
-
-        public override bool IsSaveLocalMetadataEnabled()
-        {
-            return false;
-        }
-
-        public ChannelAudioItem()
-        {
-            ChannelMediaSources = new List<ChannelMediaInfo>();
-        }
-
-        [IgnoreDataMember]
-        public override LocationType LocationType
-        {
-            get
-            {
-                if (string.IsNullOrEmpty(Path))
-                {
-                    return LocationType.Remote;
-                }
-                
-                return base.LocationType;
-            }
-        }
-
-        protected override string GetInternalMetadataPath(string basePath)
-        {
-            return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N"));
-        }
-
-        public override IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
-        {
-            var sources = ChannelManager.GetStaticMediaSources(this, false, CancellationToken.None)
-                       .Result.ToList();
-
-            if (sources.Count > 0)
-            {
-                return sources;
-            }
-
-            var list = base.GetMediaSources(enablePathSubstitution).ToList();
-
-            foreach (var mediaSource in list)
-            {
-                if (string.IsNullOrWhiteSpace(mediaSource.Path))
-                {
-                    mediaSource.Type = MediaSourceType.Placeholder;
-                }
-            }
-
-            return list;
-        }
-
-        public override bool CanDelete()
-        {
-            return false;
-        }
-
-        public override bool IsVisibleStandalone(User user)
-        {
-            return IsVisibleStandaloneInternal(user, false) && ChannelVideoItem.IsChannelVisible(this, user);
-        }
-    }
-}

+ 0 - 90
MediaBrowser.Controller/Channels/ChannelFolderItem.cs

@@ -1,90 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Model.Channels;
-using MediaBrowser.Model.Querying;
-using MediaBrowser.Model.Users;
-using System;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Entities;
-
-namespace MediaBrowser.Controller.Channels
-{
-    public class ChannelFolderItem : Folder
-    {
-        public ChannelFolderType ChannelFolderType { get; set; }
-
-        protected override bool GetBlockUnratedValue(UserPolicy config)
-        {
-            // Don't block. 
-            return false;
-        }
-
-        public override UnratedItem GetBlockUnratedType()
-        {
-            return UnratedItem.ChannelContent;
-        }
-
-        [IgnoreDataMember]
-        public override bool SupportsLocalMetadata
-        {
-            get
-            {
-                return false;
-            }
-        }
-
-        public override bool IsSaveLocalMetadataEnabled()
-        {
-            return false;
-        }
-
-        protected override string CreateUserDataKey()
-        {
-            return ExternalId;
-        }
-
-        public override async Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
-        {
-            try
-            {
-                // Don't blow up here because it could cause parent screens with other content to fail
-                return await ChannelManager.GetChannelItemsInternal(new ChannelItemQuery
-                {
-                    ChannelId = ChannelId,
-                    FolderId = Id.ToString("N"),
-                    Limit = query.Limit,
-                    StartIndex = query.StartIndex,
-                    UserId = query.User.Id.ToString("N"),
-                    SortBy = query.SortBy,
-                    SortOrder = query.SortOrder
-
-                }, new Progress<double>(), CancellationToken.None);
-            }
-            catch
-            {
-                // Already logged at lower levels
-                return new QueryResult<BaseItem>
-                {
-
-                };
-            }
-        }
-
-        protected override string GetInternalMetadataPath(string basePath)
-        {
-            return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N"));
-        }
-
-        public override bool CanDelete()
-        {
-            return false;
-        }
-
-        public override bool IsVisibleStandalone(User user)
-        {
-            return IsVisibleStandaloneInternal(user, false) && ChannelVideoItem.IsChannelVisible(this, user);
-        }
-    }
-}

+ 0 - 128
MediaBrowser.Controller/Channels/ChannelVideoItem.cs

@@ -1,128 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Channels;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Threading;
-
-namespace MediaBrowser.Controller.Channels
-{
-    public class ChannelVideoItem : Video
-    {
-        public ChannelMediaContentType ContentType { get; set; }
-
-        public List<ChannelMediaInfo> ChannelMediaSources { get; set; }
-
-        protected override string CreateUserDataKey()
-        {
-            if (ContentType == ChannelMediaContentType.MovieExtra)
-            {
-                var key = this.GetProviderId(MetadataProviders.Imdb) ?? this.GetProviderId(MetadataProviders.Tmdb);
-
-                if (!string.IsNullOrWhiteSpace(key))
-                {
-                    key = key + "-" + ExtraType.ToString().ToLower();
-
-                    // Make sure different trailers have their own data.
-                    if (RunTimeTicks.HasValue)
-                    {
-                        key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
-                    }
-
-                    return key;
-                }
-            }
-
-            return ExternalId;
-        }
-
-        public override UnratedItem GetBlockUnratedType()
-        {
-            return UnratedItem.ChannelContent;
-        }
-
-        [IgnoreDataMember]
-        public override bool SupportsLocalMetadata
-        {
-            get
-            {
-                return false;
-            }
-        }
-
-        public override bool IsSaveLocalMetadataEnabled()
-        {
-            return false;
-        }
-
-        public ChannelVideoItem()
-        {
-            ChannelMediaSources = new List<ChannelMediaInfo>();
-        }
-
-        [IgnoreDataMember]
-        public override LocationType LocationType
-        {
-            get
-            {
-                if (string.IsNullOrEmpty(Path))
-                {
-                    return LocationType.Remote;
-                }
-
-                return base.LocationType;
-            }
-        }
-
-        public override IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
-        {
-            var sources = ChannelManager.GetStaticMediaSources(this, false, CancellationToken.None)
-                       .Result.ToList();
-
-            if (sources.Count > 0)
-            {
-                return sources;
-            }
-
-            var list = base.GetMediaSources(enablePathSubstitution).ToList();
-
-            foreach (var mediaSource in list)
-            {
-                if (string.IsNullOrWhiteSpace(mediaSource.Path))
-                {
-                    mediaSource.Type = MediaSourceType.Placeholder;
-                }
-            }
-
-            return list;
-        }
-
-        protected override string GetInternalMetadataPath(string basePath)
-        {
-            return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N"));
-        }
-
-        public override bool CanDelete()
-        {
-            return false;
-        }
-
-        public override bool IsVisibleStandalone(User user)
-        {
-            return IsVisibleStandaloneInternal(user, false) && IsChannelVisible(this, user);
-        }
-
-        internal static bool IsChannelVisible(BaseItem item, User user)
-        {
-            var channel = ChannelManager.GetChannel(item.ChannelId);
-
-            return channel.IsVisible(user);
-        }
-    }
-}

+ 0 - 11
MediaBrowser.Controller/Channels/IChannelItem.cs

@@ -1,11 +0,0 @@
-using MediaBrowser.Controller.Entities;
-
-namespace MediaBrowser.Controller.Channels
-{
-    public interface IChannelItem : IHasImages, IHasTags
-    {
-        string ChannelId { get; set; }
-
-        string ExternalId { get; set; }
-    }
-}

+ 0 - 18
MediaBrowser.Controller/Channels/IChannelMediaItem.cs

@@ -1,18 +0,0 @@
-using MediaBrowser.Model.Channels;
-using MediaBrowser.Model.Entities;
-using System.Collections.Generic;
-
-namespace MediaBrowser.Controller.Channels
-{
-    public interface IChannelMediaItem : IChannelItem
-    {
-        long? RunTimeTicks { get; set; }
-        string MediaType { get; }
-
-        ChannelMediaContentType ContentType { get; set; }
-
-        ExtraType? ExtraType { get; set; }
-
-        List<ChannelMediaInfo> ChannelMediaSources { get; set; }
-    }
-}

Some files were not shown because too many files changed in this diff