Saltar a contenido

Primeros pasos con Video Fingerprinting SDK

Try it Download free trial dotnet add package VisioForge.DotNet.Core Pricing →

¡Bienvenido al VisioForge Video Fingerprinting SDK! Esta guía completa le llevará a través de todo lo que necesita para comenzar, desde la instalación hasta su primera aplicación funcional. Al final de esta guía, tendrá una base sólida para construir aplicaciones de huella digital de video.

Resumen de inicio rápido

Si busca ponerse en marcha rápidamente:

  1. Instale el SDK vía NuGet: Install-Package VisioForge.DotNet.Core
  2. Agregue el paquete de redistribución: Install-Package VisioForge.DotNet.Core.Redist.VideoFingerprinting
  3. Este paquete único soporta Windows (x86/x64/ARM64), Linux (x64/ARM64) y macOS
  4. Establezca su clave de licencia: VFPAnalyzer.SetLicenseKey("TRIAL");
  5. Genere su primera huella digital usando los ejemplos a continuación

Prerrequisitos y requisitos del sistema

Para requisitos detallados del sistema incluyendo plataformas soportadas, especificaciones de hardware y consideraciones de rendimiento, por favor consulte nuestra guía completa de Requisitos del Sistema.

Requisitos específicos de .NET

  • Versión de .NET:
  • Windows: .NET Framework 4.6.1+ o .NET 6.0+
  • Linux: .NET 6.0+
  • macOS: .NET 9.0+
  • Framework de destino (aplicaciones .NET 5+): añada el sistema operativo, -windows en Windows (net8.0-windows) y -macos en macOS (net9.0-macos o posterior). Un framework de destino sin sufijo de sistema operativo (net8.0) es la compilación para Linux: en Windows o macOS informa de que falta la biblioteca nativa.
  • IDE: Visual Studio 2019+ (Windows), Visual Studio Code, o JetBrains Rider
  • Administrador de Paquetes NuGet: Para instalación y actualizaciones fáciles

Métodos de instalación

Método 1: Administrador de paquetes NuGet (recomendado)

La forma más fácil de instalar el SDK es a través del Administrador de Paquetes NuGet en Visual Studio.

Vía interfaz de usuario del Administrador de paquetes

  1. Haga clic derecho en su proyecto en el Explorador de Soluciones
  2. Seleccione "Administrar Paquetes NuGet"
  3. Haga clic en "Examinar" y busque "VisioForge.DotNet.Core"
  4. Seleccione el paquete y haga clic en "Instalar"
  5. Acepte el acuerdo de licencia

Vía consola del Administrador de paquetes

# Instalar el paquete principal del SDK
Install-Package VisioForge.DotNet.Core

# Instalar el paquete de redistribución con bibliotecas nativas (requerido)
# Este paquete incluye soporte para Windows (x86/x64/ARM64), Linux (x64/arm64) y macOS
Install-Package VisioForge.DotNet.Core.Redist.VideoFingerprinting

# Para integración con MongoDB (opcional)
Install-Package VisioForge.DotNet.VideoFingerprinting.MongoDB

Vía CLI de .NET

# Agregar el paquete principal del SDK
dotnet add package VisioForge.DotNet.Core

# Agregar el paquete de redistribución con bibliotecas nativas (requerido)
# Este paquete incluye soporte para Windows (x86/x64/ARM64), Linux (x64/arm64) y macOS
dotnet add package VisioForge.DotNet.Core.Redist.VideoFingerprinting

# Para integración con MongoDB (opcional)
dotnet add package VisioForge.DotNet.VideoFingerprinting.MongoDB

# Restaurar paquetes
dotnet restore

Vía PackageReference (en .csproj)

<ItemGroup>
  <PackageReference Include="VisioForge.DotNet.Core" Version="[2026.10.26]"/>
  <PackageReference Include="VisioForge.DotNet.Core.Redist.VideoFingerprinting" Version="[2026.10.26]"/>

  <!-- Opcional: Integración con MongoDB -->
  <PackageReference Include="VisioForge.DotNet.VideoFingerprinting.MongoDB" Version="[2025.8.6]"/>
</ItemGroup>

Requisitos de Paquetes NuGet

