aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller')
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs25
-rw-r--r--MediaBrowser.Controller/Entities/InternalItemsQuery.cs36
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs14
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveStream.cs141
4 files changed, 154 insertions, 62 deletions
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
index f40ab3cde..e9eca19cf 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
@@ -8,6 +8,7 @@ using System.Linq;
using MediaBrowser.Model.Serialization;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
@@ -42,20 +43,22 @@ namespace MediaBrowser.Controller.Entities.Audio
[IgnoreDataMember]
public MusicArtist MusicArtist
{
- get
- {
- var artist = GetParents().OfType<MusicArtist>().FirstOrDefault();
+ get { return GetMusicArtist(new DtoOptions(true)); }
+ }
- if (artist == null)
+ public MusicArtist GetMusicArtist(DtoOptions options)
+ {
+ var artist = GetParents().OfType<MusicArtist>().FirstOrDefault();
+
+ if (artist == null)
+ {
+ var name = AlbumArtist;
+ if (!string.IsNullOrWhiteSpace(name))
{
- var name = AlbumArtist;
- if (!string.IsNullOrWhiteSpace(name))
- {
- artist = LibraryManager.GetArtist(name);
- }
+ artist = LibraryManager.GetArtist(name, options);
}
- return artist;
}
+ return artist;
}
[IgnoreDataMember]
@@ -171,7 +174,7 @@ namespace MediaBrowser.Controller.Entities.Audio
id.AlbumArtists = AlbumArtists;
- var artist = MusicArtist;
+ var artist = GetMusicArtist(new DtoOptions(false));
if (artist != null)
{
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
index f029d36fd..d3220f6c1 100644
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
@@ -160,42 +160,6 @@ namespace MediaBrowser.Controller.Entities
public DtoOptions DtoOptions { get; set; }
public int MinSimilarityScore { get; set; }
- public bool HasField(ItemFields name)
- {
- var fields = DtoOptions.Fields;
-
- switch (name)
- {
- case ItemFields.HomePageUrl:
- case ItemFields.Keywords:
- case ItemFields.DisplayMediaType:
- case ItemFields.VoteCount:
- case ItemFields.CustomRating:
- case ItemFields.ProductionLocations:
- case ItemFields.Settings:
- case ItemFields.OriginalTitle:
- case ItemFields.Taglines:
- case ItemFields.SortName:
- case ItemFields.Studios:
- case ItemFields.Tags:
- case ItemFields.ThemeSongIds:
- case ItemFields.ThemeVideoIds:
- case ItemFields.DateCreated:
- case ItemFields.Overview:
- case ItemFields.Genres:
- case ItemFields.DateLastMediaAdded:
- case ItemFields.ExternalEtag:
- case ItemFields.PresentationUniqueKey:
- case ItemFields.InheritedParentalRatingValue:
- case ItemFields.ExternalSeriesId:
- return fields.Contains(name);
- case ItemFields.ServiceName:
- return true;
- default:
- return true;
- }
- }
-
public InternalItemsQuery()
{
MinSimilarityScore = 20;
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 70a635872..7dcc207db 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -12,6 +12,7 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
@@ -68,18 +69,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="name">The name.</param>
/// <returns>Task{Artist}.</returns>
MusicArtist GetArtist(string name);
- /// <summary>
- /// Gets the album artists.
- /// </summary>
- /// <param name="items">The items.</param>
- /// <returns>IEnumerable&lt;MusicArtist&gt;.</returns>
- IEnumerable<MusicArtist> GetAlbumArtists(IEnumerable<IHasAlbumArtist> items);
- /// <summary>
- /// Gets the artists.
- /// </summary>
- /// <param name="items">The items.</param>
- /// <returns>IEnumerable&lt;MusicArtist&gt;.</returns>
- IEnumerable<MusicArtist> GetArtists(IEnumerable<IHasArtist> items);
+ MusicArtist GetArtist(string name, DtoOptions options);
/// <summary>
/// Gets a Studio
/// </summary>
diff --git a/MediaBrowser.Controller/LiveTv/LiveStream.cs b/MediaBrowser.Controller/LiveTv/LiveStream.cs
index 0908c3ecc..48468d1a0 100644
--- a/MediaBrowser.Controller/LiveTv/LiveStream.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveStream.cs
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.System;
namespace MediaBrowser.Controller.LiveTv
{
@@ -10,7 +13,8 @@ namespace MediaBrowser.Controller.LiveTv
{
public MediaSourceInfo OriginalMediaSource { get; set; }
public MediaSourceInfo OpenedMediaSource { get; set; }
- public int ConsumerCount {
+ public int ConsumerCount
+ {
get { return SharedStreamIds.Count; }
}
public ITunerHost TunerHost { get; set; }
@@ -18,11 +22,16 @@ namespace MediaBrowser.Controller.LiveTv
public bool EnableStreamSharing { get; set; }
public string UniqueId = Guid.NewGuid().ToString("N");
- public List<string> SharedStreamIds = new List<string>();
+ public List<string> SharedStreamIds = new List<string>();
+ protected readonly IEnvironmentInfo Environment;
+ protected readonly IFileSystem FileSystem;
+ const int StreamCopyToBufferSize = 81920;
- public LiveStream(MediaSourceInfo mediaSource)
+ public LiveStream(MediaSourceInfo mediaSource, IEnvironmentInfo environment, IFileSystem fileSystem)
{
OriginalMediaSource = mediaSource;
+ Environment = environment;
+ FileSystem = fileSystem;
OpenedMediaSource = mediaSource;
EnableStreamSharing = true;
}
@@ -41,5 +50,131 @@ namespace MediaBrowser.Controller.LiveTv
{
return Task.FromResult(true);
}
+
+ private Stream GetInputStream(string path, long startPosition, bool allowAsyncFileRead)
+ {
+ var fileOpenOptions = startPosition > 0
+ ? FileOpenOptions.RandomAccess
+ : FileOpenOptions.SequentialScan;
+
+ if (allowAsyncFileRead)
+ {
+ fileOpenOptions |= FileOpenOptions.Asynchronous;
+ }
+
+ return FileSystem.GetFileStream(path, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.ReadWrite, fileOpenOptions);
+ }
+
+ protected async Task DeleteTempFile(string path, int retryCount = 0)
+ {
+ try
+ {
+ FileSystem.DeleteFile(path);
+ return;
+ }
+ catch
+ {
+
+ }
+
+ if (retryCount > 20)
+ {
+ return;
+ }
+
+ await Task.Delay(500).ConfigureAwait(false);
+ await DeleteTempFile(path, retryCount + 1).ConfigureAwait(false);
+ }
+
+ protected async Task CopyFileTo(string path, bool allowEndOfFile, Stream outputStream, CancellationToken cancellationToken)
+ {
+ var eofCount = 0;
+
+ long startPosition = -25000;
+ if (startPosition < 0)
+ {
+ var length = FileSystem.GetFileInfo(path).Length;
+ startPosition = Math.Max(length - startPosition, 0);
+ }
+
+ // use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
+ var allowAsyncFileRead = Environment.OperatingSystem != OperatingSystem.Windows;
+
+ using (var inputStream = GetInputStream(path, startPosition, allowAsyncFileRead))
+ {
+ if (startPosition > 0)
+ {
+ inputStream.Position = startPosition;
+ }
+
+ while (eofCount < 20 || !allowEndOfFile)
+ {
+ int bytesRead;
+ if (allowAsyncFileRead)
+ {
+ bytesRead = await CopyToInternalAsync(inputStream, outputStream, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ bytesRead = await CopyToInternalAsyncWithSyncRead(inputStream, outputStream, cancellationToken).ConfigureAwait(false);
+ }
+
+ //var position = fs.Position;
+ //_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path);
+
+ if (bytesRead == 0)
+ {
+ eofCount++;
+ await Task.Delay(100, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ eofCount = 0;
+ }
+ }
+ }
+ }
+
+ private async Task<int> CopyToInternalAsyncWithSyncRead(Stream source, Stream destination, CancellationToken cancellationToken)
+ {
+ var array = new byte[StreamCopyToBufferSize];
+ int bytesRead;
+ int totalBytesRead = 0;
+
+ while ((bytesRead = source.Read(array, 0, array.Length)) != 0)
+ {
+ var bytesToWrite = bytesRead;
+
+ if (bytesToWrite > 0)
+ {
+ await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false);
+
+ totalBytesRead += bytesRead;
+ }
+ }
+
+ return totalBytesRead;
+ }
+
+ private async Task<int> CopyToInternalAsync(Stream source, Stream destination, CancellationToken cancellationToken)
+ {
+ var array = new byte[StreamCopyToBufferSize];
+ int bytesRead;
+ int totalBytesRead = 0;
+
+ while ((bytesRead = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0)
+ {
+ var bytesToWrite = bytesRead;
+
+ if (bytesToWrite > 0)
+ {
+ await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false);
+
+ totalBytesRead += bytesRead;
+ }
+ }
+
+ return totalBytesRead;
+ }
}
}