aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2013-12-05 22:39:44 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2013-12-05 22:39:44 -0500
commit5f0d8000a5ec26fd66c5f188f3bb517bb139b74b (patch)
tree769514a446fc33ba812d1a9a05a66f0845c9e590
parentebe483db9a5d31528a644200a71f2b36ac2864bd (diff)
moved media streams to the database
-rw-r--r--MediaBrowser.Api/LibraryService.cs38
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs22
-rw-r--r--MediaBrowser.Api/Playback/Hls/AudioHlsService.cs13
-rw-r--r--MediaBrowser.Api/Playback/Hls/BaseHlsService.cs21
-rw-r--r--MediaBrowser.Api/Playback/Hls/VideoHlsService.cs26
-rw-r--r--MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs5
-rw-r--r--MediaBrowser.Api/UserLibrary/ItemsService.cs12
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs14
-rw-r--r--MediaBrowser.Controller/Entities/Book.cs15
-rw-r--r--MediaBrowser.Controller/Entities/IHasMediaStreams.cs10
-rw-r--r--MediaBrowser.Controller/Entities/IHasScreenshots.cs5
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs37
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj2
-rw-r--r--MediaBrowser.Controller/MediaInfo/FFMpegManager.cs18
-rw-r--r--MediaBrowser.Controller/Persistence/IItemRepository.cs16
-rw-r--r--MediaBrowser.Controller/Persistence/MediaStreamQuery.cs26
-rw-r--r--MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs2
-rw-r--r--MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj3
-rw-r--r--MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj3
-rw-r--r--MediaBrowser.Model/Dto/ItemCounts.cs3
-rw-r--r--MediaBrowser.Model/Entities/IHasMediaStreams.cs26
-rw-r--r--MediaBrowser.Model/Entities/MediaStream.cs6
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj1
-rw-r--r--MediaBrowser.Providers/ImageFromMediaLocationProvider.cs7
-rw-r--r--MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs25
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs56
-rw-r--r--MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/Savers/XmlSaverHelpers.cs117
-rw-r--r--MediaBrowser.Server.Implementations/BdInfo/BdInfoExaminer.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs6
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj1
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs24
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs377
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs18
-rw-r--r--MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Sorting/VideoBitRateComparer.cs12
-rw-r--r--MediaBrowser.ServerApplication/ApplicationHost.cs2
-rw-r--r--MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs2
39 files changed, 653 insertions, 328 deletions
diff --git a/MediaBrowser.Api/LibraryService.cs b/MediaBrowser.Api/LibraryService.cs
index 51eef225e..48037e801 100644
--- a/MediaBrowser.Api/LibraryService.cs
+++ b/MediaBrowser.Api/LibraryService.cs
@@ -370,44 +370,6 @@ namespace MediaBrowser.Api
UniqueTypes = items.Select(i => i.GetClientTypeName()).Distinct().ToList()
};
- var people = items.SelectMany(i => i.People)
- .Select(i => i.Name)
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .Select(i =>
- {
- try
- {
- return _libraryManager.GetPerson(i);
- }
- catch
- {
- return null;
- }
- })
- .Where(i => i != null)
- .ToList();
-
- people = request.UserId.HasValue ? FilterItems(people, request, request.UserId.Value).ToList() : people;
- counts.PersonCount = people.Count;
-
- var artists = _libraryManager.GetAllArtists(items)
- .Select(i =>
- {
- try
- {
- return _libraryManager.GetArtist(i);
- }
- catch
- {
- return null;
- }
- })
- .Where(i => i != null)
- .ToList();
-
- artists = request.UserId.HasValue ? FilterItems(artists, request, request.UserId.Value).ToList() : artists;
- counts.ArtistCount = artists.Count;
-
return ToOptimizedResult(counts);
}
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 9ad0703ae..e34f0888d 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -7,6 +7,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaInfo;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -59,7 +60,9 @@ namespace MediaBrowser.Api.Playback
protected IDtoService DtoService { get; private set; }
protected IFileSystem FileSystem { get; private set; }
-
+
+ protected IItemRepository ItemRepository { get; private set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
/// </summary>
@@ -68,8 +71,9 @@ namespace MediaBrowser.Api.Playback
/// <param name="libraryManager">The library manager.</param>
/// <param name="isoManager">The iso manager.</param>
/// <param name="mediaEncoder">The media encoder.</param>
- protected BaseStreamingService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem)
+ protected BaseStreamingService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository)
{
+ ItemRepository = itemRepository;
FileSystem = fileSystem;
DtoService = dtoService;
ApplicationPaths = appPaths;
@@ -803,6 +807,12 @@ namespace MediaBrowser.Api.Playback
var videoRequest = request as VideoStreamRequest;
+ var mediaStreams = ItemRepository.GetMediaStreams(new MediaStreamQuery
+ {
+ ItemId = item.Id
+
+ }).ToList();
+
if (videoRequest != null)
{
if (!videoRequest.VideoCodec.HasValue)
@@ -810,13 +820,13 @@ namespace MediaBrowser.Api.Playback
videoRequest.VideoCodec = InferVideoCodec(url);
}
- state.VideoStream = GetMediaStream(media.MediaStreams, videoRequest.VideoStreamIndex, MediaStreamType.Video);
- state.SubtitleStream = GetMediaStream(media.MediaStreams, videoRequest.SubtitleStreamIndex, MediaStreamType.Subtitle, false);
- state.AudioStream = GetMediaStream(media.MediaStreams, videoRequest.AudioStreamIndex, MediaStreamType.Audio);
+ state.VideoStream = GetMediaStream(mediaStreams, videoRequest.VideoStreamIndex, MediaStreamType.Video);
+ state.SubtitleStream = GetMediaStream(mediaStreams, videoRequest.SubtitleStreamIndex, MediaStreamType.Subtitle, false);
+ state.AudioStream = GetMediaStream(mediaStreams, videoRequest.AudioStreamIndex, MediaStreamType.Audio);
}
else
{
- state.AudioStream = GetMediaStream(media.MediaStreams, null, MediaStreamType.Audio, true);
+ state.AudioStream = GetMediaStream(mediaStreams, null, MediaStreamType.Audio, true);
}
return state;
diff --git a/MediaBrowser.Api/Playback/Hls/AudioHlsService.cs b/MediaBrowser.Api/Playback/Hls/AudioHlsService.cs
index 6636db05d..073cd1b7f 100644
--- a/MediaBrowser.Api/Playback/Hls/AudioHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/AudioHlsService.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
using ServiceStack.ServiceHost;
@@ -25,16 +26,8 @@ namespace MediaBrowser.Api.Playback.Hls
/// </summary>
public class AudioHlsService : BaseHlsService
{
- /// <summary>
- /// Initializes a new instance of the <see cref="AudioHlsService" /> class.
- /// </summary>
- /// <param name="appPaths">The app paths.</param>
- /// <param name="userManager">The user manager.</param>
- /// <param name="libraryManager">The library manager.</param>
- /// <param name="isoManager">The iso manager.</param>
- /// <param name="mediaEncoder">The media encoder.</param>
- public AudioHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem)
- : base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem)
+ public AudioHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository)
+ : base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository)
{
}
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index 3e96cf2f8..1e5e8b82d 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -6,6 +6,7 @@ using MediaBrowser.Controller;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
using System;
@@ -21,6 +22,11 @@ namespace MediaBrowser.Api.Playback.Hls
/// </summary>
public abstract class BaseHlsService : BaseStreamingService
{
+ protected BaseHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository)
+ : base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository)
+ {
+ }
+
protected override string GetOutputFilePath(StreamState state)
{
var folder = ApplicationPaths.EncodedMediaCachePath;
@@ -31,19 +37,6 @@ namespace MediaBrowser.Api.Playback.Hls
}
/// <summary>
- /// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
- /// </summary>
- /// <param name="appPaths">The app paths.</param>
- /// <param name="userManager">The user manager.</param>
- /// <param name="libraryManager">The library manager.</param>
- /// <param name="isoManager">The iso manager.</param>
- /// <param name="mediaEncoder">The media encoder.</param>
- protected BaseHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem)
- : base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem)
- {
- }
-
- /// <summary>
/// Gets the audio arguments.
/// </summary>
/// <param name="state">The state.</param>
@@ -260,7 +253,7 @@ namespace MediaBrowser.Api.Playback.Hls
var itsOffsetMs = hlsVideoRequest == null
? 0
- : ((GetHlsVideoStream) state.VideoRequest).TimeStampOffsetMs;
+ : ((GetHlsVideoStream)state.VideoRequest).TimeStampOffsetMs;
var itsOffset = itsOffsetMs == 0 ? string.Empty : string.Format("-itsoffset {0} ", TimeSpan.FromMilliseconds(itsOffsetMs).TotalSeconds);
diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
index dfd18ab15..b194a47fe 100644
--- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.IO;
using ServiceStack.ServiceHost;
using System;
@@ -31,17 +32,8 @@ namespace MediaBrowser.Api.Playback.Hls
/// </summary>
public class VideoHlsService : BaseHlsService
{
- /// <summary>
- /// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
- /// </summary>
- /// <param name="appPaths">The app paths.</param>
- /// <param name="userManager">The user manager.</param>
- /// <param name="libraryManager">The library manager.</param>
- /// <param name="isoManager">The iso manager.</param>
- /// <param name="mediaEncoder">The media encoder.</param>
- /// <param name="dtoService">The dto service.</param>
- public VideoHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem)
- : base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem)
+ public VideoHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository)
+ : base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository)
{
}
@@ -95,13 +87,13 @@ namespace MediaBrowser.Api.Playback.Hls
{
volParam = ",volume=2.000000";
}
-
+
if (state.Request.AudioSampleRate.HasValue)
{
- audioSampleRate= state.Request.AudioSampleRate.Value + ":";
+ audioSampleRate = state.Request.AudioSampleRate.Value + ":";
}
- args += string.Format(" -af \"adelay=1,aresample={0}async=1000{1}\"",audioSampleRate, volParam);
+ args += string.Format(" -af \"adelay=1,aresample={0}async=1000{1}\"", audioSampleRate, volParam);
return args;
}
@@ -130,7 +122,7 @@ namespace MediaBrowser.Api.Playback.Hls
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsExternal &&
(state.SubtitleStream.Codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) != -1 ||
state.SubtitleStream.Codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1);
-
+
var args = "-codec:v:0 " + codec + " -preset superfast" + keyFrameArg;
var bitrate = GetVideoBitrateParam(state);
@@ -139,7 +131,7 @@ namespace MediaBrowser.Api.Playback.Hls
{
args += string.Format(" -b:v {0} -maxrate ({0}*.85) -bufsize {0}", bitrate.Value.ToString(UsCulture));
}
-
+
// Add resolution params, if specified
if (!hasGraphicalSubs)
{
@@ -171,7 +163,7 @@ namespace MediaBrowser.Api.Playback.Hls
{
args += GetInternalGraphicalSubtitleParam(state, codec);
}
-
+
return args;
}
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index 1f0853e08..2447302f5 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -12,7 +12,6 @@ using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
-using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
@@ -25,13 +24,11 @@ namespace MediaBrowser.Api.Playback.Progressive
/// </summary>
public abstract class BaseProgressiveStreamingService : BaseStreamingService
{
- protected readonly IItemRepository ItemRepository;
protected readonly IImageProcessor ImageProcessor;
protected BaseProgressiveStreamingService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IItemRepository itemRepository, IDtoService dtoService, IImageProcessor imageProcessor, IFileSystem fileSystem) :
- base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem)
+ base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository)
{
- ItemRepository = itemRepository;
ImageProcessor = imageProcessor;
}
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index 7cb624af8..380e09463 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -226,7 +226,7 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "HasTvdbId", Description = "Optional filter by items that have a tvdb id or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? HasTvdbId { get; set; }
-
+
[ApiMember(Name = "IsYearMismatched", Description = "Optional filter by items that are potentially misidentified.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsYearMismatched { get; set; }
}
@@ -984,15 +984,9 @@ namespace MediaBrowser.Api.UserLibrary
if (request.HasSubtitles.HasValue)
{
- items = items.OfType<Video>().Where(i =>
- {
- if (request.HasSubtitles.Value)
- {
- return i.MediaStreams != null && i.MediaStreams.Any(m => m.Type == MediaStreamType.Subtitle);
- }
+ var val = request.HasSubtitles.Value;
- return i.MediaStreams == null || i.MediaStreams.All(m => m.Type != MediaStreamType.Subtitle);
- });
+ items = items.OfType<Video>().Where(i => val == i.HasSubtitles);
}
if (request.HasParentalRating.HasValue)
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index 2a7aa4fea..63c907c1f 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Model.Entities;
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
@@ -13,7 +12,6 @@ namespace MediaBrowser.Controller.Entities.Audio
{
public Audio()
{
- MediaStreams = new List<MediaStream>();
Artists = new List<string>();
}
@@ -22,13 +20,13 @@ namespace MediaBrowser.Controller.Entities.Audio
/// </summary>
/// <value>The language.</value>
public string Language { get; set; }
-
+
/// <summary>
- /// Gets or sets the media streams.
+ /// Gets or sets a value indicating whether this instance has embedded image.
/// </summary>
- /// <value>The media streams.</value>
- public List<MediaStream> MediaStreams { get; set; }
-
+ /// <value><c>true</c> if this instance has embedded image; otherwise, <c>false</c>.</value>
+ public bool HasEmbeddedImage { get; set; }
+
/// <summary>
/// Override this to true if class should be grouped under a container in indicies
/// The container class should be defined via IndexContainer
diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs
index 20df731a7..87b90b824 100644
--- a/MediaBrowser.Controller/Entities/Book.cs
+++ b/MediaBrowser.Controller/Entities/Book.cs
@@ -1,7 +1,8 @@
-
+using System.Collections.Generic;
+
namespace MediaBrowser.Controller.Entities
{
- public class Book : BaseItem
+ public class Book : BaseItem, IHasTags
{
public override string MediaType
{
@@ -10,6 +11,11 @@ namespace MediaBrowser.Controller.Entities
return Model.Entities.MediaType.Book;
}
}
+ /// <summary>
+ /// Gets or sets the tags.
+ /// </summary>
+ /// <value>The tags.</value>
+ public List<string> Tags { get; set; }
public string SeriesName { get; set; }
@@ -31,5 +37,10 @@ namespace MediaBrowser.Controller.Entities
return !IsInMixedFolder;
}
}
+
+ public Book()
+ {
+ Tags = new List<string>();
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/IHasMediaStreams.cs b/MediaBrowser.Controller/Entities/IHasMediaStreams.cs
new file mode 100644
index 000000000..b700ef628
--- /dev/null
+++ b/MediaBrowser.Controller/Entities/IHasMediaStreams.cs
@@ -0,0 +1,10 @@
+
+namespace MediaBrowser.Controller.Entities
+{
+ /// <summary>
+ /// This is essentially a marker interface
+ /// </summary>
+ public interface IHasMediaStreams
+ {
+ }
+}
diff --git a/MediaBrowser.Controller/Entities/IHasScreenshots.cs b/MediaBrowser.Controller/Entities/IHasScreenshots.cs
index 341d6403f..2276c707a 100644
--- a/MediaBrowser.Controller/Entities/IHasScreenshots.cs
+++ b/MediaBrowser.Controller/Entities/IHasScreenshots.cs
@@ -12,5 +12,10 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value>The screenshot image paths.</value>
List<string> ScreenshotImagePaths { get; set; }
+
+ /// <summary>
+ /// Validates the screenshots.
+ /// </summary>
+ void ValidateScreenshots();
}
}
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 9b02571b0..425e418ed 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -22,12 +22,29 @@ namespace MediaBrowser.Controller.Entities
public Video()
{
- MediaStreams = new List<MediaStream>();
PlayableStreamFileNames = new List<string>();
AdditionalPartIds = new List<Guid>();
}
/// <summary>
+ /// Gets or sets a value indicating whether this instance has subtitles.
+ /// </summary>
+ /// <value><c>true</c> if this instance has subtitles; otherwise, <c>false</c>.</value>
+ public bool HasSubtitles { get; set; }
+
+ /// <summary>
+ /// Gets or sets the video bit rate.
+ /// </summary>
+ /// <value>The video bit rate.</value>
+ public int? VideoBitRate { get; set; }
+
+ /// <summary>
+ /// Gets or sets the default index of the video stream.
+ /// </summary>
+ /// <value>The default index of the video stream.</value>
+ public int? DefaultVideoStreamIndex { get; set; }
+
+ /// <summary>
/// Gets or sets the type of the video.
/// </summary>
/// <value>The type of the video.</value>
@@ -46,12 +63,6 @@ namespace MediaBrowser.Controller.Entities
public Video3DFormat? Video3DFormat { get; set; }
/// <summary>
- /// Gets or sets the media streams.
- /// </summary>
- /// <value>The media streams.</value>
- public List<MediaStream> MediaStreams { get; set; }
-
- /// <summary>
/// If the video is a folder-rip, this will hold the file list for the largest playlist
/// </summary>
public List<string> PlayableStreamFileNames { get; set; }
@@ -70,7 +81,7 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value>The aspect ratio.</value>
public string AspectRatio { get; set; }
-
+
/// <summary>
/// Should be overridden to return the proper folder where metadata lives
/// </summary>
@@ -123,16 +134,6 @@ namespace MediaBrowser.Controller.Entities
}
/// <summary>
- /// The default video stream for this video. Use this to determine media info for this item.
- /// </summary>
- /// <value>The default video stream.</value>
- [IgnoreDataMember]
- public MediaStream DefaultVideoStream
- {
- get { return MediaStreams != null ? MediaStreams.FirstOrDefault(s => s.Type == MediaStreamType.Video) : null; }
- }
-
- /// <summary>
/// Gets a value indicating whether [is3 D].
/// </summary>
/// <value><c>true</c> if [is3 D]; otherwise, <c>false</c>.</value>
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 03aa1413b..21c9e39f1 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -93,6 +93,7 @@
<Compile Include="Entities\IHasBudget.cs" />
<Compile Include="Entities\IHasCriticRating.cs" />
<Compile Include="Entities\IHasLanguage.cs" />
+ <Compile Include="Entities\IHasMediaStreams.cs" />
<Compile Include="Entities\IHasProductionLocations.cs" />
<Compile Include="Entities\IHasScreenshots.cs" />
<Compile Include="Entities\IHasSoundtracks.cs" />
@@ -124,6 +125,7 @@
<Compile Include="Localization\ILocalizationManager.cs" />
<Compile Include="Notifications\INotificationsRepository.cs" />
<Compile Include="Notifications\NotificationUpdateEventArgs.cs" />
+ <Compile Include="Persistence\MediaStreamQuery.cs" />
<Compile Include="Providers\IDynamicInfoProvider.cs" />
<Compile Include="Providers\IImageProvider.cs" />
<Compile Include="Providers\NameParser.cs" />
diff --git a/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs b/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs
index fd1b12c2f..e53acfc02 100644
--- a/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs
+++ b/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs
@@ -93,7 +93,7 @@ namespace MediaBrowser.Controller.MediaInfo
return Path.Combine(_appPaths.CachePath, "subtitles");
}
}
-
+
/// <summary>
/// The first chapter ticks
/// </summary>
@@ -112,7 +112,7 @@ namespace MediaBrowser.Controller.MediaInfo
public async Task<bool> PopulateChapterImages(Video video, List<ChapterInfo> chapters, bool extractImages, bool saveChapters, CancellationToken cancellationToken)
{
// Can't extract images if there are no video streams
- if (video.MediaStreams == null || video.MediaStreams.All(m => m.Type != MediaStreamType.Video))
+ if (!video.DefaultVideoStreamIndex.HasValue)
{
return true;
}
@@ -164,7 +164,7 @@ namespace MediaBrowser.Controller.MediaInfo
var parentPath = Path.GetDirectoryName(path);
Directory.CreateDirectory(parentPath);
-
+
await _encoder.ExtractImage(inputPath, type, video.Video3DFormat, time, path, cancellationToken).ConfigureAwait(false);
chapter.ImagePath = path;
changesMade = true;
@@ -203,7 +203,17 @@ namespace MediaBrowser.Controller.MediaInfo
{
var ticksParam = offset.HasValue ? "_" + offset.Value.Ticks : "";
- var stream = input.MediaStreams[subtitleStreamIndex];
+ var stream = _itemRepo.GetMediaStreams(new MediaStreamQuery
+ {
+ ItemId = input.Id,
+ Index = subtitleStreamIndex
+
+ }).FirstOrDefault();
+
+ if (stream == null)
+ {
+ return null;
+ }
if (stream.IsExternal)
{
diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs
index e04f25605..3a5cb4e87 100644
--- a/MediaBrowser.Controller/Persistence/IItemRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs
@@ -95,6 +95,22 @@ namespace MediaBrowser.Controller.Persistence
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task SaveChildren(Guid parentId, IEnumerable<Guid> children, CancellationToken cancellationToken);
+
+ /// <summary>
+ /// Gets the media streams.
+ /// </summary>
+ /// <param name="query">The query.</param>
+ /// <returns>IEnumerable{MediaStream}.</returns>
+ IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query);
+
+ /// <summary>
+ /// Saves the media streams.
+ /// </summary>
+ /// <param name="id">The identifier.</param>
+ /// <param name="streams">The streams.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task.</returns>
+ Task SaveMediaStreams(Guid id, IEnumerable<MediaStream> streams, CancellationToken cancellationToken);
}
}
diff --git a/MediaBrowser.Controller/Persistence/MediaStreamQuery.cs b/MediaBrowser.Controller/Persistence/MediaStreamQuery.cs
new file mode 100644
index 000000000..10985f57d
--- /dev/null
+++ b/MediaBrowser.Controller/Persistence/MediaStreamQuery.cs
@@ -0,0 +1,26 @@
+using MediaBrowser.Model.Entities;
+using System;
+
+namespace MediaBrowser.Controller.Persistence
+{
+ public class MediaStreamQuery
+ {
+ /// <summary>
+ /// Gets or sets the type.
+ /// </summary>
+ /// <value>The type.</value>
+ public MediaStreamType? Type { get; set; }
+
+ /// <summary>
+ /// Gets or sets the index.
+ /// </summary>
+ /// <value>The index.</value>
+ public int? Index { get; set; }
+
+ /// <summary>
+ /// Gets or sets the item identifier.
+ /// </summary>
+ /// <value>The item identifier.</value>
+ public Guid ItemId { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs
index b39205b5d..7d9739448 100644
--- a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs
+++ b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs
@@ -1,6 +1,5 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using System;
using System.Collections.Generic;
@@ -46,6 +45,7 @@ namespace MediaBrowser.Controller.Resolvers
".3gp",
".webm",
".mts",
+ ".m2v",
".rec"
};
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index 67888aa46..f6e2725a6 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -143,9 +143,6 @@
<Compile Include="..\MediaBrowser.Model\Entities\DisplayPreferences.cs">
<Link>Entities\DisplayPreferences.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\Entities\IHasMediaStreams.cs">
- <Link>Entities\IHasMediaStreams.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\Entities\IHasProviderIds.cs">
<Link>Entities\IHasProviderIds.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index cfe4a5462..efafc7f62 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -130,9 +130,6 @@
<Compile Include="..\MediaBrowser.Model\Entities\DisplayPreferences.cs">
<Link>Entities\DisplayPreferences.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\Entities\IHasMediaStreams.cs">
- <Link>Entities\IHasMediaStreams.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\Entities\IHasProviderIds.cs">
<Link>Entities\IHasProviderIds.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model/Dto/ItemCounts.cs b/MediaBrowser.Model/Dto/ItemCounts.cs
index 34fe6ca64..34e2a1c3c 100644
--- a/MediaBrowser.Model/Dto/ItemCounts.cs
+++ b/MediaBrowser.Model/Dto/ItemCounts.cs
@@ -68,9 +68,6 @@ namespace MediaBrowser.Model.Dto
/// </summary>
/// <value>The unique types.</value>
public List<string> UniqueTypes { get; set; }
-
- public int PersonCount { get; set; }
- public int ArtistCount { get; set; }
public ItemCounts()
{
diff --git a/MediaBrowser.Model/Entities/IHasMediaStreams.cs b/MediaBrowser.Model/Entities/IHasMediaStreams.cs
deleted file mode 100644
index a00914146..000000000
--- a/MediaBrowser.Model/Entities/IHasMediaStreams.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Collections.Generic;
-
-namespace MediaBrowser.Model.Entities
-{
- /// <summary>
- /// This is essentially a marker interface
- /// </summary>
- public interface IHasMediaStreams
- {
- /// <summary>
- /// Gets or sets the media streams.
- /// </summary>
- /// <value>The media streams.</value>
- List<MediaStream> MediaStreams { get; set; }
- /// <summary>
- /// Gets or sets the path.
- /// </summary>
- /// <value>The path.</value>
- string Path { get; set; }
- /// <summary>
- /// Gets or sets the primary image path.
- /// </summary>
- /// <value>The primary image path.</value>
- string PrimaryImagePath { get; }
- }
-}
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index 5e85369b9..133631649 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -19,10 +19,10 @@ namespace MediaBrowser.Model.Entities
public string Language { get; set; }
/// <summary>
- /// Gets or sets the type of the scan.
+ /// Gets or sets a value indicating whether this instance is interlaced.
/// </summary>
- /// <value>The type of the scan.</value>
- public string ScanType { get; set; }
+ /// <value><c>true</c> if this instance is interlaced; otherwise, <c>false</c>.</value>
+ public bool IsInterlaced { get; set; }
/// <summary>
/// Gets or sets the channel layout.
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 103e583ae..5175bee91 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -125,7 +125,6 @@
<Compile Include="Entities\ParentalRating.cs" />
<Compile Include="Dto\StreamOptions.cs" />
<Compile Include="Entities\VirtualFolderInfo.cs" />
- <Compile Include="Entities\IHasMediaStreams.cs" />
<Compile Include="Extensions\ModelExtensions.cs" />
<Compile Include="IO\IZipClient.cs" />
<Compile Include="Logging\ILogger.cs" />
diff --git a/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs b/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs
index 70d9e788d..3914ba264 100644
--- a/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs
+++ b/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs
@@ -108,7 +108,12 @@ namespace MediaBrowser.Providers
// Make sure current backdrop paths still exist
item.ValidateBackdrops();
- item.ValidateScreenshots();
+
+ var hasScreenshots = item as IHasScreenshots;
+ if (hasScreenshots != null)
+ {
+ hasScreenshots.ValidateScreenshots();
+ }
cancellationToken.ThrowIfCancellationRequested();
diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
index 683dd4231..914f5b290 100644
--- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
@@ -127,7 +127,7 @@ namespace MediaBrowser.Providers.MediaInfo
var audio = (Audio)item;
- if (string.IsNullOrEmpty(audio.PrimaryImagePath) && audio.MediaStreams.Any(s => s.Type == MediaStreamType.Video))
+ if (string.IsNullOrEmpty(audio.PrimaryImagePath) && audio.HasEmbeddedImage)
{
try
{
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs
index 3594c53c5..42ba2d7b0 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
@@ -19,9 +20,12 @@ namespace MediaBrowser.Providers.MediaInfo
/// </summary>
public class FFProbeAudioInfoProvider : BaseFFProbeProvider<Audio>
{
- public FFProbeAudioInfoProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IMediaEncoder mediaEncoder, IJsonSerializer jsonSerializer)
+ private readonly IItemRepository _itemRepo;
+
+ public FFProbeAudioInfoProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IMediaEncoder mediaEncoder, IJsonSerializer jsonSerializer, IItemRepository itemRepo)
: base(logManager, configurationManager, mediaEncoder, jsonSerializer)
{
+ _itemRepo = itemRepo;
}
public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
@@ -38,7 +42,7 @@ namespace MediaBrowser.Providers.MediaInfo
cancellationToken.ThrowIfCancellationRequested();
- Fetch(myItem, cancellationToken, result);
+ await Fetch(myItem, cancellationToken, result).ConfigureAwait(false);
SetLastRefreshed(item, DateTime.UtcNow);
@@ -51,22 +55,19 @@ namespace MediaBrowser.Providers.MediaInfo
/// <param name="audio">The audio.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="data">The data.</param>
- /// <param name="isoMount">The iso mount.</param>
/// <returns>Task.</returns>
- protected void Fetch(Audio audio, CancellationToken cancellationToken, MediaInfoResult data)
+ protected Task Fetch(Audio audio, CancellationToken cancellationToken, MediaInfoResult data)
{
- if (data.streams == null)
- {
- Logger.Error("Audio item has no streams: " + audio.Path);
- return;
- }
+ var internalStreams = data.streams ?? new MediaStreamInfo[] { };
- audio.MediaStreams = data.streams.Select(s => GetMediaStream(s, data.format))
+ var mediaStreams = internalStreams.Select(s => GetMediaStream(s, data.format))
.Where(i => i != null)
.ToList();
+ audio.HasEmbeddedImage = mediaStreams.Any(i => i.Type == MediaStreamType.Video);
+
// Get the first audio stream
- var stream = data.streams.FirstOrDefault(s => s.codec_type.Equals("audio", StringComparison.OrdinalIgnoreCase));
+ var stream = internalStreams.FirstOrDefault(s => s.codec_type.Equals("audio", StringComparison.OrdinalIgnoreCase));
if (stream != null)
{
@@ -90,6 +91,8 @@ namespace MediaBrowser.Providers.MediaInfo
{
FetchDataFromTags(audio, data.format.tags);
}
+
+ return _itemRepo.SaveMediaStreams(audio.Id, mediaStreams, cancellationToken);
}
/// <summary>
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs
index 4fb65a764..c09076bff 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs
@@ -304,11 +304,17 @@ namespace MediaBrowser.Providers.MediaInfo
}
}
+ List<MediaStream> mediaStreams;
+
if (data.streams != null)
{
- video.MediaStreams = data.streams.Select(s => GetMediaStream(s, data.format))
- .Where(i => i != null)
- .ToList();
+ mediaStreams = data.streams.Select(s => GetMediaStream(s, data.format))
+ .Where(i => i != null)
+ .ToList();
+ }
+ else
+ {
+ mediaStreams = new List<MediaStream>();
}
var chapters = data.Chapters ?? new List<ChapterInfo>();
@@ -316,22 +322,28 @@ namespace MediaBrowser.Providers.MediaInfo
if (video.VideoType == VideoType.BluRay || (video.IsoType.HasValue && video.IsoType.Value == IsoType.BluRay))
{
var inputPath = isoMount != null ? isoMount.MountedPath : video.Path;
- FetchBdInfo(video, chapters, inputPath, cancellationToken);
+ FetchBdInfo(video, chapters, mediaStreams, inputPath, cancellationToken);
}
- AddExternalSubtitles(video);
+ AddExternalSubtitles(video, mediaStreams);
FetchWtvInfo(video, force, data);
- video.IsHD = video.MediaStreams.Any(i => i.Type == MediaStreamType.Video && i.Width.HasValue && i.Width.Value >= 1270);
+ video.IsHD = mediaStreams.Any(i => i.Type == MediaStreamType.Video && i.Width.HasValue && i.Width.Value >= 1270);
- if (chapters.Count == 0 && video.MediaStreams.Any(i => i.Type == MediaStreamType.Video))
+ if (chapters.Count == 0 && mediaStreams.Any(i => i.Type == MediaStreamType.Video))
{
AddDummyChapters(video, chapters);
}
- await Kernel.Instance.FFMpegManager.PopulateChapterImages(video, chapters, false, false, cancellationToken).ConfigureAwait(false);
+ var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
+
+ video.VideoBitRate = videoStream == null ? null : videoStream.BitRate;
+ video.DefaultVideoStreamIndex = videoStream == null ? (int?)null : videoStream.Index;
+ video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);
+
+ await Kernel.Instance.FFMpegManager.PopulateChapterImages(video, chapters, false, false, cancellationToken).ConfigureAwait(false);
BaseProviderInfo providerInfo;
var videoFileChanged = false;
@@ -341,6 +353,8 @@ namespace MediaBrowser.Providers.MediaInfo
videoFileChanged = CompareDate(video) > providerInfo.LastRefreshed;
}
+ await _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken).ConfigureAwait(false);
+
// Only save chapters if forcing, if the video changed, or if there are not already any saved ones
if (force || videoFileChanged || _itemRepo.GetChapter(video.Id, 0) == null)
{
@@ -439,7 +453,8 @@ namespace MediaBrowser.Providers.MediaInfo
/// Adds the external subtitles.
/// </summary>
/// <param name="video">The video.</param>
- private void AddExternalSubtitles(Video video)
+ /// <param name="currentStreams">The current streams.</param>
+ private void AddExternalSubtitles(Video video, List<MediaStream> currentStreams)
{
var useParent = !video.ResolveArgs.IsDirectory;
@@ -452,7 +467,7 @@ namespace MediaBrowser.Providers.MediaInfo
? video.Parent.ResolveArgs.FileSystemChildren
: video.ResolveArgs.FileSystemChildren;
- var startIndex = video.MediaStreams == null ? 0 : video.MediaStreams.Count;
+ var startIndex = currentStreams.Count;
var streams = new List<MediaStream>();
var videoFileNameWithoutExtension = Path.GetFileNameWithoutExtension(video.Path);
@@ -503,11 +518,7 @@ namespace MediaBrowser.Providers.MediaInfo
}
}
- if (video.MediaStreams == null)
- {
- video.MediaStreams = new List<MediaStream>();
- }
- video.MediaStreams.AddRange(streams);
+ currentStreams.AddRange(streams);
}
/// <summary>
@@ -556,9 +567,10 @@ namespace MediaBrowser.Providers.MediaInfo
/// </summary>
/// <param name="item">The item.</param>
/// <param name="chapters">The chapters.</param>
+ /// <param name="mediaStreams">The media streams.</param>
/// <param name="inputPath">The input path.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- private void FetchBdInfo(BaseItem item, List<ChapterInfo> chapters, string inputPath, CancellationToken cancellationToken)
+ private void FetchBdInfo(BaseItem item, List<ChapterInfo> chapters, List<MediaStream> mediaStreams, string inputPath, CancellationToken cancellationToken)
{
var video = (Video)item;
@@ -570,7 +582,7 @@ namespace MediaBrowser.Providers.MediaInfo
int? currentWidth = null;
int? currentBitRate = null;
- var videoStream = video.MediaStreams.FirstOrDefault(s => s.Type == MediaStreamType.Video);
+ var videoStream = mediaStreams.FirstOrDefault(s => s.Type == MediaStreamType.Video);
// Grab the values that ffprobe recorded
if (videoStream != null)
@@ -581,9 +593,9 @@ namespace MediaBrowser.Providers.MediaInfo
}
// Fill video properties from the BDInfo result
- Fetch(video, result, chapters);
+ Fetch(video, mediaStreams, result, chapters);
- videoStream = video.MediaStreams.FirstOrDefault(s => s.Type == MediaStreamType.Video);
+ videoStream = mediaStreams.FirstOrDefault(s => s.Type == MediaStreamType.Video);
// Use the ffprobe values if these are empty
if (videoStream != null)
@@ -608,13 +620,15 @@ namespace MediaBrowser.Providers.MediaInfo
/// Fills video properties from the VideoStream of the largest playlist
/// </summary>
/// <param name="video">The video.</param>
+ /// <param name="mediaStreams">The media streams.</param>
/// <param name="stream">The stream.</param>
/// <param name="chapters">The chapters.</param>
- private void Fetch(Video video, BlurayDiscInfo stream, List<ChapterInfo> chapters)
+ private void Fetch(Video video, List<MediaStream> mediaStreams, BlurayDiscInfo stream, List<ChapterInfo> chapters)
{
// Check all input for null/empty/zero
- video.MediaStreams = stream.MediaStreams;
+ mediaStreams.Clear();
+ mediaStreams.AddRange(stream.MediaStreams);
video.MainFeaturePlaylistName = stream.PlaylistName;
diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
index b57742042..551f9d8f2 100644
--- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
@@ -128,7 +128,7 @@ namespace MediaBrowser.Providers.MediaInfo
}
// Can't extract if we didn't find a video stream in the file
- if (item.MediaStreams.All(m => m.Type != MediaStreamType.Video))
+ if (!item.DefaultVideoStreamIndex.HasValue)
{
return false;
}
diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
index a4e4ce1a8..522b2c90b 100644
--- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
+++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
@@ -529,8 +529,6 @@ namespace MediaBrowser.Providers.Savers
/// Appends the media info.
/// </summary>
/// <typeparam name="T"></typeparam>
- /// <param name="item">The item.</param>
- /// <param name="builder">The builder.</param>
public static void AddMediaInfo<T>(T item, StringBuilder builder, IItemRepository itemRepository)
where T : BaseItem, IHasMediaStreams
{
@@ -538,105 +536,38 @@ namespace MediaBrowser.Providers.Savers
builder.Append("<MediaInfo>");
- foreach (var stream in item.MediaStreams)
- {
- builder.Append("<" + stream.Type + ">");
-
- if (!string.IsNullOrEmpty(stream.Codec))
- {
- builder.Append("<Codec>" + SecurityElement.Escape(stream.Codec) + "</Codec>");
- builder.Append("<FFCodec>" + SecurityElement.Escape(stream.Codec) + "</FFCodec>");
- }
-
- if (stream.BitRate.HasValue)
- {
- builder.Append("<BitRate>" + stream.BitRate.Value.ToString(UsCulture) + "</BitRate>");
- }
-
- if (stream.Width.HasValue)
- {
- builder.Append("<Width>" + stream.Width.Value.ToString(UsCulture) + "</Width>");
- }
-
- if (stream.Height.HasValue)
- {
- builder.Append("<Height>" + stream.Height.Value.ToString(UsCulture) + "</Height>");
- }
-
- if (!string.IsNullOrEmpty(stream.AspectRatio))
- {
- builder.Append("<AspectRatio>" + SecurityElement.Escape(stream.AspectRatio) + "</AspectRatio>");
- }
-
- var framerate = stream.AverageFrameRate ?? stream.RealFrameRate;
-
- if (framerate.HasValue)
- {
- builder.Append("<FrameRate>" + framerate.Value.ToString(UsCulture) + "</FrameRate>");
- }
-
- if (!string.IsNullOrEmpty(stream.Language))
- {
- builder.Append("<Language>" + SecurityElement.Escape(stream.Language) + "</Language>");
- }
+ builder.Append("<Video>");
- if (!string.IsNullOrEmpty(stream.ScanType))
- {
- builder.Append("<ScanType>" + SecurityElement.Escape(stream.ScanType) + "</ScanType>");
- }
-
- if (stream.Channels.HasValue)
- {
- builder.Append("<Channels>" + stream.Channels.Value.ToString(UsCulture) + "</Channels>");
- }
-
- if (stream.SampleRate.HasValue)
- {
- builder.Append("<SamplingRate>" + stream.SampleRate.Value.ToString(UsCulture) + "</SamplingRate>");
- }
+ if (item.RunTimeTicks.HasValue)
+ {
+ var timespan = TimeSpan.FromTicks(item.RunTimeTicks.Value);
- builder.Append("<Default>" + SecurityElement.Escape(stream.IsDefault.ToString()) + "</Default>");
- builder.Append("<Forced>" + SecurityElement.Escape(stream.IsForced.ToString()) + "</Forced>");
+ builder.Append("<Duration>" + Convert.ToInt64(timespan.TotalMinutes).ToString(UsCulture) + "</Duration>");
+ builder.Append("<DurationSeconds>" + Convert.ToInt64(timespan.TotalSeconds).ToString(UsCulture) + "</DurationSeconds>");
+ }
- if (stream.Type == MediaStreamType.Video)
+ if (video != null && video.Video3DFormat.HasValue)
+ {
+ switch (video.Video3DFormat.Value)
{
- if (item.RunTimeTicks.HasValue)
- {
- var timespan = TimeSpan.FromTicks(item.RunTimeTicks.Value);
-
- builder.Append("<Duration>" + Convert.ToInt64(timespan.TotalMinutes).ToString(UsCulture) + "</Duration>");
- builder.Append("<DurationSeconds>" + Convert.ToInt64(timespan.TotalSeconds).ToString(UsCulture) + "</DurationSeconds>");
- }
-
- if (video != null && video.Video3DFormat.HasValue)
- {
- switch (video.Video3DFormat.Value)
- {
- case Video3DFormat.FullSideBySide:
- builder.Append("<Format3D>FSBS</Format3D>");
- break;
- case Video3DFormat.FullTopAndBottom:
- builder.Append("<Format3D>FTAB</Format3D>");
- break;
- case Video3DFormat.HalfSideBySide:
- builder.Append("<Format3D>HSBS</Format3D>");
- break;
- case Video3DFormat.HalfTopAndBottom:
- builder.Append("<Format3D>HTAB</Format3D>");
- break;
- }
- }
+ case Video3DFormat.FullSideBySide:
+ builder.Append("<Format3D>FSBS</Format3D>");
+ break;
+ case Video3DFormat.FullTopAndBottom:
+ builder.Append("<Format3D>FTAB</Format3D>");
+ break;
+ case Video3DFormat.HalfSideBySide:
+ builder.Append("<Format3D>HSBS</Format3D>");
+ break;
+ case Video3DFormat.HalfTopAndBottom:
+ builder.Append("<Format3D>HTAB</Format3D>");
+ break;
}
-
- builder.Append("</" + stream.Type + ">");
}
- builder.Append("</MediaInfo>");
+ builder.Append("</Video>");
- if (video != null)
- {
- //AddChapters(video, builder, itemRepository);
- }
+ builder.Append("</MediaInfo>");
}
}
}
diff --git a/MediaBrowser.Server.Implementations/BdInfo/BdInfoExaminer.cs b/MediaBrowser.Server.Implementations/BdInfo/BdInfoExaminer.cs
index 06768f353..18f1b92fe 100644
--- a/MediaBrowser.Server.Implementations/BdInfo/BdInfoExaminer.cs
+++ b/MediaBrowser.Server.Implementations/BdInfo/BdInfoExaminer.cs
@@ -102,7 +102,7 @@ namespace MediaBrowser.Server.Implementations.BdInfo
Width = videoStream.Width,
Height = videoStream.Height,
Codec = videoStream.CodecShortName,
- ScanType = videoStream.IsInterlaced ? "interlaced" : "progressive",
+ IsInterlaced = videoStream.IsInterlaced,
Type = MediaStreamType.Video,
Index = streams.Count
};
@@ -146,7 +146,7 @@ namespace MediaBrowser.Server.Implementations.BdInfo
{
stream.Channels = audioStream.ChannelCount + 1;
}
-
+
streams.Add(stream);
}
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index bb9ee7e14..ba9dd170d 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -1034,7 +1034,11 @@ namespace MediaBrowser.Server.Implementations.Dto
if (iHasMediaStreams != null)
{
- dto.MediaStreams = iHasMediaStreams.MediaStreams;
+ dto.MediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery
+ {
+ ItemId = item.Id
+
+ }).ToList();
}
}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 54fbb502e..a4eec43f7 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -168,6 +168,7 @@
<Compile Include="MediaEncoder\MediaEncoder.cs" />
<Compile Include="Persistence\SqliteChapterRepository.cs" />
<Compile Include="Persistence\SqliteExtensions.cs" />
+ <Compile Include="Persistence\SqliteMediaStreamsRepository.cs" />
<Compile Include="Persistence\SqliteNotificationsRepository.cs" />
<Compile Include="Persistence\TypeMapper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index fc2a6de24..799b74fe2 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -56,6 +56,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
private readonly string _criticReviewsPath;
private SqliteChapterRepository _chapterRepository;
+ private SqliteMediaStreamsRepository _mediaStreamsRepository;
private IDbCommand _deleteChildrenCommand;
private IDbCommand _saveChildrenCommand;
@@ -94,6 +95,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
var chapterConnection = SqliteExtensions.ConnectToDb(chapterDbFile, _logger).Result;
_chapterRepository = new SqliteChapterRepository(chapterConnection, logManager);
+
+ var mediaStreamsDbFile = Path.Combine(_appPaths.DataPath, "mediainfo.db");
+
+ var mediaStreamsConnection = SqliteExtensions.ConnectToDb(mediaStreamsDbFile, _logger).Result;
+
+ _mediaStreamsRepository = new SqliteMediaStreamsRepository(mediaStreamsConnection, logManager);
}
/// <summary>
@@ -122,6 +129,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
PrepareStatements();
+ _mediaStreamsRepository.Initialize();
_chapterRepository.Initialize();
}
@@ -413,6 +421,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
_chapterRepository.Dispose();
_chapterRepository = null;
}
+
+ if (_mediaStreamsRepository != null)
+ {
+ _mediaStreamsRepository.Dispose();
+ _mediaStreamsRepository = null;
+ }
}
}
@@ -511,5 +525,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
_writeLock.Release();
}
}
+
+ public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query)
+ {
+ return _mediaStreamsRepository.GetMediaStreams(query);
+ }
+
+ public Task SaveMediaStreams(Guid id, IEnumerable<MediaStream> streams, CancellationToken cancellationToken)
+ {
+ return _mediaStreamsRepository.SaveMediaStreams(id, streams, cancellationToken);
+ }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs
new file mode 100644
index 000000000..ba189396a
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs
@@ -0,0 +1,377 @@
+using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Persistence
+{
+ class SqliteMediaStreamsRepository
+ {
+ private IDbConnection _connection;
+
+ private readonly ILogger _logger;
+
+ private IDbCommand _deleteStreamsCommand;
+ private IDbCommand _saveStreamCommand;
+
+ public SqliteMediaStreamsRepository(IDbConnection connection, ILogManager logManager)
+ {
+ _connection = connection;
+
+ _logger = logManager.GetLogger(GetType().Name);
+ }
+
+ /// <summary>
+ /// Opens the connection to the database
+ /// </summary>
+ /// <returns>Task.</returns>
+ public void Initialize()
+ {
+ var createTableCommand
+ = "create table if not exists mediastreams ";
+
+ createTableCommand += "(ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PRIMARY KEY (ItemId, StreamIndex))";
+
+ string[] queries = {
+
+ createTableCommand,
+ "create index if not exists idx_mediastreams on mediastreams(ItemId, StreamIndex)",
+
+ //pragmas
+ "pragma temp_store = memory"
+ };
+
+ _connection.RunQueries(queries, _logger);
+
+ PrepareStatements();
+ }
+
+ private readonly string[] _saveColumns =
+ {
+ "ItemId",
+ "StreamIndex",
+ "StreamType",
+ "Codec",
+ "Language",
+ "ChannelLayout",
+ "Profile",
+ "AspectRatio",
+ "Path",
+ "IsInterlaced",
+ "BitRate",
+ "Channels",
+ "SampleRate",
+ "IsDefault",
+ "IsForced",
+ "IsExternal",
+ "Height",
+ "Width",
+ "AverageFrameRate",
+ "RealFrameRate",
+ "Level"
+ };
+
+ /// <summary>
+ /// The _write lock
+ /// </summary>
+ private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1);
+
+ /// <summary>
+ /// Prepares the statements.
+ /// </summary>
+ private void PrepareStatements()
+ {
+ _deleteStreamsCommand = _connection.CreateCommand();
+ _deleteStreamsCommand.CommandText = "delete from mediastreams where ItemId=@ItemId";
+ _deleteStreamsCommand.Parameters.Add(_deleteStreamsCommand, "@ItemId");
+
+ _saveStreamCommand = _connection.CreateCommand();
+
+ _saveStreamCommand.CommandText = string.Format("replace into mediastreams ({0}) values ({1})",
+ string.Join(",", _saveColumns),
+ string.Join(",", _saveColumns.Select(i => "@" + i).ToArray()));
+
+ foreach (var col in _saveColumns)
+ {
+ _saveStreamCommand.Parameters.Add(_saveStreamCommand, "@" + col);
+ }
+ }
+
+ public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException("query");
+ }
+
+ using (var cmd = _connection.CreateCommand())
+ {
+ var cmdText = "select " + string.Join(",", _saveColumns) + " from mediastreams where";
+
+ cmdText += " ItemId=@ItemId";
+ cmd.Parameters.Add(cmd, "@ItemId", DbType.Guid).Value = query.ItemId;
+
+ if (query.Type.HasValue)
+ {
+ cmdText += " AND StreamType=@StreamType";
+ cmd.Parameters.Add(cmd, "@StreamType", DbType.String).Value = query.Type.Value.ToString();
+ }
+
+ if (query.Index.HasValue)
+ {
+ cmdText += " AND StreamIndex=@StreamIndex";
+ cmd.Parameters.Add(cmd, "@StreamIndex", DbType.Int32).Value = query.Index.Value;
+ }
+
+ cmdText += " order by StreamIndex ASC";
+
+ cmd.CommandText = cmdText;
+
+ using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
+ {
+ while (reader.Read())
+ {
+ yield return GetMediaStream(reader);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the chapter.
+ /// </summary>
+ /// <param name="reader">The reader.</param>
+ /// <returns>ChapterInfo.</returns>
+ private MediaStream GetMediaStream(IDataReader reader)
+ {
+ var item = new MediaStream
+ {
+ Index = reader.GetInt32(1)
+ };
+
+ item.Type = (MediaStreamType)Enum.Parse(typeof(MediaStreamType), reader.GetString(2), true);
+
+ if (!reader.IsDBNull(3))
+ {
+ item.Codec = reader.GetString(3);
+ }
+
+ if (!reader.IsDBNull(4))
+ {
+ item.Language = reader.GetString(4);
+ }
+
+ if (!reader.IsDBNull(5))
+ {
+ item.ChannelLayout = reader.GetString(5);
+ }
+
+ if (!reader.IsDBNull(6))
+ {
+ item.Profile = reader.GetString(6);
+ }
+
+ if (!reader.IsDBNull(7))
+ {
+ item.AspectRatio = reader.GetString(7);
+ }
+
+ if (!reader.IsDBNull(8))
+ {
+ item.Path = reader.GetString(8);
+ }
+
+ item.IsInterlaced = reader.GetBoolean(9);
+
+ if (!reader.IsDBNull(10))
+ {
+ item.BitRate = reader.GetInt32(10);
+ }
+
+ if (!reader.IsDBNull(11))
+ {
+ item.Channels = reader.GetInt32(11);
+ }
+
+ if (!reader.IsDBNull(12))
+ {
+ item.SampleRate = reader.GetInt32(12);
+ }
+
+ item.IsDefault = reader.GetBoolean(13);
+ item.IsForced = reader.GetBoolean(14);
+ item.IsExternal = reader.GetBoolean(15);
+
+ if (!reader.IsDBNull(16))
+ {
+ item.Width = reader.GetInt32(16);
+ }
+
+ if (!reader.IsDBNull(17))
+ {
+ item.Height = reader.GetInt32(17);
+ }
+
+ if (!reader.IsDBNull(18))
+ {
+ item.AverageFrameRate = reader.GetFloat(18);
+ }
+
+ if (!reader.IsDBNull(19))
+ {
+ item.RealFrameRate = reader.GetFloat(19);
+ }
+
+ if (!reader.IsDBNull(20))
+ {
+ item.Level = reader.GetFloat(20);
+ }
+
+ return item;
+ }
+
+ public async Task SaveMediaStreams(Guid id, IEnumerable<MediaStream> streams, CancellationToken cancellationToken)
+ {
+ if (id == Guid.Empty)
+ {
+ throw new ArgumentNullException("id");
+ }
+
+ if (streams == null)
+ {
+ throw new ArgumentNullException("streams");
+ }
+
+ cancellationToken.ThrowIfCancellationRequested();
+
+ await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+ IDbTransaction transaction = null;
+
+ try
+ {
+ transaction = _connection.BeginTransaction();
+
+ // First delete chapters
+ _deleteStreamsCommand.GetParameter(0).Value = id;
+
+ _deleteStreamsCommand.Transaction = transaction;
+
+ _deleteStreamsCommand.ExecuteNonQuery();
+
+ foreach (var stream in streams)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ _saveStreamCommand.GetParameter(0).Value = id;
+ _saveStreamCommand.GetParameter(1).Value = stream.Index;
+ _saveStreamCommand.GetParameter(2).Value = stream.Type.ToString();
+ _saveStreamCommand.GetParameter(3).Value = stream.Codec;
+ _saveStreamCommand.GetParameter(4).Value = stream.Language;
+ _saveStreamCommand.GetParameter(5).Value = stream.ChannelLayout;
+ _saveStreamCommand.GetParameter(6).Value = stream.Profile;
+ _saveStreamCommand.GetParameter(7).Value = stream.AspectRatio;
+ _saveStreamCommand.GetParameter(8).Value = stream.Path;
+
+ _saveStreamCommand.GetParameter(9).Value = stream.IsInterlaced;
+
+ _saveStreamCommand.GetParameter(10).Value = stream.BitRate;
+ _saveStreamCommand.GetParameter(11).Value = stream.Channels;
+ _saveStreamCommand.GetParameter(12).Value = stream.SampleRate;
+
+ _saveStreamCommand.GetParameter(13).Value = stream.IsDefault;
+ _saveStreamCommand.GetParameter(14).Value = stream.IsForced;
+ _saveStreamCommand.GetParameter(15).Value = stream.IsExternal;
+
+ _saveStreamCommand.GetParameter(16).Value = stream.Width;
+ _saveStreamCommand.GetParameter(17).Value = stream.Height;
+ _saveStreamCommand.GetParameter(18).Value = stream.AverageFrameRate;
+ _saveStreamCommand.GetParameter(19).Value = stream.RealFrameRate;
+ _saveStreamCommand.GetParameter(20).Value = stream.Level;
+
+ _saveStreamCommand.Transaction = transaction;
+ _saveStreamCommand.ExecuteNonQuery();
+ }
+
+ transaction.Commit();
+ }
+ catch (OperationCanceledException)
+ {
+ if (transaction != null)
+ {
+ transaction.Rollback();
+ }
+
+ throw;
+ }
+ catch (Exception e)
+ {
+ _logger.ErrorException("Failed to save media streams:", e);
+
+ if (transaction != null)
+ {
+ transaction.Rollback();
+ }
+
+ throw;
+ }
+ finally
+ {
+ if (transaction != null)
+ {
+ transaction.Dispose();
+ }
+
+ _writeLock.Release();
+ }
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private readonly object _disposeLock = new object();
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources.
+ /// </summary>
+ /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool dispose)
+ {
+ if (dispose)
+ {
+ try
+ {
+ lock (_disposeLock)
+ {
+ if (_connection != null)
+ {
+ if (_connection.IsOpen())
+ {
+ _connection.Close();
+ }
+
+ _connection.Dispose();
+ _connection = null;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error disposing database", ex);
+ }
+ }
+ }
+ }
+}
+
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
index a9d5d8746..c174eb08e 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
@@ -31,36 +31,26 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
}
- private readonly IJsonSerializer _jsonSerializer;
-
/// <summary>
/// The _app paths
/// </summary>
private readonly IApplicationPaths _appPaths;
/// <summary>
- /// Initializes a new instance of the <see cref="SqliteUserDataRepository"/> class.
+ /// Initializes a new instance of the <see cref="SqliteUserDataRepository" /> class.
/// </summary>
/// <param name="appPaths">The app paths.</param>
- /// <param name="jsonSerializer">The json serializer.</param>
/// <param name="logManager">The log manager.</param>
- /// <exception cref="System.ArgumentNullException">
- /// jsonSerializer
+ /// <exception cref="System.ArgumentNullException">jsonSerializer
/// or
- /// appPaths
- /// </exception>
- public SqliteUserDataRepository(IApplicationPaths appPaths, IJsonSerializer jsonSerializer, ILogManager logManager)
+ /// appPaths</exception>
+ public SqliteUserDataRepository(IApplicationPaths appPaths, ILogManager logManager)
{
- if (jsonSerializer == null)
- {
- throw new ArgumentNullException("jsonSerializer");
- }
if (appPaths == null)
{
throw new ArgumentNullException("appPaths");
}
- _jsonSerializer = jsonSerializer;
_appPaths = appPaths;
_logger = logManager.GetLogger(GetType().Name);
}
diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
index c82899948..9270b879a 100644
--- a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
+++ b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
@@ -101,7 +101,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
// Limit to video files to reduce changes of ffmpeg crash dialog
foreach (var item in newItems
- .Where(i => i.LocationType == LocationType.FileSystem && i.VideoType == VideoType.VideoFile && string.IsNullOrEmpty(i.PrimaryImagePath) && i.MediaStreams.Any(m => m.Type == MediaStreamType.Video))
+ .Where(i => i.LocationType == LocationType.FileSystem && i.VideoType == VideoType.VideoFile && string.IsNullOrEmpty(i.PrimaryImagePath) && i.DefaultVideoStreamIndex.HasValue)
.Take(2))
{
try
diff --git a/MediaBrowser.Server.Implementations/Sorting/VideoBitRateComparer.cs b/MediaBrowser.Server.Implementations/Sorting/VideoBitRateComparer.cs
index 469eb5d6a..cbf6ebac6 100644
--- a/MediaBrowser.Server.Implementations/Sorting/VideoBitRateComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/VideoBitRateComparer.cs
@@ -1,8 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Sorting;
-using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
-using System.Linq;
namespace MediaBrowser.Server.Implementations.Sorting
{
@@ -21,17 +19,11 @@ namespace MediaBrowser.Server.Implementations.Sorting
private int GetValue(BaseItem item)
{
- var video = item as IHasMediaStreams;
+ var video = item as Video;
if (video != null)
{
- var videoStream = video.MediaStreams
- .FirstOrDefault(i => i.Type == MediaStreamType.Video);
-
- if (videoStream != null)
- {
- return videoStream.BitRate ?? 0;
- }
+ return video.VideoBitRate ?? 0;
}
return 0;
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index ac6959e45..ecd6a923b 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -394,7 +394,7 @@ namespace MediaBrowser.ServerApplication
/// <returns>Task.</returns>
private async Task ConfigureUserDataRepositories()
{
- var repo = new SqliteUserDataRepository(ApplicationPaths, JsonSerializer, LogManager);
+ var repo = new SqliteUserDataRepository(ApplicationPaths, LogManager);
await repo.Initialize().ConfigureAwait(false);
diff --git a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs
index 87a70f534..ec7dc582d 100644
--- a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs
+++ b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs
@@ -3,7 +3,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
{
public static class FFMpegDownloadInfo
{
- public static string Version = "ffmpeg20131110";
+ public static string Version = "ffmpeg20131110.1";
public static string[] FfMpegUrls = new[]
{