El SDK requiere dos paquetes:

  1. VisioForge.DotNet.Core - La biblioteca principal del SDK con API de C#
  2. VisioForge.DotNet.Core.Redist.VideoFingerprinting - Bibliotecas nativas para funcionalidad de huella digital de video (soporta Windows x86/x64/ARM64, Linux x64/arm64 y macOS)

Ambos paquetes deben instalarse para que el SDK funcione correctamente. El paquete de redistribución contiene bibliotecas nativas específicas de plataforma que se despliegan automáticamente a su directorio de salida.

Paquetes opcionales:

  • VisioForge.DotNet.VideoFingerprinting.MongoDB - Integración con MongoDB para almacenar huellas digitales en una base de datos

Soporte de Plataforma: El paquete VisioForge.DotNet.Core.Redist.VideoFingerprinting incluye bibliotecas nativas para:

  • Windows (x86, x64 y ARM64; ARM64 requiere .NET 6+ y la versión 2026.10.23 o posterior de VisioForge.DotNet.Core y de VisioForge.DotNet.Core.Redist.VideoFingerprinting, en ARM64 una aplicación .NET Framework debe ejecutarse como x86, o como x64 en Windows 11)
  • Linux (x64 y ARM64)
  • macOS (Intel y Apple Silicon)

Las bibliotecas específicas de plataforma correctas se seleccionan y despliegan automáticamente basadas en su tiempo de ejecución objetivo.

Método 2: Instalación manual

Para entornos donde NuGet no está disponible o para escenarios de despliegue personalizados:

  1. Descargue el SDK
  2. Visite la página del producto
  3. Elija su plataforma y arquitectura

  4. Ejecute el instalador

Paquetes adicionales específicos de plataforma

Mientras que el paquete VisioForge.DotNet.Core.Redist.VideoFingerprinting incluye todas las bibliotecas nativas necesarias para huella digital de video, puede necesitar paquetes adicionales para funcionalidad extendida:

Para aplicaciones Windows

# Paquetes adicionales específicos de Windows (opcional, basado en sus necesidades)
Install-Package VisioForge.DotNet.Core.Redist.Base.x64  # Soporte extendido de Windows x64
Install-Package VisioForge.DotNet.Core.Redist.Base.x86  # Soporte extendido de Windows x86

Para aplicaciones móviles

Ningún paquete adicional: los controles VideoView de Apple y Android se fusionaron en VisioForge.DotNet.Core.

Configuración específica de plataforma

Configuración de Windows

No requerida.

Configuración de Linux

  1. Instale Dependencias de GStreamer
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y \
  gstreamer1.0-plugins-base \
  gstreamer1.0-plugins-good \
  gstreamer1.0-plugins-bad \
  gstreamer1.0-plugins-ugly \
  gstreamer1.0-libav

# RHEL/CentOS
sudo yum install -y \
  gstreamer1.0-plugins-base \
  gstreamer1.0-plugins-good \
  gstreamer1.0-plugins-bad \
  gstreamer1.0-plugins-ugly \
  gstreamer1.0-libav

Configuración de macOS

No requerida.

Activación de clave de licencia

Obtener una clave de licencia

  1. Licencia de Prueba
  2. Use cadena vacía para evaluación
  3. Funcionalidad completa con marca de agua
  4. Período de evaluación de 30 días

  5. Licencia Comercial

  6. Compre desde Página del Producto
  7. Reciba clave de licencia vía email
  8. Use clave de licencia en su aplicación

Activar su licencia

using VisioForge.Core.VideoFingerPrinting;

// Al inicio de la aplicación
public static void InitializeSDK()
{
    // Para evaluación de prueba - no hacer nada

    // Para licencia comercial
    VFPAnalyzer.SetLicenseKey("YOUR-LICENSE-KEY-HERE");    
}

Validación de licencia

// Verificar el estado de la licencia
public static bool ValidateLicense()
{
    try
    {
        // Intentar una operación simple para verificar la licencia
        var testSource = new VFPFingerprintSource("test.mp4");
        testSource.StopTime = TimeSpan.FromSeconds(1);

        // Esto fallará si la licencia es inválida
        var fp = VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(testSource).Result;

        return fp != null;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Validación de licencia fallida: {ex.Message}");
        return false;
    }
}

Tipos de licencia

