fix bugs with playout mode multiple (#2160)
This commit is contained in:
@@ -106,6 +106,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Split main `Settings` page into multiple pages
|
||||
- Update UI layout on all pages to be less cramped and to work better on mobile
|
||||
- Add CPU and Video Controller info to `Troubleshooting` > `General` output
|
||||
- Expand special zero-count case for `Multiple` playout mode with playlists
|
||||
- This configuration will automatically maintain the multiple count so that it is equal to the number of items in each playlist item
|
||||
- This configuration should be used if you want to play every media item in a playlist item exactly once before advancing
|
||||
|
||||
### Fixed
|
||||
- Fix QSV acceleration in docker with older Intel devices
|
||||
@@ -127,6 +130,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Fix some NVIDIA edge cases when media servers don't provide video bit depth information
|
||||
- Fix VAAPI tonemap failure
|
||||
- Fix green bars after VAAPI tonemap
|
||||
- Fix bug where playout mode `Multiple` would ignore fixed start time
|
||||
|
||||
## [25.2.0] - 2025-06-24
|
||||
### Added
|
||||
|
||||
@@ -840,6 +840,113 @@ public class PlayoutBuilderTests
|
||||
result.Anchor.NextStartOffset.ShouldBe(HoursAfterMidnight(7));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task FloodContent_Should_FloodAroundFixedContent_Multiple_With_Gap()
|
||||
{
|
||||
var floodCollection = new Collection
|
||||
{
|
||||
Id = 1,
|
||||
Name = "Flood Items",
|
||||
MediaItems = new List<MediaItem>
|
||||
{
|
||||
TestMovie(1, TimeSpan.FromMinutes(50), new DateTime(2020, 1, 1)),
|
||||
TestMovie(2, TimeSpan.FromHours(1), new DateTime(2020, 2, 1))
|
||||
}
|
||||
};
|
||||
|
||||
var fixedCollection = new Collection
|
||||
{
|
||||
Id = 2,
|
||||
Name = "Fixed Items",
|
||||
MediaItems = new List<MediaItem>
|
||||
{
|
||||
TestMovie(3, TimeSpan.FromHours(2), new DateTime(2020, 1, 1)),
|
||||
TestMovie(4, TimeSpan.FromHours(1), new DateTime(2020, 1, 2))
|
||||
}
|
||||
};
|
||||
|
||||
var fakeRepository = new FakeMediaCollectionRepository(
|
||||
Map(
|
||||
(floodCollection.Id, floodCollection.MediaItems.ToList()),
|
||||
(fixedCollection.Id, fixedCollection.MediaItems.ToList())));
|
||||
|
||||
var items = new List<ProgramScheduleItem>
|
||||
{
|
||||
new ProgramScheduleItemFlood
|
||||
{
|
||||
Id = 1,
|
||||
Index = 1,
|
||||
Collection = floodCollection,
|
||||
CollectionId = floodCollection.Id,
|
||||
StartTime = null,
|
||||
PlaybackOrder = PlaybackOrder.Chronological
|
||||
},
|
||||
new ProgramScheduleItemMultiple
|
||||
{
|
||||
Id = 2,
|
||||
Index = 2,
|
||||
Collection = fixedCollection,
|
||||
CollectionId = fixedCollection.Id,
|
||||
StartTime = TimeSpan.FromHours(3),
|
||||
Count = 2,
|
||||
PlaybackOrder = PlaybackOrder.Chronological
|
||||
}
|
||||
};
|
||||
|
||||
var playout = new Playout
|
||||
{
|
||||
ProgramSchedule = new ProgramSchedule
|
||||
{
|
||||
Items = items
|
||||
},
|
||||
Channel = new Channel(Guid.Empty) { Id = 1, Name = "Test Channel" },
|
||||
ProgramScheduleAnchors = new List<PlayoutProgramScheduleAnchor>(),
|
||||
Items = new List<PlayoutItem>(),
|
||||
ProgramScheduleAlternates = new List<ProgramScheduleAlternate>(),
|
||||
FillGroupIndices = []
|
||||
};
|
||||
|
||||
IConfigElementRepository configRepo = Substitute.For<IConfigElementRepository>();
|
||||
var televisionRepo = new FakeTelevisionRepository();
|
||||
IArtistRepository artistRepo = Substitute.For<IArtistRepository>();
|
||||
IMultiEpisodeShuffleCollectionEnumeratorFactory factory =
|
||||
Substitute.For<IMultiEpisodeShuffleCollectionEnumeratorFactory>();
|
||||
ILocalFileSystem localFileSystem = Substitute.For<ILocalFileSystem>();
|
||||
var builder = new PlayoutBuilder(
|
||||
Substitute.For<IPlayoutTimeShifter>(),
|
||||
configRepo,
|
||||
fakeRepository,
|
||||
televisionRepo,
|
||||
artistRepo,
|
||||
factory,
|
||||
localFileSystem,
|
||||
_logger);
|
||||
|
||||
DateTimeOffset start = HoursAfterMidnight(0);
|
||||
DateTimeOffset finish = start + TimeSpan.FromHours(7);
|
||||
|
||||
Playout result = await builder.Build(playout, PlayoutBuildMode.Reset, start, finish, _cancellationToken);
|
||||
|
||||
result.Items.Count.ShouldBe(6);
|
||||
|
||||
result.Items[0].StartOffset.TimeOfDay.ShouldBe(TimeSpan.Zero);
|
||||
result.Items[0].MediaItemId.ShouldBe(1);
|
||||
result.Items[1].StartOffset.TimeOfDay.ShouldBe(TimeSpan.FromMinutes(50));
|
||||
result.Items[1].MediaItemId.ShouldBe(2);
|
||||
result.Items[2].StartOffset.TimeOfDay.ShouldBe(TimeSpan.FromMinutes(50 + 60));
|
||||
result.Items[2].MediaItemId.ShouldBe(1);
|
||||
|
||||
result.Items[3].StartOffset.TimeOfDay.ShouldBe(TimeSpan.FromHours(3));
|
||||
result.Items[3].MediaItemId.ShouldBe(3);
|
||||
result.Items[4].StartOffset.TimeOfDay.ShouldBe(TimeSpan.FromHours(5));
|
||||
result.Items[4].MediaItemId.ShouldBe(4);
|
||||
|
||||
result.Items[5].StartOffset.TimeOfDay.ShouldBe(TimeSpan.FromHours(6));
|
||||
result.Items[5].MediaItemId.ShouldBe(2);
|
||||
|
||||
result.Anchor.NextStartOffset.ShouldBe(HoursAfterMidnight(7));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task FloodContent_Should_FloodWithFixedStartTime()
|
||||
{
|
||||
|
||||
@@ -16,6 +16,77 @@ public class PlayoutModeSchedulerMultipleTests : SchedulerTestBase
|
||||
|
||||
private CancellationToken _cancellationToken;
|
||||
|
||||
[Test]
|
||||
public void Should_Respect_Fixed_Start_Time()
|
||||
{
|
||||
Collection collectionOne = TwoItemCollection(1, 2, TimeSpan.FromHours(1));
|
||||
|
||||
var scheduleItem = new ProgramScheduleItemMultiple
|
||||
{
|
||||
Id = 1,
|
||||
Index = 1,
|
||||
CollectionType = ProgramScheduleItemCollectionType.Collection,
|
||||
Collection = collectionOne,
|
||||
CollectionId = collectionOne.Id,
|
||||
StartTime = TimeSpan.FromHours(1),
|
||||
PlaybackOrder = PlaybackOrder.Chronological,
|
||||
TailFiller = null,
|
||||
FallbackFiller = null,
|
||||
Count = 0,
|
||||
CustomTitle = "CustomTitle"
|
||||
};
|
||||
|
||||
var scheduleItemsEnumerator = new OrderedScheduleItemsEnumerator(
|
||||
new List<ProgramScheduleItem> { scheduleItem },
|
||||
new CollectionEnumeratorState());
|
||||
|
||||
var enumerator = new ChronologicalMediaCollectionEnumerator(
|
||||
collectionOne.MediaItems,
|
||||
new CollectionEnumeratorState());
|
||||
|
||||
var collectionItemCount = new Dictionary<CollectionKey, int>
|
||||
{
|
||||
{ CollectionKey.ForScheduleItem(scheduleItem), collectionOne.MediaItems.Count }
|
||||
}.ToMap();
|
||||
|
||||
PlayoutBuilderState startState = StartState(scheduleItemsEnumerator);
|
||||
|
||||
var scheduler = new PlayoutModeSchedulerMultiple(collectionItemCount, Substitute.For<ILogger>());
|
||||
(PlayoutBuilderState playoutBuilderState, List<PlayoutItem> playoutItems) = scheduler.Schedule(
|
||||
startState,
|
||||
CollectionEnumerators(scheduleItem, enumerator),
|
||||
scheduleItem,
|
||||
NextScheduleItem,
|
||||
HardStop(scheduleItemsEnumerator),
|
||||
_cancellationToken);
|
||||
|
||||
playoutBuilderState.CurrentTime.ShouldBe(startState.CurrentTime.AddHours(3));
|
||||
playoutItems.Last().FinishOffset.ShouldBe(playoutBuilderState.CurrentTime);
|
||||
|
||||
playoutBuilderState.NextGuideGroup.ShouldBe(2); // one guide group here because of custom title
|
||||
playoutBuilderState.DurationFinish.IsNone.ShouldBeTrue();
|
||||
playoutBuilderState.InFlood.ShouldBeFalse();
|
||||
playoutBuilderState.MultipleRemaining.IsNone.ShouldBeTrue();
|
||||
playoutBuilderState.InDurationFiller.ShouldBeFalse();
|
||||
playoutBuilderState.ScheduleItemsEnumerator.State.Index.ShouldBe(0);
|
||||
|
||||
enumerator.State.Index.ShouldBe(0);
|
||||
|
||||
playoutItems.Count.ShouldBe(2);
|
||||
|
||||
playoutItems[0].MediaItemId.ShouldBe(1);
|
||||
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime.AddHours(1));
|
||||
playoutItems[0].GuideGroup.ShouldBe(1);
|
||||
playoutItems[0].FillerKind.ShouldBe(FillerKind.None);
|
||||
playoutItems[0].CustomTitle.ShouldBe("CustomTitle");
|
||||
|
||||
playoutItems[1].MediaItemId.ShouldBe(2);
|
||||
playoutItems[1].StartOffset.ShouldBe(startState.CurrentTime.AddHours(2));
|
||||
playoutItems[1].GuideGroup.ShouldBe(1);
|
||||
playoutItems[1].FillerKind.ShouldBe(FillerKind.None);
|
||||
playoutItems[1].CustomTitle.ShouldBe("CustomTitle");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_Fill_Exactly_To_Next_Schedule_Item()
|
||||
{
|
||||
|
||||
@@ -24,6 +24,8 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
|
||||
|
||||
public ImmutableList<PlaylistEnumeratorCollectionKey> ChildEnumerators { get; private set; }
|
||||
|
||||
public bool CurrentEnumeratorPlayAll => _playAll[EnumeratorIndex];
|
||||
|
||||
public int EnumeratorIndex { get; private set; }
|
||||
|
||||
public void ResetState(CollectionEnumeratorState state) =>
|
||||
|
||||
@@ -33,19 +33,34 @@ public class PlayoutModeSchedulerMultiple : PlayoutModeSchedulerBase<ProgramSche
|
||||
|
||||
PlayoutBuilderState nextState = playoutBuilderState with
|
||||
{
|
||||
CurrentTime = firstStart,
|
||||
MultipleRemaining = playoutBuilderState.MultipleRemaining.IfNone(scheduleItem.Count)
|
||||
};
|
||||
|
||||
if (nextState.MultipleRemaining == 0)
|
||||
{
|
||||
nextState = nextState with
|
||||
{
|
||||
MultipleRemaining = _collectionItemCount[CollectionKey.ForScheduleItem(scheduleItem)]
|
||||
};
|
||||
}
|
||||
|
||||
IMediaCollectionEnumerator contentEnumerator =
|
||||
collectionEnumerators[CollectionKey.ForScheduleItem(scheduleItem)];
|
||||
|
||||
if (nextState.MultipleRemaining == 0)
|
||||
{
|
||||
// playlist count of zero means play all media items in the current playlist item
|
||||
if (contentEnumerator is PlaylistEnumerator { CurrentEnumeratorPlayAll: true } playlistEnumerator)
|
||||
{
|
||||
nextState = nextState with
|
||||
{
|
||||
MultipleRemaining = playlistEnumerator
|
||||
.ChildEnumerators[playlistEnumerator.EnumeratorIndex]
|
||||
.Enumerator.Count
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
nextState = nextState with
|
||||
{
|
||||
MultipleRemaining = _collectionItemCount[CollectionKey.ForScheduleItem(scheduleItem)]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
while (contentEnumerator.Current.IsSome && nextState.MultipleRemaining > 0 &&
|
||||
nextState.CurrentTime < hardStop)
|
||||
{
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<NoWarn>VSTHRD200</NoWarn>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<AnalysisLevel>latest-Recommended</AnalysisLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blurhash.ImageSharp" Version="4.0.0" />
|
||||
<PackageReference Include="CliWrap" Version="3.9.0" />
|
||||
<PackageReference Include="Dapper" Version="2.1.66" />
|
||||
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="9.0.7" />
|
||||
<PackageReference Include="Jint" Version="4.4.0" />
|
||||
<PackageReference Include="Lucene.Net" Version="4.8.0-beta00017" />
|
||||
<PackageReference Include="Lucene.Net.Analysis.Common" Version="4.8.0-beta00017" />
|
||||
<PackageReference Include="Lucene.Net.QueryParser" Version="4.8.0-beta00017" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Refit" Version="8.0.0" />
|
||||
<PackageReference Include="Refit.Newtonsoft.Json" Version="8.0.0" />
|
||||
<PackageReference Include="Refit.Xml" Version="8.0.0" />
|
||||
<PackageReference Include="Scriban.Signed" Version="6.2.1" />
|
||||
<PackageReference Include="TagLibSharp" Version="2.3.0" />
|
||||
|
||||
|
||||
<!-- transitive; upgrading for vuln -->
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ErsatzTV.Core\ErsatzTV.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
|
||||
<_Parameter1>ErsatzTV.Infrastructure.Tests</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<NoWarn>VSTHRD200</NoWarn>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<AnalysisLevel>latest-Recommended</AnalysisLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blurhash.ImageSharp" Version="4.0.0" />
|
||||
<PackageReference Include="CliWrap" Version="3.9.0" />
|
||||
<PackageReference Include="Dapper" Version="2.1.66" />
|
||||
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="9.0.7" />
|
||||
<PackageReference Include="Jint" Version="4.4.0" />
|
||||
<PackageReference Include="Lucene.Net" Version="4.8.0-beta00017" />
|
||||
<PackageReference Include="Lucene.Net.Analysis.Common" Version="4.8.0-beta00017" />
|
||||
<PackageReference Include="Lucene.Net.QueryParser" Version="4.8.0-beta00017" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Refit" Version="8.0.0" />
|
||||
<PackageReference Include="Refit.Newtonsoft.Json" Version="8.0.0" />
|
||||
<PackageReference Include="Refit.Xml" Version="8.0.0" />
|
||||
<PackageReference Include="Scriban.Signed" Version="6.2.1" />
|
||||
<PackageReference Include="TagLibSharp" Version="2.3.0" />
|
||||
|
||||
|
||||
<!-- transitive; upgrading for vuln -->
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ErsatzTV.Core\ErsatzTV.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
|
||||
<_Parameter1>ErsatzTV.Infrastructure.Tests</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,45 +1,45 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Configurations>Debug;Release;Debug No Sync</Configurations>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
<UserSecretsId>729e6271-c307-43c8-8e36-1b36c39f6de2</UserSecretsId>
|
||||
<AnalysisLevel>latest-Recommended</AnalysisLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ErsatzTV.Core\ErsatzTV.Core.csproj" />
|
||||
<ProjectReference Include="..\ErsatzTV.Infrastructure.MySql\ErsatzTV.Infrastructure.MySql.csproj" />
|
||||
<ProjectReference Include="..\ErsatzTV.Infrastructure.Sqlite\ErsatzTV.Infrastructure.Sqlite.csproj" />
|
||||
<ProjectReference Include="..\ErsatzTV.Infrastructure\ErsatzTV.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CliWrap" Version="3.9.0" />
|
||||
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
|
||||
<PackageReference Include="LanguageExt.Core" Version="4.4.9" />
|
||||
<PackageReference Include="MediatR" Version="[12.5.0]" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.7" />
|
||||
<PackageReference Include="Serilog" Version="4.3.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta6.25358.103" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
|
||||
<_Parameter1>ErsatzTV.Scanner.Tests</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Configurations>Debug;Release;Debug No Sync</Configurations>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
<UserSecretsId>729e6271-c307-43c8-8e36-1b36c39f6de2</UserSecretsId>
|
||||
<AnalysisLevel>latest-Recommended</AnalysisLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ErsatzTV.Core\ErsatzTV.Core.csproj" />
|
||||
<ProjectReference Include="..\ErsatzTV.Infrastructure.MySql\ErsatzTV.Infrastructure.MySql.csproj" />
|
||||
<ProjectReference Include="..\ErsatzTV.Infrastructure.Sqlite\ErsatzTV.Infrastructure.Sqlite.csproj" />
|
||||
<ProjectReference Include="..\ErsatzTV.Infrastructure\ErsatzTV.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CliWrap" Version="3.9.0" />
|
||||
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
|
||||
<PackageReference Include="LanguageExt.Core" Version="4.4.9" />
|
||||
<PackageReference Include="MediatR" Version="[12.5.0]" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.7" />
|
||||
<PackageReference Include="Serilog" Version="4.3.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta6.25358.103" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
|
||||
<_Parameter1>ErsatzTV.Scanner.Tests</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user