`AudioSignature` is the DSP — band table, periodic Hann, radix-2 FFT, band-mean peak, energy class, packing — and `AudioSignatureService` the decode, running the FFmpeg binary `IMediaEncoder.EncoderPath` names. The plugin gained no dependency. The server specification's prose does not determine a byte stream, so the parameters it leaves open are pinned by the fixture shared with the extraction repo and restated at the top of `AudioSignature`: double throughout, whole frames only, periodic Hann, unnormalised FFT, band mean rather than sum, argmax ties to the lowest index. `fixtures/audio/` holds the extraction repo's three files byte-identically and the computed signature equals the recorded vector exactly. The binding check regenerates the fixture PCM from `make_fixture.py`'s arithmetic and verifies it against the recorded decode checksums, so it runs on a host with no codec at all and a decode divergence stays distinguishable from a DSP one; the two tests that drive real FFmpeg self-skip without a binary. The workflow named "Test Plugin" until now only compiled one. A test that is built and never run is not evidence, and a golden vector shared across two repos exists precisely so CI fails when they drift. TRACES: JR-042, JR-043 | SR-003
69 lines
3.0 KiB
XML
69 lines
3.0 KiB
XML
<Project Sdk="Microsoft.NET.Sdk">
|
|
|
|
<PropertyGroup>
|
|
<TargetFramework>net9.0</TargetFramework>
|
|
<Nullable>enable</Nullable>
|
|
<IsPackable>false</IsPackable>
|
|
<!--
|
|
The plugin project treats warnings as errors and runs StyleCop. Tests do
|
|
not inherit that: their naming conventions differ deliberately (Method_
|
|
Condition_Expectation reads as documentation, and trips SA1300-family
|
|
rules), and a style failure in a test is not a defect in the thing under
|
|
test.
|
|
-->
|
|
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
|
<GenerateDocumentationFile>false</GenerateDocumentationFile>
|
|
<!--
|
|
The plugin targets net9.0 to match Jellyfin's ABI, but a machine that can
|
|
build it need not have the 9.0 *runtime* installed. Roll the test host
|
|
forward to whatever major is present so the suite runs on a developer box
|
|
and on CI without pinning either to a runtime that is not the plugin's.
|
|
-->
|
|
<RollForward>LatestMajor</RollForward>
|
|
<!--
|
|
The plugin framework-references Microsoft.AspNetCore.App through
|
|
Jellyfin.Controller, and that reference flows into anything referencing
|
|
the plugin. The T1 tier tests pure logic that touches no web type, so
|
|
inheriting the web framework would make the suite unrunnable on any box
|
|
without the ASP.NET Core runtime for no benefit. .NET resolves assemblies
|
|
lazily, so types that never touch ASP.NET load fine without it.
|
|
|
|
T2 (controllers, authorisation) genuinely needs that runtime. When those
|
|
tests arrive they belong in a second project that keeps this reference.
|
|
-->
|
|
<DisableTransitiveFrameworkReferences>true</DisableTransitiveFrameworkReferences>
|
|
</PropertyGroup>
|
|
|
|
<ItemGroup>
|
|
<!--
|
|
The plugin sets ExcludeAssets=runtime on these: at run time the Jellyfin
|
|
server supplies them, so shipping copies in the plugin would risk loading
|
|
a second, different MediaBrowser.Common. The test host is not the server,
|
|
so it has to bring its own — hence the same packages without that
|
|
exclusion, and only here.
|
|
-->
|
|
<PackageReference Include="Jellyfin.Controller" Version="10.11.5" />
|
|
<PackageReference Include="Jellyfin.Model" Version="10.11.5" />
|
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
|
<PackageReference Include="xunit" Version="2.9.2" />
|
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<ProjectReference Include="..\Jellyfin.Plugin.JRay\Jellyfin.Plugin.JRay.csproj" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<!--
|
|
The audio-signature golden vector, shared verbatim with the extraction
|
|
repo (JR-043): the same three files, byte for byte, in both repos. Two
|
|
independent implementations of one fingerprint are only useful if they
|
|
agree exactly, and this is what makes that a checked claim.
|
|
-->
|
|
<Content Include="fixtures\**\*">
|
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
</Content>
|
|
</ItemGroup>
|
|
|
|
</Project>
|