Característica Prueba Comercial
Huella Digital Básica ✅ ✅
Comparación de Video ✅ ✅
Búsqueda de Fragmento ✅ ✅
Soporte de Base de Datos ✅ ✅
Soporte Multiplataforma ✅ ✅
Marca de Agua Sí No
Soporte Técnico Foro Email/Prioridad
Actualizaciones 30 días 1 año

Su primera generación de huella digital

Vamos a crear una aplicación de consola simple que genera una huella digital de video:

Paso 1: Crear un nuevo proyecto

# Crear una nueva aplicación de consola
dotnet new console -n VideoFingerprintingDemo
cd VideoFingerprintingDemo

# Agregar los paquetes del SDK
dotnet add package VisioForge.DotNet.Core
dotnet add package VisioForge.DotNet.Core.Redist.VideoFingerprinting

En Windows, añada -windows a <TargetFramework> en VideoFingerprintingDemo.csproj (net10.0 pasa a net10.0-windows). En macOS añada -macos, que requiere .NET 9 o posterior, Xcode y dotnet workload install macos. El framework de destino que escribe dotnet new console no lleva sufijo de sistema operativo, por lo que es la compilación para Linux.

Paso 2: Implementación básica

using System;
using System.IO;
using System.Threading.Tasks;
using VisioForge.Core.VideoFingerPrinting;
using VisioForge.Core.Types; // para Size / Rect

namespace VideoFingerprintingDemo
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // Inicializar el SDK con su licencia
            VFPAnalyzer.SetLicenseKey("TRIAL");

            // Especificar el archivo de video a procesar
            string videoPath = @"C:\Videos\sample.mp4";

            if (!File.Exists(videoPath))
            {
                Console.WriteLine($"Error: Archivo de video no encontrado en {videoPath}");
                return;
            }

            try
            {
                // Generar la huella digital
                await GenerateFingerprint(videoPath);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
        }

        static async Task GenerateFingerprint(string videoPath)
        {
            Console.WriteLine($"Procesando: {Path.GetFileName(videoPath)}");
            Console.WriteLine("----------------------------------------");

            // Crear configuración de fuente
            var source = new VFPFingerprintSource(videoPath);

            // Opcional: Procesar solo los primeros 30 segundos para pruebas
            source.StopTime = TimeSpan.FromSeconds(30);

            // Opcional: Reducir resolución para procesamiento más rápido
            source.CustomResolution = new VisioForge.Core.Types.Size(640, 480);

            // Generar huella digital con seguimiento de progreso
            var fingerprint = await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(
                source,
                errorDelegate: (error) => {
                    Console.WriteLine($"Error: {error}");
                },
                progressDelegate: (progress) => {
                    Console.Write($"\rProgreso: {progress}%");
                }
            );

            Console.WriteLine(); // Nueva línea después del progreso

            if (fingerprint != null)
            {
                // Mostrar información de la huella digital
                Console.WriteLine("\n¡Huella Digital Generada Exitosamente!");
                Console.WriteLine($"  Duración: {fingerprint.Duration}");
                Console.WriteLine($"  Resolución: {fingerprint.Width}x{fingerprint.Height}");
                Console.WriteLine($"  Tasa de Cuadros: {fingerprint.FrameRate:F2} fps");
                Console.WriteLine($"  Tamaño de Datos: {fingerprint.Data?.Length ?? 0} bytes");

                // Guardar huella digital en archivo
                string outputPath = Path.ChangeExtension(videoPath, ".vfp");
                fingerprint.Save(outputPath);

                Console.WriteLine($"\nHuella digital guardada en: {outputPath}");
                Console.WriteLine($"Tamaño del archivo: {new FileInfo(outputPath).Length / 1024} KB");
            }
            else
            {
                Console.WriteLine("Falló al generar la huella digital.");
            }
        }
    }
}

Paso 3: Ejecutar la aplicación

# Compilar y ejecutar
dotnet build
dotnet run

# Salida esperada:
# Procesando: sample.mp4
# ----------------------------------------
# Progreso: 100%
# 
# ¡Huella Digital Generada Exitosamente!
#   Duración: 00:00:30
#   Resolución: 1920x1080
#   Tasa de Cuadros: 29.97 fps
#   Tamaño de Datos: 125440 bytes
# 
# Huella digital guardada en: C:\Videos\sample.vfp
# Tamaño del archivo: 122 KB

