Analise o conteúdo de vídeo em busca de material censurável em C#

Este artigo fornece informações e exemplos de código para ajudá-lo a começar a usar o SDK do Content Moderator para .NET para verificar conteúdo de vídeo para conteúdo adulto ou racista.

Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.

Pré-requisitos

Configurar recursos do Azure

O recurso de moderação de vídeo do Moderador de Conteúdo está disponível como um processador de mídia de visualização pública gratuito nos Serviços de Mídia do Azure (AMS). Os Serviços de Mídia do Azure são um serviço especializado do Azure para armazenar e transmitir conteúdo de vídeo.

Criar uma conta dos Azure Media Services

Siga as instruções em Criar uma conta dos Serviços de Mídia do Azure para assinar o AMS e criar uma conta de armazenamento do Azure associada. Nessa conta de armazenamento, crie um novo contêiner de armazenamento de Blob.

Criar um aplicativo Microsoft Entra

Navegue até sua nova assinatura do AMS no portal do Azure e selecione Acesso à API no menu lateral. Selecione Conectar aos Serviços de Mídia do Azure com a entidade de serviço. Observe o valor no campo de ponto de extremidade da API REST, você precisará disso mais tarde.

Na seção Aplicativo Microsoft Entra, selecione Criar Novo e nomeie seu novo registro de aplicativo Microsoft Entra (por exemplo, "VideoModADApp"). Selecione Salvar e aguarde alguns minutos enquanto o aplicativo está configurado. Em seguida, você verá seu novo registro de aplicativo na seção do aplicativo Microsoft Entra da página.

Selecione o registro do aplicativo e clique no botão Gerenciar aplicativo abaixo dele. Anote o valor no campo ID do aplicativo, você precisará disso mais tarde. Selecione Configurações>Chaves e insira uma descrição para uma nova chave (como "VideoModKey"). Selecione Salvar e observe o novo valor de chave. Copie esta string e salve-a em algum lugar seguro.

Para obter um passo a passo mais completo do processo acima, consulte Introdução à autenticação do Microsoft Entra.

Depois de fazer isso, você pode usar o processador de mídia de moderação de vídeo de duas maneiras diferentes.

Usar o Azure Media Services Explorer

O Azure Media Services Explorer é um frontend amigável para AMS. Use-o para navegar na sua conta AMS, carregar vídeos e digitalizar conteúdo com o processador de mídia do Content Moderator. Transfira e instale-o a partir do GitHub ou consulte a publicação do blogue do Azure Media Services Explorer para obter mais informações.

Azure Media Services explorer with Content Moderator

Criar o projeto do Visual Studio

  1. No Visual Studio, crie um novo projeto de aplicativo de console (.NET Framework) e nomeie-o VideoModeration.
  2. Se houver outros projetos na sua solução, selecione esta como o único projeto de arranque.
  3. Obtenha os pacotes NuGet necessários. Clique com o botão direito do mouse em seu projeto no Gerenciador de Soluções e selecione Gerenciar Pacotes NuGet, em seguida, localize e instale os seguintes pacotes:
    • WindowsAzure.MediaServices
    • windowsazure.mediaservices.extensions

Adicionar código de moderação de vídeo

Depois, vai copiar e colar o código neste guia no projeto, para implementar um cenário de moderação de conteúdos simples.

Atualizar as instruções de utilização do programa

Adicione as declarações using seguintes à parte superior do ficheiro Program.cs.

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.MediaServices.Client;
using System.IO;
using System.Threading;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using System.Collections.Generic;

Configurar referências de recursos

Adicione os seguintes campos estáticos à classe Programa em Program.cs. Esses campos contêm as informações necessárias para se conectar à sua assinatura AMS. Preencha-os com os valores obtidos nas etapas acima. Observe que é o valor de ID do aplicativo do seu aplicativo Microsoft Entra e CLIENT_SECRET é o valor do "VideoModKey" que CLIENT_ID você criou para esse aplicativo.

// declare constants and globals
private static CloudMediaContext _context = null;
private static CloudStorageAccount _StorageAccount = null;

