Prdb.Hashing 0.1.0

dotnet add package Prdb.Hashing --version 0.1.0
                    
NuGet\Install-Package Prdb.Hashing -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Prdb.Hashing" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Prdb.Hashing" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Prdb.Hashing" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Prdb.Hashing --version 0.1.0
                    
#r "nuget: Prdb.Hashing, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Prdb.Hashing@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Prdb.Hashing&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Prdb.Hashing&version=0.1.0
                    
Install as a Cake Tool

Prdb.Hashing

Computes the osHash and pHash values that the prdb Public API identifies video files by — the same values Stash computes, bit for bit.

Separate from the Prdb.Sdk package on purpose: this one starts processes and needs ffmpeg, which an HTTP client has no business doing. Use them together or either alone.

Install

dotnet add package Prdb.Hashing

The perceptual hash shells out to ffmpeg and ffprobe, which have to be on PATH or configured explicitly. OSHash does not need them.

Use

using Prdb.Hashing;

// OSHash: cheap, exact, and null for a file under 128 KiB.
string? osHash = OsHash.Compute("/media/scene.mkv");

// Perceptual hash: decodes 25 frames, so it belongs in a background queue.
var hasher = new VideoPerceptualHasher();
var result = await hasher.ComputeAsync("/media/scene.mkv");

if (result.IsComputed)
    Console.WriteLine(result.Hash);      // 16 lowercase hex characters
else
    Console.WriteLine(result.Outcome);   // ProbeFailed, FrameCaptureFailed, TimedOut, ...

Point it at a specific ffmpeg, and give it longer on slow storage:

var hasher = new VideoPerceptualHasher(new VideoHashingOptions
{
    FfmpegPath = "/opt/ffmpeg/bin/ffmpeg",   // ffprobe is found next to it
    FrameTimeout = TimeSpan.FromMinutes(5),
});

Compare two perceptual hashes by Hamming distance, never for equality:

int? distance = PerceptualHashDistance.Between(left, right);

if (distance <= PerceptualHashDistance.DefaultThreshold)   // 8 of 64 bits, as Stash uses
    // ... the same content in a different encode

Two things worth knowing

Failures are returned, not thrown. On a real library, a truncated download or a container ffmpeg cannot seek is routine. A caller working through a backlog needs to record the outcome against that file and carry on, so only cancellation propagates.

Casing differs across the API boundary. This package produces lowercase hex; the API normalises to uppercase on write. Its validation is case-insensitive, so lookups work either way — but a local store usually compares bytes, and there a mirrored uppercase hash never matches a locally computed one. The miss is silent. FileHashes.Normalize and FileHashes.ForPrdbLookup convert in each direction.

Compatibility

The method is specified in docs/video-hashing.md, in enough detail to reimplement from, with public test vectors. This package is a transcription of it and reproduces the reference's quirks deliberately — a perceptual hash that does not match what everyone else computes is worth very little.

License

MIT — see LICENSE.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 1,163 8/9/2026