Ejemplo básico de comparación

Ahora vamos a comparar dos videos para determinar su similitud:

using System;
using System.Threading.Tasks;
using VisioForge.Core.VideoFingerPrinting;
using VisioForge.Core.Types; // para Size / Rect

class VideoComparisonDemo
{
    static async Task Main(string[] args)
    {
        VFPAnalyzer.SetLicenseKey("TRIAL");

        string video1 = @"C:\Videos\original.mp4";
        string video2 = @"C:\Videos\copy.mp4";

        await CompareVideos(video1, video2);
    }

    static async Task CompareVideos(string path1, string path2)
    {
        Console.WriteLine("Comparando videos...");
        Console.WriteLine($"Video 1: {Path.GetFileName(path1)}");
        Console.WriteLine($"Video 2: {Path.GetFileName(path2)}");
        Console.WriteLine("----------------------------------------");

        // Crear fuentes con límites de tiempo para comparación rápida
        var source1 = new VFPFingerprintSource(path1)
        {
            StopTime = TimeSpan.FromSeconds(30),
            CustomResolution = new VisioForge.Core.Types.Size(640, 480)
        };

        var source2 = new VFPFingerprintSource(path2)
        {
            StopTime = TimeSpan.FromSeconds(30),
            CustomResolution = new VisioForge.Core.Types.Size(640, 480)
        };

        // Generar huellas digitales
        Console.Write("Generando huella digital 1...");
        var fp1 = await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(source1);
        Console.WriteLine(" Hecho");

        Console.Write("Generando huella digital 2...");
        var fp2 = await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(source2);
        Console.WriteLine(" Hecho");

        if (fp1 != null && fp2 != null)
        {
            // Comparar huellas digitales
            int difference = VFPAnalyzer.Compare(
                fp1, 
                fp2, 
                TimeSpan.FromMilliseconds(500)
            );

            Console.WriteLine($"\nResultados de Comparación:");
            Console.WriteLine($"  Puntaje de Diferencia: {difference}");

            // Interpretar los resultados
            string interpretation = GetInterpretation(difference);
            Console.WriteLine($"  Interpretación: {interpretation}");

            // Proporcionar análisis detallado
            if (difference < 100)
            {
                double similarity = Math.Max(0, 100 - (difference / 3.0));
                Console.WriteLine($"  Similitud: {similarity:F1}%");
            }
        }
        else
        {
            Console.WriteLine("Error: Falló al generar una o ambas huellas digitales");
        }
    }

    static string GetInterpretation(int difference)
    {
        if (difference < 5)
            return "IDÉNTICOS - Mismo video, posiblemente diferente codificación";
        else if (difference < 15)
            return "CASI IDÉNTICOS - Mismo video con diferencias menores de calidad";
        else if (difference < 30)
            return "MUY SIMILARES - Mismo contenido con modificaciones leves";
        else if (difference < 50)
            return "SIMILARES - Mismo contenido con cambios notables (marca de agua, logo, etc.)";
        else if (difference < 100)
            return "RELACIONADOS - Similitudes significativas, probablemente mismo material fuente";
        else if (difference < 300)
            return "ALGO RELACIONADOS - Algunas escenas o contenido común";
        else
            return "DIFERENTES - Videos completamente diferentes";
    }
}

Errores comunes y soluciones

Problema 1: DllNotFoundException

Problema: La aplicación se bloquea con "Unable to load DLL 'VisioForge_VideoFingerprinting'"

Solución:

Agregue el paquete NuGet VisioForge.DotNet.Core.Redist.VideoFingerprinting a su proyecto.

Problema 2: Excepción de memoria insuficiente

Problema: "System.OutOfMemoryException" al procesar videos grandes

Soluciones:

// Solución 1: Usar proceso de 64 bits y aumentar memoria
// Agregar a .csproj:
<PropertyGroup>
  <PlatformTarget>x64</PlatformTarget>
  <LargeAddressAware>true</LargeAddressAware>
</PropertyGroup>

