VideoHash is a Swift package for generating video fingerprints on macOS:
PHash: perceptual hash for near-duplicate detection.OSHash: OpenSubtitles hash for exact file identity.
The default PHash pipeline is compatibility-focused and matches peolic/videohashes output.
- macOS 26.0+
- Swift 6.2+
- Xcode 17+
ffmpegavailable onPATH(or setHashConfiguration.ffmpegPath)
dependencies:[.package(url:"https://github.com/fdenis75/VideoHash.git", from:"0.2.0")]Then add the product dependency:
.product(name:"VideoHash",package:"VideoHash")import VideoHash
letgenerator=VideoHashGenerator()leturl=URL(fileURLWithPath:"/path/to/video.mp4")letresult=tryawait generator.generateHashes(for: url)print("PHash: \(result.phash)")print("OSHash: \(result.oshash)")print("Duration: \(Int(result.duration))s")Batch hashing with controlled concurrency:
leturls:[URL]=[URL(fileURLWithPath:"/path/to/a.mp4"),URL(fileURLWithPath:"/Volumes/Archive/b.mp4")]letresults=tryawait generator.generateHashes(
for: urls,
maxConcurrentTasks:4)letconfig=HashConfiguration(
frameCount:25,
frameWidth:160,
spriteColumns:5,
spriteRows:5,
dctSize:32,
hashSize:8,
useAccelerate:false,
useFFmpegFrameExtraction:true,
ffmpegPath:nil)letgenerator=VideoHashGenerator(configuration: config)Notes:
useFFmpegFrameExtraction: trueis the default and is recommended for parity withvideohashes.useFFmpegFrameExtraction: falseuses the AVFoundation/CoreGraphics path.phashis emitted as lowercase hexadecimal (not zero-padded).
swift build
swift test
swift run test-hash /path/to/video.mp4
swift run test-hash /path/to/folder 4Manual parity check against the original tool:
./.build/debug/test-hash /path/to/video.mp4
/opt/bin/videohashes-amd64-macos /path/to/video.mp4Sources/VideoHash/Models: shared models and errorsSources/VideoHash/OSHash: OSHash implementationSources/VideoHash/PHash: PHash pipelineSources/VideoHash/Utilities: logging helpersTests/VideoHashTests: test suite
MIT. See LICENSE.
PHash compatibility is based on peolic/videohashes.