Update to match master. Playback broken as GetPostedPlaybackInfo does not get MediaSourceId.
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@@ -26,7 +26,7 @@ public class CinemaEpisode : Episode
|
||||
return result;
|
||||
}
|
||||
|
||||
public override List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
public override IReadOnlyList<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
{
|
||||
var result = this.VideoGetMediaSources(enablePathSubstitution);
|
||||
if (result == null)
|
||||
|
||||
@@ -7,6 +7,7 @@ using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using CinemaLib.API;
|
||||
using Jellyfin.Database.Implementations.Enums;
|
||||
|
||||
namespace Jellyfin.Plugin.Cinema;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AssemblyOriginatorKeyFile>..\key.snk</AssemblyOriginatorKeyFile>
|
||||
@@ -11,10 +11,10 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CinemaLib\CinemaLib.csproj" />
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.10.3" />
|
||||
<!--ProjectReference Include="..\..\..\jellyfin/MediaBrowser.Controller\MediaBrowser.Controller.csproj" /-->
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.10.3" />
|
||||
<!--ProjectReference Include="..\..\..\jellyfin\MediaBrowser.Model\MediaBrowser.Model.csproj" /-->
|
||||
<!--PackageReference Include="Jellyfin.Controller" Version="10.10.6" /-->
|
||||
<ProjectReference Include="/home/rv/temp/jellyfin/MediaBrowser.Controller/MediaBrowser.Controller.csproj" />
|
||||
<!--PackageReference Include="Jellyfin.Model" Version="10.10.6" /-->
|
||||
<ProjectReference Include="/home/rv/temp/jellyfin/MediaBrowser.Model/MediaBrowser.Model.csproj" />
|
||||
|
||||
<PackageReference Include="ILRepack.Lib.MSBuild.Task" Version="2.0.34.2" PrivateAssets="All"/>
|
||||
</ItemGroup>
|
||||
@@ -28,7 +28,7 @@
|
||||
<ItemGroup>
|
||||
<DebugCopyFiles Include="$(TargetDir)\Cinema*.dll" />
|
||||
</ItemGroup>
|
||||
<MakeDir Directories="\home\code\.local\share\jellyfin\plugins\Cinema" />
|
||||
<Copy SourceFiles="@(DebugCopyFiles)" DestinationFolder="\home\code\.local\share\jellyfin\plugins\Cinema" />
|
||||
<MakeDir Directories="\home\rv\.local\share\jellyfin\plugins\Cinema" />
|
||||
<Copy SourceFiles="@(DebugCopyFiles)" DestinationFolder="\home\rv\.local\share\jellyfin\plugins\Cinema" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using CinemaLib.API;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using Jellyfin.Database.Implementations.Enums;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
@@ -15,15 +16,17 @@ using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Jellyfin.Database.Implementations;
|
||||
|
||||
namespace Jellyfin.Plugin.Cinema;
|
||||
|
||||
sealed class CinemaLibraryManager : ILibraryManager
|
||||
{
|
||||
private readonly ILibraryManager _inner;
|
||||
private readonly IUserDataRepository _userData;
|
||||
private readonly IDbContextFactory<JellyfinDbContext> _userData;
|
||||
|
||||
public CinemaLibraryManager(CinemaInnerLibraryManager innerLibraryManager, IUserDataRepository userData, IServiceProvider svc)
|
||||
public CinemaLibraryManager(CinemaInnerLibraryManager innerLibraryManager, IDbContextFactory<JellyfinDbContext> userData, IServiceProvider svc)
|
||||
{
|
||||
if (innerLibraryManager == null || svc == null)
|
||||
throw new ArgumentNullException();
|
||||
@@ -217,12 +220,12 @@ sealed class CinemaLibraryManager : ILibraryManager
|
||||
return _inner.GetItemById<T>(id, user);
|
||||
}
|
||||
|
||||
public List<Guid> GetItemIds(InternalItemsQuery query)
|
||||
public IReadOnlyList<Guid> GetItemIds(InternalItemsQuery query)
|
||||
{
|
||||
return _inner.GetItemIds(query);
|
||||
}
|
||||
|
||||
public List<BaseItem> GetItemList(InternalItemsQuery query)
|
||||
public IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query)
|
||||
{
|
||||
string? serieOrSeasonIdS;
|
||||
Guid serieOrSeasonId;
|
||||
@@ -255,12 +258,12 @@ sealed class CinemaLibraryManager : ILibraryManager
|
||||
}
|
||||
}
|
||||
|
||||
public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
|
||||
public IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
|
||||
{
|
||||
return _inner.GetItemList(query, allowExternalContent);
|
||||
}
|
||||
|
||||
public List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
|
||||
public IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
|
||||
{
|
||||
return _inner.GetItemList(query, parents);
|
||||
}
|
||||
@@ -277,16 +280,21 @@ sealed class CinemaLibraryManager : ILibraryManager
|
||||
if (query.OrderBy.FirstOrDefault().OrderBy == ItemSortBy.DatePlayed && query.User != null && query.MediaTypes.Contains(MediaType.Video))
|
||||
{
|
||||
// Get Resume play items
|
||||
// PERF: This may quickly become very slow
|
||||
var resumePlay = _userData.GetAllUserData(query.User.InternalId)
|
||||
UserData[]? resumePlay;
|
||||
Guid userId = query.User.Id;
|
||||
using (JellyfinDbContext context = _userData.CreateDbContext())
|
||||
resumePlay = context.UserData.AsNoTracking()
|
||||
.Where(e => e.UserId.Equals(userId))
|
||||
.OrderByDescending(x => x.Played)
|
||||
.Skip(query.StartIndex ?? 0)
|
||||
.Take(query.Limit ?? 20);
|
||||
foreach (UserItemData i in resumePlay)
|
||||
.Take(query.Limit ?? 20)
|
||||
.ToArray();
|
||||
|
||||
foreach (UserData i in resumePlay)
|
||||
{
|
||||
// Note: All Cinema items override GetUserDataKeys and return ExternalId
|
||||
string? csId;
|
||||
if (CinemaQueryExtensions.TryGetCinemaIdFromExternalId(i.Key, out csId))
|
||||
if (CinemaQueryExtensions.TryGetCinemaIdFromExternalId(i.CustomDataKey, out csId))
|
||||
{
|
||||
// First try to get already in-memory item
|
||||
Guid itemId = CinemaQueryExtensions.GetMediaItemId(csId, null);
|
||||
@@ -303,7 +311,7 @@ sealed class CinemaLibraryManager : ILibraryManager
|
||||
else
|
||||
{
|
||||
// Try to append item from the inner result
|
||||
if (Guid.TryParse(i.Key, out Guid key))
|
||||
if (Guid.TryParse(i.CustomDataKey, out Guid key))
|
||||
foreach (BaseItem j in result.Items)
|
||||
if (j.Id == key)
|
||||
{
|
||||
@@ -336,6 +344,11 @@ sealed class CinemaLibraryManager : ILibraryManager
|
||||
return new QueryResult<BaseItem>() { Items = resultL };
|
||||
}
|
||||
|
||||
public IReadOnlyList<BaseItem> GetLatestItemList(InternalItemsQuery query, IReadOnlyList<BaseItem> parents, CollectionType collectionType)
|
||||
{
|
||||
return _inner.GetLatestItemList(query, parents, collectionType);
|
||||
}
|
||||
|
||||
public LibraryOptions GetLibraryOptions(BaseItem item)
|
||||
{
|
||||
return _inner.GetLibraryOptions(item);
|
||||
@@ -381,6 +394,11 @@ sealed class CinemaLibraryManager : ILibraryManager
|
||||
return _inner.GetNewItemId(key, type);
|
||||
}
|
||||
|
||||
public IReadOnlyList<string> GetNextUpSeriesKeys(InternalItemsQuery query, IReadOnlyCollection<BaseItem> parents, DateTime dateCutoff)
|
||||
{
|
||||
return _inner.GetNextUpSeriesKeys(query, parents, dateCutoff);
|
||||
}
|
||||
|
||||
public BaseItem GetParentItem(Guid? parentId, Guid? userId)
|
||||
{
|
||||
return _inner.GetParentItem(parentId, userId);
|
||||
@@ -391,22 +409,22 @@ sealed class CinemaLibraryManager : ILibraryManager
|
||||
return _inner.GetPathAfterNetworkSubstitution(path, ownerItem);
|
||||
}
|
||||
|
||||
public List<PersonInfo> GetPeople(BaseItem item)
|
||||
public IReadOnlyList<PersonInfo> GetPeople(BaseItem item)
|
||||
{
|
||||
return _inner.GetPeople(item);
|
||||
}
|
||||
|
||||
public List<PersonInfo> GetPeople(InternalPeopleQuery query)
|
||||
public IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery query)
|
||||
{
|
||||
return _inner.GetPeople(query);
|
||||
}
|
||||
|
||||
public List<Person> GetPeopleItems(InternalPeopleQuery query)
|
||||
public IReadOnlyList<Person> GetPeopleItems(InternalPeopleQuery query)
|
||||
{
|
||||
return _inner.GetPeopleItems(query);
|
||||
}
|
||||
|
||||
public List<string> GetPeopleNames(InternalPeopleQuery query)
|
||||
public IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery query)
|
||||
{
|
||||
return _inner.GetPeopleNames(query);
|
||||
}
|
||||
@@ -416,9 +434,9 @@ sealed class CinemaLibraryManager : ILibraryManager
|
||||
return _inner.GetPerson(name);
|
||||
}
|
||||
|
||||
public int? GetSeasonNumberFromPath(string path)
|
||||
public int? GetSeasonNumberFromPath(string path, Guid? parentId)
|
||||
{
|
||||
return _inner.GetSeasonNumberFromPath(path);
|
||||
return _inner.GetSeasonNumberFromPath(path, parentId);
|
||||
}
|
||||
|
||||
public UserView GetShadowView(BaseItem parent, CollectionType? viewType, string sortName)
|
||||
@@ -556,7 +574,7 @@ sealed class CinemaLibraryManager : ILibraryManager
|
||||
_inner.UpdatePeople(item, people);
|
||||
}
|
||||
|
||||
public Task UpdatePeopleAsync(BaseItem item, List<PersonInfo> people, CancellationToken cancellationToken)
|
||||
public Task UpdatePeopleAsync(BaseItem item, IReadOnlyList<PersonInfo> people, CancellationToken cancellationToken)
|
||||
{
|
||||
return _inner.UpdatePeopleAsync(item, people, cancellationToken);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
@@ -21,6 +21,7 @@ using MediaBrowser.Controller.MediaEncoding;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LinkGenerator = CinemaLib.Webshare.LinkGenerator;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using Jellyfin.Extensions;
|
||||
|
||||
namespace Jellyfin.Plugin.Cinema;
|
||||
|
||||
@@ -130,12 +131,12 @@ sealed class CinemaMediaSourceManager : IMediaSourceManager
|
||||
return _inner.GetLiveStreamWithDirectStreamProvider(id, cancellationToken);
|
||||
}
|
||||
|
||||
public List<MediaAttachment> GetMediaAttachments(Guid itemId)
|
||||
public IReadOnlyList<MediaAttachment> GetMediaAttachments(Guid itemId)
|
||||
{
|
||||
return _inner.GetMediaAttachments(itemId);
|
||||
}
|
||||
|
||||
public List<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query)
|
||||
public IReadOnlyList<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query)
|
||||
{
|
||||
return _inner.GetMediaAttachments(query);
|
||||
}
|
||||
@@ -145,12 +146,12 @@ sealed class CinemaMediaSourceManager : IMediaSourceManager
|
||||
return _inner.GetMediaSource(item, mediaSourceId, liveStreamId, enablePathSubstitution, cancellationToken);
|
||||
}
|
||||
|
||||
public List<MediaStream> GetMediaStreams(Guid itemId)
|
||||
public IReadOnlyList<MediaStream> GetMediaStreams(Guid itemId)
|
||||
{
|
||||
return _inner.GetMediaStreams(itemId);
|
||||
}
|
||||
|
||||
public List<MediaStream> GetMediaStreams(MediaStreamQuery query)
|
||||
public IReadOnlyList<MediaStream> GetMediaStreams(MediaStreamQuery query)
|
||||
{
|
||||
return _inner.GetMediaStreams(query);
|
||||
}
|
||||
@@ -160,12 +161,12 @@ sealed class CinemaMediaSourceManager : IMediaSourceManager
|
||||
return _inner.GetPathProtocol(path);
|
||||
}
|
||||
|
||||
public Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken)
|
||||
public Task<IReadOnlyList<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
return _inner.GetRecordingStreamMediaSources(info, cancellationToken);
|
||||
}
|
||||
|
||||
public List<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User? user = null)
|
||||
public IReadOnlyList<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User? user = null)
|
||||
{
|
||||
// Intercept for CinemaItems
|
||||
if (item == null
|
||||
@@ -173,21 +174,26 @@ sealed class CinemaMediaSourceManager : IMediaSourceManager
|
||||
|| string.IsNullOrEmpty(item.ExternalId))
|
||||
return _inner.GetStaticMediaSources(item, enablePathSubstitution, user);
|
||||
|
||||
List<MediaSourceInfo> result = GetPlaybackMediaSourcesInternal(item, user, false, enablePathSubstitution, needsPreciseStreamIndicies: false, default).GetAwaiter().GetResult();
|
||||
IReadOnlyList<MediaSourceInfo> result = GetPlaybackMediaSourcesInternal(item, user, false, enablePathSubstitution, needsPreciseStreamIndicies: false, default).GetAwaiter().GetResult();
|
||||
|
||||
// HACK Prevent crash
|
||||
if (result.Count == 0)
|
||||
result.Append(new MediaSourceInfo() { MediaStreams = new List<MediaStream>() });
|
||||
{
|
||||
MediaSourceInfo[] result2 = new MediaSourceInfo[result.Count + 1];
|
||||
result.CopyTo(result2, 0);
|
||||
result2[result2.Length - 1] = new MediaSourceInfo() { MediaStreams = new List<MediaStream>() };
|
||||
result = result2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Task<List<MediaSourceInfo>> GetPlaybackMediaSources(BaseItem item, User? user, bool allowMediaProbe, bool enablePathSubstitution, CancellationToken cancellationToken)
|
||||
public Task<IReadOnlyList<MediaSourceInfo>> GetPlaybackMediaSources(BaseItem item, User? user, bool allowMediaProbe, bool enablePathSubstitution, CancellationToken cancellationToken)
|
||||
{
|
||||
return GetPlaybackMediaSourcesInternal(item, user, allowMediaProbe, enablePathSubstitution, needsPreciseStreamIndicies: true, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<List<MediaSourceInfo>> GetPlaybackMediaSourcesInternal(BaseItem item, User? user, bool allowMediaProbe, bool enablePathSubstitution, bool needsPreciseStreamIndicies, CancellationToken cancellationToken)
|
||||
private async Task<IReadOnlyList<MediaSourceInfo>> GetPlaybackMediaSourcesInternal(BaseItem item, User? user, bool allowMediaProbe, bool enablePathSubstitution, bool needsPreciseStreamIndicies, CancellationToken cancellationToken)
|
||||
{
|
||||
// Intercept for CinemaItems
|
||||
if (item == null
|
||||
|
||||
@@ -26,7 +26,7 @@ public class CinemaMovie : Movie
|
||||
return result;
|
||||
}
|
||||
|
||||
public override List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
public override IReadOnlyList<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
{
|
||||
var result = this.VideoGetMediaSources(enablePathSubstitution);
|
||||
if (result == null)
|
||||
|
||||
@@ -25,7 +25,7 @@ public sealed class CinemaMusicVideo : MusicVideo
|
||||
return result;
|
||||
}
|
||||
|
||||
public override List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
public override IReadOnlyList<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
{
|
||||
var result = this.VideoGetMediaSources(enablePathSubstitution);
|
||||
if (result == null)
|
||||
|
||||
@@ -46,10 +46,6 @@ static class CinemaQueryExtensions
|
||||
//case ItemSortBy.IsFavoriteOrLiked:
|
||||
case ItemSortBy.DateLastContentAdded: return FilterSortBy.LastChildrenDateAdded;
|
||||
case ItemSortBy.SeriesDatePlayed: return FilterSortBy.LastChildPremiered;
|
||||
//case ItemSortBy.ParentIndexNumber:
|
||||
//case ItemSortBy.IndexNumber:
|
||||
case ItemSortBy.SimilarityScore: return FilterSortBy.Score;
|
||||
case ItemSortBy.SearchScore: return FilterSortBy.Score;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using CinemaLib.API;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
|
||||
namespace Jellyfin.Plugin.Cinema;
|
||||
|
||||
@@ -28,7 +28,7 @@ public abstract class CinemaRootFolder : CinemaFilterFolder, ICollectionFolder
|
||||
public abstract CollectionType? CollectionType { get; }
|
||||
|
||||
public override bool IsHidden => _hidden;
|
||||
public override bool IsVisible(User user) => !_hidden;
|
||||
public override bool IsVisible(User user, bool skipAllowedTagsCheck = false) => !_hidden;
|
||||
|
||||
internal bool Hide
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Globalization;
|
||||
using CinemaLib.API;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Globalization;
|
||||
using CinemaLib.API;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
|
||||
@@ -11,16 +11,16 @@ public class CinemaPluginConfiguration : BasePluginConfiguration
|
||||
{
|
||||
}
|
||||
|
||||
public string MoviesFolderName { get; set; }
|
||||
public string? MoviesFolderName { get; set; }
|
||||
public bool HideMoviesFolder { get; set; }
|
||||
|
||||
public string SeriesFolderName { get; set; }
|
||||
public string? SeriesFolderName { get; set; }
|
||||
public bool HideSeriesFolder { get; set; }
|
||||
|
||||
public string AnimeFolderName { get; set; }
|
||||
public string? AnimeFolderName { get; set; }
|
||||
public bool HideAnimeFolder { get; set; }
|
||||
|
||||
public string ConcertFolderName { get; set; }
|
||||
public string? ConcertFolderName { get; set; }
|
||||
public bool HideConcertFolder { get; set; }
|
||||
|
||||
public string? WebshareUser { get; set; }
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace CinemaLib.API;
|
||||
|
||||
public class Art
|
||||
{
|
||||
#pragma warning disable CS8618
|
||||
public string poster {get;set;} // imge url
|
||||
public string fanart {get;set;} // image url
|
||||
#pragma warning restore CS8618
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@ namespace CinemaLib.API;
|
||||
|
||||
public class Stream
|
||||
{
|
||||
#pragma warning disable CS8618
|
||||
public string _id {get; set;}
|
||||
public string? name {get;set;}
|
||||
public string media {get;set;}
|
||||
public string provider {get;set;}
|
||||
public DateTime? date_added {get;set;}
|
||||
public string ident {get;set;}
|
||||
#pragma warning restore CS8618
|
||||
public long? size {get;set;}
|
||||
public List<StreamAudio>? audio {get;set;}
|
||||
public List<StreamVideo>? video {get;set;}
|
||||
|
||||
@@ -4,7 +4,9 @@ namespace CinemaLib.API;
|
||||
|
||||
public class StreamAudio
|
||||
{
|
||||
#pragma warning disable CS8618
|
||||
public string language { get; set; } // two letter ISO code
|
||||
public string codec { get; set; } // ie. AAC
|
||||
#pragma warning restore CS8618
|
||||
public int channels { get; set; }
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ namespace CinemaLib.API;
|
||||
|
||||
public class StreamSubtitle
|
||||
{
|
||||
#pragma warning disable CS8618
|
||||
public string language { get; set; } // two letter ISO code
|
||||
#pragma warning restore CS8618
|
||||
public bool forced { get; set; }
|
||||
public string? _id { get; set; }
|
||||
public string? src { get; set; } // url to external subtitles
|
||||
|
||||
@@ -8,7 +8,9 @@ public class StreamVideo
|
||||
{
|
||||
public int width { get; set; } // horizontal resolution in pixels
|
||||
public int height { get; set; } // vertical resolution in pixels
|
||||
#pragma warning disable CS8618
|
||||
public string codec { get; set; } // ie. AVC
|
||||
#pragma warning restore CS8618
|
||||
public double? aspect { get; set; } // aspect ratio, ie. 1.778
|
||||
[JsonPropertyName("hdr")]
|
||||
public JsonElement? hdr_raw_donotuse { get; set; } // ie. Dolby Vision / SMPTE ST 2086
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!--OutputType>Exe</OutputType-->
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
Reference in New Issue
Block a user