// Solución 2: Reducir resolución de video. VFPFingerprintSource no expone una
// propiedad FrameRate — para reducir los FPS analizados, transcodificar la fuente
// previamente o re-muestrear upstream. Knobs disponibles: CustomResolution,
// CustomCropSize, IgnoredAreas, StartTime / StopTime.
var source = new VFPFingerprintSource(videoPath)
{
    CustomResolution = new VisioForge.Core.Types.Size(320, 240) // Resolución muy baja
};

Problema 3: Velocidad de procesamiento lenta

Problema: La generación de huella digital toma demasiado tiempo

Soluciones:

// Solución 1: Usar procesamiento paralelo para múltiples videos
static async Task ProcessMultipleVideos(string[] videoPaths)
{
    var tasks = videoPaths.Select(path => Task.Run(async () =>
    {
        var source = new VFPFingerprintSource(path)
        {
            CustomResolution = new VisioForge.Core.Types.Size(640, 480)
        };

        return await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(source);
    }));

    var fingerprints = await Task.WhenAll(tasks);
}

// Solución 3: Cachear huellas digitales
class FingerprintCache
{
    private static Dictionary<string, VFPFingerPrint> cache = new();

    public static async Task<VFPFingerPrint> GetOrGenerate(string videoPath)
    {
        string cacheKey = GetCacheKey(videoPath);

        if (cache.ContainsKey(cacheKey))
            return cache[cacheKey];

        string cachePath = $"{videoPath}.vfp";

        if (File.Exists(cachePath))
        {
            var fp = VFPFingerPrint.Load(cachePath);
            cache[cacheKey] = fp;
            return fp;
        }

        // Generar nueva huella digital
        var source = new VFPFingerprintSource(videoPath);
        var fingerprint = await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(source);

        if (fingerprint != null)
        {
            fingerprint.Save(cachePath);
            cache[cacheKey] = fingerprint;
        }

        return fingerprint;
    }

    private static string GetCacheKey(string path)
    {
        var info = new FileInfo(path);
        return $"{path}_{info.Length}_{info.LastWriteTimeUtc.Ticks}";
    }
}

Problema 4: Resultados de similitud incorrectos

Problema: Videos que deberían coincidir se muestran como diferentes

Soluciones:

// Solución 1: Ajustar parámetros de comparación
static int CompareWithTolerance(VFPFingerPrint fp1, VFPFingerPrint fp2)
{
    // Probar diferentes desplazamientos de tiempo
    int[] shifts = { 100, 500, 1000, 2000 }; // milisegundos
    int minDifference = int.MaxValue;

    foreach (int shift in shifts)
    {
        int diff = VFPAnalyzer.Compare(fp1, fp2, TimeSpan.FromMilliseconds(shift));
        minDifference = Math.Min(minDifference, diff);
    }

    return minDifference;
}

// Solución 2: Manejar videos con diferentes relaciones de aspecto.
// El constructor de Rect es (left, top, right, bottom) — NO width/height.
var source = new VFPFingerprintSource(videoFilePath);
{
    // Ignorar áreas letterbox/pillarbox (banda 1920x140 arriba + abajo en frame 1920x1080)
    source.IgnoredAreas.AddRange(new[]
    {
        new Rect(0, 0,    1920, 140),    // Letterbox superior: y en [0, 140)
        new Rect(0, 940,  1920, 1080)    // Letterbox inferior: y en [940, 1080)
    });
};

Resumen de mejores prácticas

Cosas que hacer

  • ✅ Siempre establezca clave de licencia antes de cualquier operación del SDK
  • ✅ Use bloques try-catch alrededor de llamadas del SDK
  • ✅ Procese videos a resolución más baja para análisis más rápido
  • ✅ Cachee huellas digitales para evitar reprocesamiento
  • ✅ Use tipo apropiado de huella digital (Búsqueda vs Comparación)
  • ✅ Pruebe con segmentos de video pequeños primero
  • ✅ Implemente callbacks de progreso para retroalimentación del usuario
  • ✅ Deseche objetos de huella digital cuando termine

Cosas que no hacer

  • ❌ No ignore callbacks de error
  • ❌ No compare huellas digitales de diferentes tipos
  • ❌ No procese múltiples videos grandes simultáneamente sin gestión de memoria

Próximos pasos

