#nullable disable #pragma warning disable CS1591 using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; using Jellyfin.Extensions; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Controller.Entities { /// /// Class Video. /// public class Video : BaseItem, IHasAspectRatio, ISupportsPlaceHolders, IHasMediaSources { public Video() { AdditionalParts = Array.Empty(); LocalAlternateVersions = Array.Empty(); SubtitleFiles = Array.Empty(); AudioFiles = Array.Empty(); LinkedAlternateVersions = Array.Empty(); } [JsonIgnore] public string PrimaryVersionId { get; set; } public string[] AdditionalParts { get; set; } public string[] LocalAlternateVersions { get; set; } public LinkedChild[] LinkedAlternateVersions { get; set; } [JsonIgnore] public override bool SupportsPlayedStatus => true; [JsonIgnore] public override bool SupportsPeople => true; [JsonIgnore] public override bool SupportsInheritedParentImages => true; [JsonIgnore] public override bool SupportsPositionTicksResume { get { var extraType = ExtraType; if (extraType.HasValue) { if (extraType.Value == Model.Entities.ExtraType.Sample) { return false; } if (extraType.Value == Model.Entities.ExtraType.ThemeVideo) { return false; } if (extraType.Value == Model.Entities.ExtraType.Trailer) { return false; } } return true; } } [JsonIgnore] public override bool SupportsThemeMedia => true; /// /// Gets or sets the timestamp. /// /// The timestamp. public TransportStreamTimestamp? Timestamp { get; set; } /// /// Gets or sets the subtitle paths. /// /// The subtitle paths. public string[] SubtitleFiles { get; set; } /// /// Gets or sets the audio paths. /// /// The audio paths. public string[] AudioFiles { 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; } public bool IsPlaceHolder { 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; } /// /// Gets or sets the aspect ratio. /// /// The aspect ratio. public string AspectRatio { get; set; } [JsonIgnore] public override bool SupportsAddingToPlaylist => true; [JsonIgnore] public int MediaSourceCount { get { if (!string.IsNullOrEmpty(PrimaryVersionId)) { var item = LibraryManager.GetItemById(PrimaryVersionId); if (item is Video video) { return video.MediaSourceCount; } } return LinkedAlternateVersions.Length + LocalAlternateVersions.Length + 1; } } [JsonIgnore] public bool IsStacked => AdditionalParts.Length > 0; [JsonIgnore] public override bool HasLocalAlternateVersions => LocalAlternateVersions.Length > 0; public static ILiveTvManager LiveTvManager { get; set; } [JsonIgnore] public override SourceType SourceType { get { if (IsActiveRecording()) { return SourceType.LiveTV; } return base.SourceType; } } [JsonIgnore] public bool IsCompleteMedia { get { if (SourceType == SourceType.Channel) { return !Tags.Contains("livestream", StringComparison.OrdinalIgnoreCase); } return !IsActiveRecording(); } } [JsonIgnore] protected virtual bool EnableDefaultVideoUserDataKeys => true; [JsonIgnore] public override string ContainingFolderPath { get { if (IsStacked) { return System.IO.Path.GetDirectoryName(Path); } if (!IsPlaceHolder) { if (VideoType == VideoType.BluRay || VideoType == VideoType.Dvd) { return Path; } } return base.ContainingFolderPath; } } [JsonIgnore] public override string FileNameWithoutExtension { get { if (IsFileProtocol) { if (VideoType == VideoType.BluRay || VideoType == VideoType.Dvd) { return System.IO.Path.GetFileName(Path); } return System.IO.Path.GetFileNameWithoutExtension(Path); } return null; } } /// /// Gets a value indicating whether [is3 D]. /// /// true if [is3 D]; otherwise, false. [JsonIgnore] public bool Is3D => Video3DFormat.HasValue; /// /// Gets the type of the media. /// /// The type of the media. [JsonIgnore] public override string MediaType => Model.Entities.MediaType.Video; public override List GetUserDataKeys() { var list = base.GetUserDataKeys(); if (EnableDefaultVideoUserDataKeys) { if (ExtraType.HasValue) { var key = this.GetProviderId(MetadataProvider.Tmdb); if (!string.IsNullOrEmpty(key)) { list.Insert(0, GetUserDataKey(key)); } key = this.GetProviderId(MetadataProvider.Imdb); if (!string.IsNullOrEmpty(key)) { list.Insert(0, GetUserDataKey(key)); } } else { var key = this.GetProviderId(MetadataProvider.Imdb); if (!string.IsNullOrEmpty(key)) { list.Insert(0, key); } key = this.GetProviderId(MetadataProvider.Tmdb); if (!string.IsNullOrEmpty(key)) { list.Insert(0, key); } } } return list; } public void SetPrimaryVersionId(string id) { if (string.IsNullOrEmpty(id)) { PrimaryVersionId = null; } else { PrimaryVersionId = id; } PresentationUniqueKey = CreatePresentationUniqueKey(); } public override string CreatePresentationUniqueKey() { if (!string.IsNullOrEmpty(PrimaryVersionId)) { return PrimaryVersionId; } return base.CreatePresentationUniqueKey(); } public override bool CanDownload() { if (VideoType == VideoType.Dvd || VideoType == VideoType.BluRay) { return false; } return IsFileProtocol; } protected override bool IsActiveRecording() { return LiveTvManager.GetActiveRecordingInfo(Path) != null; } public override bool CanDelete() { if (IsActiveRecording()) { return false; } return base.CanDelete(); } public IEnumerable GetAdditionalPartIds() { return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video))); } public IEnumerable GetLocalAlternateVersionIds() { return LocalAlternateVersions.Select(i => LibraryManager.GetNewItemId(i, typeof(Video))); } private string GetUserDataKey(string providerId) { var key = providerId + "-" + ExtraType.ToString().ToLowerInvariant(); // Make sure different trailers have their own data. if (RunTimeTicks.HasValue) { key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture); } return key; } public IEnumerable