// Azure Media Services (AMS) associated Storage Account, Key, and the Container that has
// a list of Blobs to be processed.
static string STORAGE_NAME = "YOUR AMS ASSOCIATED BLOB STORAGE NAME";
static string STORAGE_KEY = "YOUR AMS ASSOCIATED BLOB STORAGE KEY";
static string STORAGE_CONTAINER_NAME = "YOUR BLOB CONTAINER FOR VIDEO FILES";

private static StorageCredentials _StorageCredentials = null;

// Azure Media Services authentication.
private const string AZURE_AD_TENANT_NAME = "microsoft.onmicrosoft.com";
private const string CLIENT_ID = "YOUR CLIENT ID";
private const string CLIENT_SECRET = "YOUR CLIENT SECRET";

// REST API endpoint, for example "https://accountname.restv2.westcentralus.media.azure.net/API".
private const string REST_API_ENDPOINT = "YOUR API ENDPOINT";

// Content Moderator Media Processor Nam
private const string MEDIA_PROCESSOR = "Azure Media Content Moderator";

// Input and Output files in the current directory of the executable
private const string INPUT_FILE = "VIDEO FILE NAME";
private const string OUTPUT_FOLDER = "";

// JSON settings file
private static readonly string CONTENT_MODERATOR_PRESET_FILE = "preset.json";

Importante

Lembre-se de remover as chaves do seu código quando terminar e nunca publicá-las publicamente. Para produção, use uma maneira segura de armazenar e acessar suas credenciais, como o Azure Key Vault. Consulte o artigo de segurança dos serviços de IA do Azure para obter mais informações.

Se você deseja usar um arquivo de vídeo local (caso mais simples), adicione-o ao projeto e insira seu caminho como o INPUT_FILE valor (os caminhos relativos são relativos ao diretório de execução).

Você também precisará criar o arquivo preset.json no diretório atual e usá-lo para especificar um número de versão. Por exemplo:

{
    "version": "2.0"
}

Carregue o(s) vídeo(s) de entrada

O método Main da classe Program criará um Contexto de Mídia do Azure e, em seguida, um Contexto de Armazenamento do Azure (caso seus vídeos estejam no armazenamento de blobs). O código restante verifica um vídeo de uma pasta local, blob ou vários blobs dentro de um contêiner de armazenamento do Azure. Você pode tentar todas as opções comentando as outras linhas de código.

// Create Azure Media Context
CreateMediaContext();

// Create Storage Context
CreateStorageContext();

// Use a file as the input.
IAsset asset = CreateAssetfromFile();

// -- OR ---

// Or a blob as the input
// IAsset asset = CreateAssetfromBlob((CloudBlockBlob)GetBlobsList().First());

// Then submit the asset to Content Moderator
RunContentModeratorJob(asset);

//-- OR ----

// Just run the content moderator on all blobs in a list (from a Blob Container)
// RunContentModeratorJobOnBlobs();

Criar um contexto de mídia do Azure

Adicione o seguinte método à classe Programa. Isso usa suas credenciais AMS para permitir a comunicação com o AMS.

// Creates a media context from azure credentials
static void CreateMediaContext()
{
    // Get Azure AD credentials
    var tokenCredentials = new AzureAdTokenCredentials(AZURE_AD_TENANT_NAME,
        new AzureAdClientSymmetricKey(CLIENT_ID, CLIENT_SECRET),
        AzureEnvironments.AzureCloudEnvironment);

    // Initialize an Azure AD token
    var tokenProvider = new AzureAdTokenProvider(tokenCredentials);

    // Create a media context
    _context = new CloudMediaContext(new Uri(REST_API_ENDPOINT), tokenProvider);
}

Adicionar o código para criar um Contexto de Armazenamento do Azure

Adicione o seguinte método à classe Programa. Você usa o contexto de armazenamento, criado a partir de suas credenciais de armazenamento, para acessar seu armazenamento de blob.