Ahora que tiene el SDK instalado y funcionando, explore estos recursos:

  1. Documentación de API - Referencia completa para todas las clases y métodos
  2. Casos de Uso y Aplicaciones - Escenarios de implementación del mundo real
  3. Entendiendo la Tecnología - Inmersión técnica profunda

Obtener ayuda

Recursos

Preguntas comunes

  • P: ¿Puedo usar el SDK en una aplicación web? R: Sí, el SDK puede usarse en aplicaciones ASP.NET Core para procesamiento del lado del servidor.

  • P: ¿Qué formatos de video están soportados? R: MP4, AVI, MKV, MOV, WMV, FLV, WebM y muchos más a través de GStreamer.

  • P: ¿Qué tan precisa es la huella digital? R: Típicamente 95-99% precisa para identificación de contenido, dependiendo de transformaciones.

  • P: ¿Puede detectar videos con marcas de agua agregadas? R: Sí, el SDK puede identificar videos incluso con marcas de agua, logos o subtítulos agregados.

Ejemplo completo funcional

Aquí hay una aplicación de consola completa que demuestra todas las operaciones básicas:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using VisioForge.Core.VideoFingerPrinting;
using VisioForge.Core.Types; // para Size / Rect

namespace VideoFingerprintingDemo
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // Inicializar SDK
            VFPAnalyzer.SetLicenseKey("TRIAL");

            // Configurar rutas
            string videosDir = @"C:\Videos";
            string dbDir = @"C:\FingerprintDB";
            Directory.CreateDirectory(dbDir);

            var app = new FingerprintingApp(videosDir, dbDir);

            while (true)
            {
                Console.WriteLine("\n=== Demo de Huella Digital de Video ===");
                Console.WriteLine("1. Generar huella digital para un video");
                Console.WriteLine("2. Comparar dos videos");
                Console.WriteLine("3. Encontrar fragmento en video");
                Console.WriteLine("4. Construir base de datos de huellas digitales");
                Console.WriteLine("5. Buscar en base de datos videos similares");
                Console.WriteLine("0. Salir");
                Console.Write("\nSelecciona opción: ");

                var choice = Console.ReadLine();
                Console.WriteLine();

                try
                {
                    switch (choice)
                    {
                        case "1":
                            await app.GenerateFingerprint();
                            break;
                        case "2":
                            await app.CompareTwoVideos();
                            break;
                        case "3":
                            await app.FindFragment();
                            break;
                        case "4":
                            await app.BuildDatabase();
                            break;
                        case "5":
                            await app.SearchDatabase();
                            break;
                        case "0":
                            return;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error: {ex.Message}");
                }

                Console.WriteLine("\nPresiona cualquier tecla para continuar...");
                Console.ReadKey();
            }
        }
    }

    class FingerprintingApp
    {
        private string videosDir;
        private string dbDir;
        private Dictionary<string, VFPFingerPrint> database = new Dictionary<string, VFPFingerPrint>();

        public FingerprintingApp(string videosDir, string dbDir)
        {
            this.videosDir = videosDir;
            this.dbDir = dbDir;
            LoadDatabase();
        }

        public async Task GenerateFingerprint()
        {
            Console.Write("Ingresa nombre de archivo de video: ");
            string filename = Console.ReadLine();
            string videoPath = Path.Combine(videosDir, filename);

            if (!File.Exists(videoPath))
            {
                Console.WriteLine("¡Archivo no encontrado!");
                return;
            }

            var source = new VFPFingerprintSource(videoPath);

            Console.Write("¿Procesar video completo? (y/n): ");
            if (Console.ReadLine().ToLower() != "y")
            {
                Console.Write("Ingresa duración en segundos: ");
                if (int.TryParse(Console.ReadLine(), out int seconds))
                {
                    source.StopTime = TimeSpan.FromSeconds(seconds);
                }
            }

            Console.WriteLine("Generando huella digital...");
            var fp = await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(
                source,
                errorDelegate: (msg) => Console.WriteLine($"Error: {msg}"),
                progressDelegate: (p) => Console.Write($"\rProgreso: {p}%")
            );

            if (fp != null)
            {
                string outputPath = Path.ChangeExtension(videoPath, ".vfp");
                fp.Save(outputPath);
                Console.WriteLine($"\n✓ Huella digital guardada en: {outputPath}");
                Console.WriteLine($"  Duración: {fp.Duration}");
                Console.WriteLine($"  Resolución: {fp.Width}x{fp.Height}");
                Console.WriteLine($"  Tasa de Cuadros: {fp.FrameRate:F2} fps");
            }
        }

        public async Task CompareTwoVideos()
        {
            Console.Write("Ingresa nombre de archivo del primer video: ");
            string file1 = Path.Combine(videosDir, Console.ReadLine());

            Console.Write("Ingresa nombre de archivo del segundo video: ");
            string file2 = Path.Combine(videosDir, Console.ReadLine());

            if (!File.Exists(file1) || !File.Exists(file2))
            {
                Console.WriteLine("¡Uno o ambos archivos no encontrados!");
                return;
            }

            Console.WriteLine("Generando huellas digitales...");

            var source1 = new VFPFingerprintSource(file1);
            source1.StopTime = TimeSpan.FromSeconds(30); // Comparación rápida

            var source2 = new VFPFingerprintSource(file2);
            source2.StopTime = TimeSpan.FromSeconds(30);

            var fp1 = await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(source1);
            var fp2 = await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(source2);

            if (fp1 != null && fp2 != null)
            {
                int difference = VFPAnalyzer.Compare(fp1, fp2, TimeSpan.FromMilliseconds(500));

                Console.WriteLine($"\nPuntaje de Diferencia: {difference}");

                if (difference < 5)
                    Console.WriteLine("✓ Videos son IDÉNTICOS");
                else if (difference < 30)
                    Console.WriteLine("✓ Videos son MUY SIMILARES");
                else if (difference < 100)
                    Console.WriteLine("✓ Videos son SIMILARES");
                else if (difference < 300)
                    Console.WriteLine("⚠ Videos tienen ALGUNAS SIMILITUDES");
                else
                    Console.WriteLine("✗ Videos son DIFERENTES");
            }
        }

        public async Task FindFragment()
        {
            Console.Write("Ingresa nombre de archivo de video de fragmento: ");
            string fragmentFile = Path.Combine(videosDir, Console.ReadLine());

            Console.Write("Ingresa nombre de archivo de video completo: ");
            string fullFile = Path.Combine(videosDir, Console.ReadLine());

            if (!File.Exists(fragmentFile) || !File.Exists(fullFile))
            {
                Console.WriteLine("¡Uno o ambos archivos no encontrados!");
                return;
            }

            Console.WriteLine("Procesando fragmento...");
            var fragmentFp = await VFPAnalyzer.GetSearchFingerprintForVideoFileAsync(
                new VFPFingerprintSource(fragmentFile),
                progressDelegate: (p) => Console.Write($"\rFragmento: {p}%")
            );

            Console.WriteLine("\nProcesando video completo...");
            var fullFp = await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(
                new VFPFingerprintSource(fullFile),
                progressDelegate: (p) => Console.Write($"\rVideo completo: {p}%")
            );

            if (fragmentFp != null && fullFp != null)
            {
                Console.WriteLine("\n\nBuscando...");
                var positions = await VFPAnalyzer.SearchAsync(
                    fragmentFp, fullFp, fragmentFp.Duration, 50, true
                );

                if (positions.Count > 0)
                {
                    Console.WriteLine($"✓ Encontradas {positions.Count} ocurrencia(s):");
                    foreach (var pos in positions)
                    {
                        Console.WriteLine($"  - En {pos:hh\\:mm\\:ss}");
                    }
                }
                else
                {
                    Console.WriteLine("✗ Fragmento no encontrado");
                }
            }
        }

        public async Task BuildDatabase()
        {
            var videoFiles = Directory.GetFiles(videosDir, "*.mp4")
                .Concat(Directory.GetFiles(videosDir, "*.avi"))
                .Concat(Directory.GetFiles(videosDir, "*.mkv"))
                .ToList();

            Console.WriteLine($"Encontrados {videoFiles.Count} archivos de video");

            int processed = 0;
            foreach (var videoFile in videoFiles)
            {
                string id = Path.GetFileNameWithoutExtension(videoFile);
                string fpPath = Path.Combine(dbDir, $"{id}.vfp");

                if (File.Exists(fpPath))
                {
                    Console.WriteLine($"Saltando {id} (ya existe)");
                    continue;
                }

                Console.WriteLine($"Procesando {id}...");

                var source = new VFPFingerprintSource(videoFile);
                source.StopTime = TimeSpan.FromSeconds(60); // Solo primer minuto

                var fp = await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(
                    source,
                    progressDelegate: (p) => Console.Write($"\r  Progreso: {p}%")
                );

                if (fp != null)
                {
                    fp.ID = Guid.NewGuid();
                    fp.OriginalFilename = Path.GetFileName(videoFile);
                    fp.Save(fpPath);
                    processed++;
                    Console.WriteLine($"\r  ✓ Huella digital guardada para {id}");
                }
            }

            Console.WriteLine($"\n✓ Procesados {processed} videos");
            LoadDatabase();
        }

        public async Task SearchDatabase()
        {
            Console.Write("Ingresa nombre de archivo de video de consulta: ");
            string queryFile = Path.Combine(videosDir, Console.ReadLine());

            if (!File.Exists(queryFile))
            {
                Console.WriteLine("¡Archivo no encontrado!");
                return;
            }

            Console.Write("Ingresa umbral de similitud (predeterminado 30): ");
            if (!int.TryParse(Console.ReadLine(), out int threshold))
                threshold = 30;

            Console.WriteLine("Generando huella digital de consulta...");
            var queryFp = await VFPAnalyzer.GetComparingFingerprintForVideoFileAsync(
                new VFPFingerprintSource(queryFile) { StopTime = TimeSpan.FromSeconds(60) }
            );

            if (queryFp == null) return;

            Console.WriteLine($"Buscando {database.Count} huellas digitales...");

            var matches = new List<(string id, int score)>();

            foreach (var entry in database)
            {
                int score = VFPAnalyzer.Compare(queryFp, entry.Value, TimeSpan.FromMilliseconds(500));
                if (score < threshold)
                {
                    matches.Add((entry.Key, score));
                }
            }

            if (matches.Count > 0)
            {
                Console.WriteLine($"\n✓ Encontrados {matches.Count} video(s) similar(es):");
                foreach (var match in matches.OrderBy(m => m.score))
                {
                    var fp = database[match.id];
                    Console.WriteLine($"  - {fp.OriginalFilename} (puntaje: {match.score})");
                }
            }
            else
            {
                Console.WriteLine("\n✗ No se encontraron videos similares");
            }
        }

        private void LoadDatabase()
        {
            database.Clear();

            if (!Directory.Exists(dbDir))
                return;

            var files = Directory.GetFiles(dbDir, "*.vfp");
            foreach (var file in files)
            {
                try
                {
                    var fp = VFPFingerPrint.Load(file);
                    string id = Path.GetFileNameWithoutExtension(file);
                    database[id] = fp;
                }
                catch { }
            }

            Console.WriteLine($"Cargadas {database.Count} huellas digitales de la base de datos");
        }
    }
}

