using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Entities
{
///
/// Class Video
///
public class Video : BaseItem, IHasMediaStreams, IHasAspectRatio, IHasTags
{
public bool IsMultiPart { get; set; }
public List AdditionalPartIds { get; set; }
public Video()
{
PlayableStreamFileNames = new List();
AdditionalPartIds = new List();
Tags = new List();
SubtitleFiles = new List();
}
///
/// Gets or sets the subtitle paths.
///
/// The subtitle paths.
public List SubtitleFiles { get; set; }
///
/// Gets or sets a value indicating whether this instance has subtitles.
///
/// true if this instance has subtitles; otherwise, false.
public bool HasSubtitles { get; set; }
///
/// Gets or sets the tags.
///
/// The tags.
public List Tags { get; set; }
///
/// Gets or sets the video bit rate.
///
/// The video bit rate.
public int? VideoBitRate { get; set; }
///
/// Gets or sets the default index of the video stream.
///
/// The default index of the video stream.
public int? DefaultVideoStreamIndex { get; set; }
///
/// Gets or sets the type of the video.
///
/// The type of the video.
public VideoType VideoType { get; set; }
///
/// Gets or sets the type of the iso.
///
/// The type of the iso.
public IsoType? IsoType { get; set; }
///
/// Gets or sets the video3 D format.
///
/// The video3 D format.
public Video3DFormat? Video3DFormat { get; set; }
///
/// If the video is a folder-rip, this will hold the file list for the largest playlist
///
public List PlayableStreamFileNames { get; set; }
///
/// Gets the playable stream files.
///
/// List{System.String}.
public List GetPlayableStreamFiles()
{
return GetPlayableStreamFiles(Path);
}
///
/// Gets or sets the aspect ratio.
///
/// The aspect ratio.
public string AspectRatio { get; set; }
[IgnoreDataMember]
public override string ContainingFolderPath
{
get
{
if (IsMultiPart)
{
return System.IO.Path.GetDirectoryName(Path);
}
if (VideoType == VideoType.BluRay || VideoType == VideoType.Dvd ||
VideoType == VideoType.HdDvd)
{
return Path;
}
return base.ContainingFolderPath;
}
}
public string MainFeaturePlaylistName { get; set; }
///
/// Gets the playable stream files.
///
/// The root path.
/// List{System.String}.
public List GetPlayableStreamFiles(string rootPath)
{
var allFiles = Directory.EnumerateFiles(rootPath, "*", SearchOption.AllDirectories).ToList();
return PlayableStreamFileNames.Select(name => allFiles.FirstOrDefault(f => string.Equals(System.IO.Path.GetFileName(f), name, StringComparison.OrdinalIgnoreCase)))
.Where(f => !string.IsNullOrEmpty(f))
.ToList();
}
///
/// Gets a value indicating whether [is3 D].
///
/// true if [is3 D]; otherwise, false.
[IgnoreDataMember]
public bool Is3D
{
get { return Video3DFormat.HasValue; }
}
public bool IsHD { get; set; }
///
/// Gets the type of the media.
///
/// The type of the media.
public override string MediaType
{
get
{
return Model.Entities.MediaType.Video;
}
}
protected override async Task RefreshedOwnedItems(MetadataRefreshOptions options, List fileSystemChildren, CancellationToken cancellationToken)
{
var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
// Must have a parent to have additional parts
// In other words, it must be part of the Parent/Child tree
// The additional parts won't have additional parts themselves
if (IsMultiPart && LocationType == LocationType.FileSystem && Parent != null)
{
var additionalPartsChanged = await RefreshAdditionalParts(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
if (additionalPartsChanged)
{
hasChanges = true;
}
}
return hasChanges;
}
///
/// Refreshes the additional parts.
///
/// The options.
/// The file system children.
/// The cancellation token.
/// Task{System.Boolean}.
private async Task RefreshAdditionalParts(MetadataRefreshOptions options, IEnumerable fileSystemChildren, CancellationToken cancellationToken)
{
var newItems = LoadAdditionalParts(fileSystemChildren, options.DirectoryService).ToList();
var newItemIds = newItems.Select(i => i.Id).ToList();
var itemsChanged = !AdditionalPartIds.SequenceEqual(newItemIds);
var tasks = newItems.Select(i => i.RefreshMetadata(options, cancellationToken));
await Task.WhenAll(tasks).ConfigureAwait(false);
AdditionalPartIds = newItemIds;
return itemsChanged;
}
///
/// Loads the additional parts.
///
/// IEnumerable{Video}.
private IEnumerable