// Creates a storage context from the AMS associated storage name and key
static void CreateStorageContext()
{
    // Get a reference to the storage account associated with a Media Services account.
    if (_StorageCredentials == null)
    {
        _StorageCredentials = new StorageCredentials(STORAGE_NAME, STORAGE_KEY);
    }
    _StorageAccount = new CloudStorageAccount(_StorageCredentials, false);
}

Adicionar o código para criar Ativos de Mídia do Azure a partir de arquivo e blob local

O processador de mídia do Content Moderator executa trabalhos em Ativos dentro da plataforma de Serviços de Mídia do Azure. Esses métodos criam os Assets a partir de um arquivo local ou de um blob associado.

// Creates an Azure Media Services Asset from the video file
static IAsset CreateAssetfromFile()
{
    return _context.Assets.CreateFromFile(INPUT_FILE, AssetCreationOptions.None); ;
}

// Creates an Azure Media Services asset from your blog storage
static IAsset CreateAssetfromBlob(CloudBlockBlob Blob)
{
    // Create asset from the FIRST blob in the list and return it
    return _context.Assets.CreateFromBlob(Blob, _StorageCredentials, AssetCreationOptions.None);
}

Adicione o código para digitalizar uma coleção de vídeos (como blobs) dentro de um contêiner

// Runs the Content Moderator Job on all Blobs in a given container name
static void RunContentModeratorJobOnBlobs()
{
    // Get the reference to the list of Blobs. See the following method.
    var blobList = GetBlobsList();

    // Iterate over the Blob list items or work on specific ones as needed
    foreach (var sourceBlob in blobList)
    {
        // Create an Asset
        IAsset asset = _context.Assets.CreateFromBlob((CloudBlockBlob)sourceBlob,
                            _StorageCredentials, AssetCreationOptions.None);
        asset.Update();

        // Submit to Content Moderator
        RunContentModeratorJob(asset);
    }
}

// Get all blobs in your container
static IEnumerable<IListBlobItem> GetBlobsList()
{
    // Get a reference to the Container within the Storage Account
    // that has the files (blobs) for moderation
    CloudBlobClient CloudBlobClient = _StorageAccount.CreateCloudBlobClient();
    CloudBlobContainer MediaBlobContainer = CloudBlobClient.GetContainerReference(STORAGE_CONTAINER_NAME);

    // Get the reference to the list of Blobs
    var blobList = MediaBlobContainer.ListBlobs();
    return blobList;
}

Adicionar o método para executar o trabalho do moderador de conteúdo

// Run the Content Moderator job on the designated Asset from local file or blob storage
static void RunContentModeratorJob(IAsset asset)
{
    // Grab the presets
    string configuration = File.ReadAllText(CONTENT_MODERATOR_PRESET_FILE);

    // grab instance of Azure Media Content Moderator MP
    IMediaProcessor mp = _context.MediaProcessors.GetLatestMediaProcessorByName(MEDIA_PROCESSOR);

    // create Job with Content Moderator task
    IJob job = _context.Jobs.Create(String.Format("Content Moderator {0}",
            asset.AssetFiles.First() + "_" + Guid.NewGuid()));

    ITask contentModeratorTask = job.Tasks.AddNew("Adult and racy classifier task",
            mp, configuration,
            TaskOptions.None);
    contentModeratorTask.InputAssets.Add(asset);
    contentModeratorTask.OutputAssets.AddNew("Adult and racy classifier output",
        AssetCreationOptions.None);

    job.Submit();


    // Create progress printing and querying tasks
    Task progressPrintTask = new Task(() =>
    {
        IJob jobQuery = null;
        do
        {
            var progressContext = _context;
            jobQuery = progressContext.Jobs
            .Where(j => j.Id == job.Id)
                .First();
                Console.WriteLine(string.Format("{0}\t{1}",
                DateTime.Now,
                jobQuery.State));
                Thread.Sleep(10000);
            }
            while (jobQuery.State != JobState.Finished &&
            jobQuery.State != JobState.Error &&
            jobQuery.State != JobState.Canceled);
    });
    progressPrintTask.Start();

    Task progressJobTask = job.GetExecutionProgressTask(
    CancellationToken.None);
    progressJobTask.Wait();

    // If job state is Error, the event handling
    // method for job progress should log errors.  Here we check
    // for error state and exit if needed.
    if (job.State == JobState.Error)
    {
        ErrorDetail error = job.Tasks.First().ErrorDetails.First();
        Console.WriteLine(string.Format("Error: {0}. {1}",
        error.Code,
        error.Message));
    }

    DownloadAsset(job.OutputMediaAssets.First(), OUTPUT_FOLDER);
}