Benchmarks de rendimiento

Operación Duración Tamaño de Archivo Tiempo de Procesamiento Uso de Memoria
Generar huella digital 1 minuto 100 MB ~5 segundos 200 MB
Generar huella digital 10 minutos 1 GB ~45 segundos 400 MB
Comparar huellas digitales N/A N/A <1 ms Mínimo
Buscar fragmento 30 seg en 1 hora N/A ~100 ms 100 MB
Consulta de base de datos N/A 1000 videos ~50 ms 250 MB

Resumen

Ahora ha aprendido cómo:

  • ✅ Instalar y configurar el Video Fingerprinting SDK con paquetes NuGet apropiados
  • ✅ Generar huellas digitales desde archivos de video
  • ✅ Comparar videos para similitud
  • ✅ Buscar fragmentos dentro de videos
  • ✅ Construir y consultar una base de datos de huellas digitales
  • ✅ Manejar problemas comunes y optimizar rendimiento

El Video Fingerprinting SDK proporciona una base poderosa para aplicaciones de identificación de contenido, detección de duplicados y monitoreo de medios. Comience con los ejemplos simples e incorpore gradualmente características más avanzadas a medida que crezcan sus necesidades.

¡Felicitaciones! Ahora está listo para construir poderosas aplicaciones de huella digital de video con el SDK de VisioForge.