Adicionar funções auxiliares

Esses métodos baixam o arquivo de saída do Content Moderator (JSON) do ativo Serviços de Mídia do Azure e ajudam a controlar o status do trabalho de moderação para que o programa possa registrar um status de execução no console.

static void DownloadAsset(IAsset asset, string outputDirectory)
{
    foreach (IAssetFile file in asset.AssetFiles)
    {
        file.Download(Path.Combine(outputDirectory, file.Name));
    }
}

// event handler for Job State
static void StateChanged(object sender, JobStateChangedEventArgs e)
{
    Console.WriteLine("Job state changed event:");
    Console.WriteLine("  Previous state: " + e.PreviousState);
    Console.WriteLine("  Current state: " + e.CurrentState);
    switch (e.CurrentState)
    {
        case JobState.Finished:
            Console.WriteLine();
            Console.WriteLine("Job finished.");
            break;
        case JobState.Canceling:
        case JobState.Queued:
        case JobState.Scheduled:
        case JobState.Processing:
            Console.WriteLine("Please wait...\n");
            break;
        case JobState.Canceled:
            Console.WriteLine("Job is canceled.\n");
            break;
        case JobState.Error:
            Console.WriteLine("Job failed.\n");
            break;
        default:
            break;
    }
}

Executar o programa e rever o resultado

Depois que o trabalho de moderação de conteúdo for concluído, analise a resposta JSON. Consiste nos seguintes elementos:

  • Resumo de informações em vídeo
  • Tiros como "fragmentos"
  • Quadros-chave como "eventos" com uma revisãoRecomendado" (= verdadeiro ou falso)" sinalizador com base nas pontuações Adulto e Racy
  • start, duration, totalDuration e timestamp estão em "ticks". Divida por escala de tempo para obter o número em segundos.

Nota

  • adultScore representa a presença potencial e a pontuação de previsão de conteúdo que pode ser considerado sexualmente explícito ou adulto em determinadas situações.
  • racyScore representa a presença potencial e a pontuação de previsão de conteúdo que pode ser considerado sexualmente sugestivo ou maduro em determinadas situações.
  • adultScore e estão entre 0 e racyScore 1. Quanto maior a pontuação, maior o modelo está prevendo que a categoria pode ser aplicável. Esta pré-visualização baseia-se num modelo estatístico em vez de resultados codificados manualmente. Recomendamos testar com seu próprio conteúdo para determinar como cada categoria se alinha às suas necessidades.
  • reviewRecommended é verdadeira ou falsa, dependendo dos limiares internos de pontuação. Os clientes devem avaliar se devem usar esse valor ou decidir sobre limites personalizados com base em suas políticas de conteúdo.
{
"version": 2,
"timescale": 90000,
"offset": 0,
"framerate": 50,
"width": 1280,
"height": 720,
"totalDuration": 18696321,
"fragments": [
{
    "start": 0,
    "duration": 18000
},
{
    "start": 18000,
    "duration": 3600,
    "interval": 3600,
    "events": [
    [
        {
        "reviewRecommended": false,
        "adultScore": 0.00001,
        "racyScore": 0.03077,
        "index": 5,
        "timestamp": 18000,
        "shotIndex": 0
        }
    ]
    ]
},
{
    "start": 18386372,
    "duration": 119149,
    "interval": 119149,
    "events": [
    [
        {
        "reviewRecommended": true,
        "adultScore": 0.00000,
        "racyScore": 0.91902,
        "index": 5085,
        "timestamp": 18386372,
        "shotIndex": 62
        }
    ]
    ]
}
]
}

Próximos passos

Baixe a solução Visual Studio para este e outros inícios rápidos do Content Moderator para .NET.