kurz: analýza videí pomocí Media Services v3

logo Media Services verze 3


hledáte dokumentaci k Media Services v2?

Tento kurz vám ukáže, jak analyzovat video pomocí služby Azure Media Services. Existuje mnoho případů, ve kterých můžete potřebovat získat podrobnější přehled o zaznamenaném video nebo audio obsahu. Pokud chtějí organizace například dosáhnout vyšší spokojenosti zákazníků, mohou převést záznamy řeči zákaznické podpory na text a vytvořit prohledávatelný katalog s rejstříky a řídicími panely.

V tomto kurzu získáte informace o následujících postupech:

  • Stáhněte si ukázkovou aplikaci popsanou v tématu.
  • Projděte si kód, který analyzuje zadané video.
  • Spusťte aplikaci.
  • Prohlédněte si výstup.
  • Vyčistěte prostředky.

Pokud ještě nemáte předplatné Azure,vytvořte si bezplatný účet před tím, než začnete.

Dodržování předpisů, ochrana osobních údajů a zabezpečení

Jako důležité připomenutí musíte dodržovat všechny použitelné zákony v používání Azure video Analyzer pro multimédia (dřív Video Indexer). Nemusíte používat nástroj video Analyzer pro média ani žádnou jinou službu Azure způsobem, který porušuje práva ostatních. Před nahráním videí, včetně jakýchkoli biometrických dat, do analyzátoru videa pro službu Media Service pro zpracování a ukládání, musíte mít všechna patřičná práva, včetně všech příslušných souhlasů, od jednotlivců ve videu. Pokud se chcete dozvědět o dodržování předpisů, ochraně osobních údajů a zabezpečení v analyzátoru videa pro média, Cognitive Services podmínkyAzure. Zásady ochrany osobních údajů od Microsoftu a jejich zpracování najdete v prohlášení o zásadách ochrany osobních údajůod Microsoftu, na základě podmínek pro online služby (OST) a v dodatku pro zpracování dat (DPA). Další informace o ochraně osobních údajů, včetně uchovávání, odstranění nebo zničení dat, jsou k dispozici v OST a zde. Pomocí analyzátoru videa pro média souhlasíte s tím, že budete vázáni Cognitive Services podmínkami, OST, DPA a prohlášením o zásadách ochrany osobních údajů.

Požadavky

Stažení a konfigurace ukázky

Do svého počítače naklonujte pomocí následujícího příkazu úložiště GitHub obsahující ukázku .NET:

git clone https://github.com/Azure-Samples/media-services-v3-dotnet-tutorials.git

Tato ukázka se nachází ve složce AnalyzeVideos.

Otevřete appsettings.jsve stažených projektech. Nahraďte hodnoty přihlašovacími údaji, které jste získali z přístupu k rozhraním API.

Poznámka

Můžete také použít formát souboru .env v kořenovém adresáři projektu a nastavit proměnné prostředí jenom jednou pro všechny projekty v úložišti ukázek .NET. Stačí zkopírovat soubor sample.env a pak vyplnit informace, které jste získali ze stránky Media Services API Access v Azure Portal nebo z Azure CLI. Přejmenujte soubor sample.env na .env a použijte ho ve všech projektech.

Soubor .gitignore je už nakonfigurovaný tak, aby se zabránilo publikování tohoto souboru do vašeho forku úložiště.

Kontrola kódu, který analyzuje dané video

Tato část prozkoumává funkce definované v souboru Program.cs z projektu AnalyzeVideos.

Ukázka dokončí následující akce:

  1. Vytvoří transformaci a úlohu , která analyzuje vaše video.
  2. Vytvoří vstupní Asset a nahraje do něj video. Prostředek se použije jako vstup úlohy.
  3. Vytvoří výstupní prostředek, který ukládá výstup úlohy.
  4. Odešle úlohu.
  5. Zkontroluje stav úlohy.
  6. Stáhne soubory, které jsou výsledkem spuštění úlohy.

začínáme používat rozhraní api pro Media Services se sadou .net SDK

chcete-li začít používat rozhraní Media Services api s rozhraním .net, je nutné vytvořit AzureMediaServicesClient objekt. Chcete-li vytvořit objekt, je nutné zadat přihlašovací údaje klienta pro připojení k Azure pomocí Azure Active Directory. Další možností je použít interaktivní ověřování, které je implementováno v GetCredentialsInteractiveAuthAsync .

public static async Task<IAzureMediaServicesClient> CreateMediaServicesClientAsync(ConfigWrapper config, bool interactive = false)
{
    ServiceClientCredentials credentials;
    if (interactive)
        credentials = await GetCredentialsInteractiveAuthAsync(config);
    else
        credentials = await GetCredentialsAsync(config);

    return new AzureMediaServicesClient(config.ArmEndpoint, credentials)
    {
        SubscriptionId = config.SubscriptionId,
    };
}

V kódu, který jste naklonoval na začátku článku, GetCredentialsAsync funkce vytvoří ServiceClientCredentials objekt na základě přihlašovacích údajů zadaných v místním konfiguračním souboru (appSettings. JSON) nebo pomocí souboru proměnných prostředí . env v kořenovém adresáři úložiště.

private static async Task<ServiceClientCredentials> GetCredentialsAsync(ConfigWrapper config)
{
    // Use ConfidentialClientApplicationBuilder.AcquireTokenForClient to get a token using a service principal with symmetric key

    var scopes = new[] { config.ArmAadAudience + "/.default" };

    var app = ConfidentialClientApplicationBuilder.Create(config.AadClientId)
        .WithClientSecret(config.AadSecret)
        .WithAuthority(AzureCloudInstance.AzurePublic, config.AadTenantId)
        .Build();

    var authResult = await app.AcquireTokenForClient(scopes)
                                             .ExecuteAsync()
                                             .ConfigureAwait(false);

    return new TokenCredentials(authResult.AccessToken, TokenType);
}

V případě interaktivního ověřování GetCredentialsInteractiveAuthAsync funkce vytvoří ServiceClientCredentials objekt na základě interaktivního ověřování a parametrů připojení dodaných v místním konfiguračním souboru (appSettings. JSON) nebo prostřednictvím souboru proměnných prostředí . env v kořenovém adresáři úložiště. V takovém případě nejsou AADCLIENTID a AADSECRET potřeba v souboru proměnných konfigurace nebo prostředí.

private static async Task<ServiceClientCredentials> GetCredentialsInteractiveAuthAsync(ConfigWrapper config)
{
    var scopes = new[] { config.ArmAadAudience + "/user_impersonation" };

    // client application of Az Cli
    string ClientApplicationId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";

    AuthenticationResult result = null;

    IPublicClientApplication app = PublicClientApplicationBuilder.Create(ClientApplicationId)
        .WithAuthority(AzureCloudInstance.AzurePublic, config.AadTenantId)
        .WithRedirectUri("http://localhost")
        .Build();

    var accounts = await app.GetAccountsAsync();

    try
    {
        result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync();
    }
    catch (MsalUiRequiredException ex)
    {
        try
        {
            result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
        }
        catch (MsalException maslException)
        {
            Console.Error.WriteLine($"ERROR: MSAL interactive authentication exception with code '{maslException.ErrorCode}' and message '{maslException.Message}'.");
        }
    }
    catch (MsalException maslException)
    {
        Console.Error.WriteLine($"ERROR: MSAL silent authentication exception with code '{maslException.ErrorCode}' and message '{maslException.Message}'.");
    }

    return new TokenCredentials(result.AccessToken, TokenType);
}

Vytvoření vstupního prostředku a nahrání místního souboru do tohoto prostředku

Funkce CreateInputAsset vytvoří nový vstupní Asset a nahraje zadaný místní videosoubor do souboru. Tento prostředek se použije jako vstup ve vaší úloze kódování. Ve službě Media Services v3 můžete jako vstup úlohy použít buď prostředek, nebo obsah, který jste přes adresu URL protokolu HTTPS zpřístupnili ve svém účtu služby Media Services. Informace o tom, jak kódovat z adresy URL HTTPS, najdete v tomto článku.

Ve službě Media Services v3 slouží k nahrání souborů rozhraní API služby Azure Storage. Následující fragment kódu .NET vám ukáže, jak na to.

Následující funkce dokončí tyto akce:

  • Vytvoří Asset.

  • Získá zapisovatelnou adresu URL SAS kontejneru assetu v úložišti.

    Pokud používáte funkci ListContainerSas assetu k získání adres URL SAS, Všimněte si, že funkce vrací několik adres URL SAS, protože pro každý účet úložiště jsou k dispozici dva klíče účtu úložiště. Účet úložiště má dva klíče, protože umožňuje plynulé střídání klíčů účtu úložiště (například při použití druhého, zahájení použití nového klíče a střídání druhého klíče). První adresa URL SAS představuje úložiště klíč1 a druhé úložiště key2.

  • Nahraje soubor do kontejneru v úložišti pomocí adresy URL SAS.

private static async Task<Asset> CreateInputAssetAsync(
    IAzureMediaServicesClient client,
    string resourceGroupName,
    string accountName,
    string assetName,
    string fileToUpload)
{
    // In this example, we are assuming that the asset name is unique.
    //
    // If you already have an asset with the desired name, use the Assets.Get method
    // to get the existing asset. In Media Services v3, the Get method on entities returns null 
    // if the entity doesn't exist (a case-insensitive check on the name).

    // Call Media Services API to create an Asset.
    // This method creates a container in storage for the Asset.
    // The files (blobs) associated with the asset will be stored in this container.
    Asset asset = await client.Assets.CreateOrUpdateAsync(resourceGroupName, accountName, assetName, new Asset());

    // Use Media Services API to get back a response that contains
    // SAS URL for the Asset container into which to upload blobs.
    // That is where you would specify read-write permissions 
    // and the exparation time for the SAS URL.
    var response = await client.Assets.ListContainerSasAsync(
        resourceGroupName,
        accountName,
        assetName,
        permissions: AssetContainerPermission.ReadWrite,
        expiryTime: DateTime.UtcNow.AddHours(4).ToUniversalTime());

    var sasUri = new Uri(response.AssetContainerSasUrls.First());

    // Use Storage API to get a reference to the Asset container
    // that was created by calling Asset's CreateOrUpdate method.  
    BlobContainerClient container = new BlobContainerClient(sasUri);
    BlobClient blob = container.GetBlobClient(Path.GetFileName(fileToUpload));

    // Use Storage API to upload the file into the container in storage.
    await blob.UploadAsync(fileToUpload);

    return asset;
}

Vytvoření výstupního prostředku k uložení výsledku úlohy

Výstupní Asset ukládá výsledek vaší úlohy. Projekt definuje funkci DownloadResults, která stáhne výsledky z tohoto výstupního prostředku do výstupní složky, kde si je můžete zkontrolovat.

private static async Task<Asset> CreateOutputAssetAsync(IAzureMediaServicesClient client, string resourceGroupName, string accountName, string assetName)
{
    bool existingAsset = true;
    Asset outputAsset;
    try
    {
        // Check if an Asset already exists
        outputAsset = await client.Assets.GetAsync(resourceGroupName, accountName, assetName);
    }
    catch (ErrorResponseException ex) when (ex.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
    {
        existingAsset = false;
    }

    Asset asset = new Asset();
    string outputAssetName = assetName;

    if (existingAsset)
    {
        // Name collision! In order to get the sample to work, let's just go ahead and create a unique asset name
        // Note that the returned Asset can have a different name than the one specified as an input parameter.
        // You may want to update this part to throw an Exception instead, and handle name collisions differently.
        string uniqueness = $"-{Guid.NewGuid():N}";
        outputAssetName += uniqueness;

        Console.WriteLine("Warning – found an existing Asset with name = " + assetName);
        Console.WriteLine("Creating an Asset with this name instead: " + outputAssetName);
    }

    return await client.Assets.CreateOrUpdateAsync(resourceGroupName, accountName, outputAssetName, asset);
}

Vytvoření transformace a úlohy, která analyzuje videa

při kódování nebo zpracování obsahu v Media Services se jedná o společný vzor pro nastavení kódování jako recept. Potom stačí odeslat Úlohu, která tento předpis použije pro video. Když odešlete nové úlohy pro každé nové video, použijete tento recept na všechna videa v knihovně. recept v Media Services se nazývá transformace. Další informace najdete v tématu transformace a úlohy. Ukázka popsaná v tomto kurzu definuje předpis, který analyzuje zadané video.

Transformace

Když vytváříte novou instanci Transformace, musíte určit, co má být jejím výstupem. TransformOutput je povinný parametr. Každý objekt TransformOutput obsahuje Předvolbu. Předvolba popisuje podrobné pokyny operací zpracování videa a/nebo audia, které se používají ke generování požadovaného objektu TransformOutput. V tomto příkladu se používá předvolba VideoAnalyzerPreset a jazyk ("en-US") je předán konstruktoru ( new VideoAnalyzerPreset("en-US") ). Tato předvolba vám umožňuje z videa extrahovat několik audio a video přehledů. Pokud potřebujete z videa extrahovat pouze několik audio přehledů, můžete použít předvolbu AudioAnalyzerPreset.

Při vytváření transformace si nejdříve zajistěte, pokud už existuje, pomocí metody Get , jak je znázorněno v následujícím kódu. Pokud entita v Media Services v3 neexistuje, metoda Get vrátí hodnotu null (v názvu se nerozlišují malá a velká písmena).

private static async Task<Transform> GetOrCreateTransformAsync(IAzureMediaServicesClient client,
    string resourceGroupName,
    string accountName,
    string transformName,
    Preset preset)
{

    bool createTransform = false;
    Transform transform = null;
    try
    {
        // Does a transform already exist with the desired name? Assume that an existing Transform with the desired name
        // also uses the same recipe or Preset for processing content.
        transform = client.Transforms.Get(resourceGroupName, accountName, transformName);
    }
    catch (ErrorResponseException ex) when (ex.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
    {
        createTransform = true;
    }

    if (createTransform)
    {
        // Start by defining the desired outputs.
        TransformOutput[] outputs = new TransformOutput[]
        {
            new TransformOutput(preset),
        };

        // Create the Transform with the output defined above
        transform = await client.Transforms.CreateOrUpdateAsync(resourceGroupName, accountName, transformName, outputs);
    }

    return transform;
}

Úloha

Jak je uvedeno výše, objekt Transformace je předpis a Úloha je vlastní požadavek na službu Media Services, aby transformaci použila na daný vstupní videoobsah nebo zvukový obsah. Úloha určuje informace, jako je umístění vstupního videa a umístění výstupu. Umístění videa můžete zadat pomocí adres URL protokolu HTTPS, adres URL podpisu SAS nebo prostředků, které máte ve svém účtu služby Media Services.

V tomto příkladu je vstupem úlohy místní video.

private static async Task<Job> SubmitJobAsync(IAzureMediaServicesClient client,
    string resourceGroupName,
    string accountName,
    string transformName,
    string jobName,
    JobInput jobInput,
    string outputAssetName)
{
    JobOutput[] jobOutputs =
    {
        new JobOutputAsset(outputAssetName),
    };

    // In this example, we are assuming that the job name is unique.
    //
    // If you already have a job with the desired name, use the Jobs.Get method
    // to get the existing job. In Media Services v3, Get methods on entities returns null 
    // if the entity doesn't exist (a case-insensitive check on the name).
    Job job = await client.Jobs.CreateAsync(
        resourceGroupName,
        accountName,
        transformName,
        jobName,
        new Job
        {
            Input = jobInput,
            Outputs = jobOutputs,
        });

    return job;
}

Čekání na dokončení úlohy

Dokončení úlohy trvá déle. V takovém případě chcete být upozorněni. Existují různé možnosti, jak získat upozornění na dokončení úlohy . Nejjednodušší možnost (zobrazená tady) je použití cyklického dotazování.

Cyklické dotazování není doporučeným osvědčeným postupem pro produkční aplikace kvůli možné latenci. Pokud se dotazování u některého účtu používá nadměrně, je možné ho omezit. Místo dotazování by vývojáři měli používat službu Event Grid.

Služba Event Grid je navržená pro vysokou dostupnost, konzistentní výkon a dynamické škálování. Díky službě Event Grid můžou vaše aplikace naslouchat událostem a reagovat na ně, ať už pocházejí z kterékoli služby Azure. Události můžou pocházet i z vlastních zdrojů. Jednoduché, reaktivní zpracování událostí založené na protokolu HTTP pomáhá sestavovat efektivní řešení prostřednictvím inteligentního filtrování a směrování událostí. Další informace najdete v tématu Směrování událostí do vlastního webového koncového bodu.

Úloha obvykle prochází následujícími stavy: Naplánováno, Ve frontě, Zpracovávání a Dokončeno (konečný stav). Pokud se úloha dokončí v rámci chyby, zobrazí se chybový stav. Pokud se úloha právě zrušila, zobrazí se po dokončení operace Zrušení a potom Zrušeno.

private static async Task<Job> WaitForJobToFinishAsync(IAzureMediaServicesClient client,
    string resourceGroupName,
    string accountName,
    string transformName,
    string jobName)
{
    const int SleepIntervalMs = 20 * 1000;

    Job job;
    do
    {
        job = await client.Jobs.GetAsync(resourceGroupName, accountName, transformName, jobName);

        Console.WriteLine($"Job is '{job.State}'.");
        for (int i = 0; i < job.Outputs.Count; i++)
        {
            JobOutput output = job.Outputs[i];
            Console.Write($"\tJobOutput[{i}] is '{output.State}'.");
            if (output.State == JobState.Processing)
            {
                Console.Write($"  Progress (%): '{output.Progress}'.");
            }

            Console.WriteLine();
        }

        if (job.State != JobState.Finished && job.State != JobState.Error && job.State != JobState.Canceled)
        {
            await Task.Delay(SleepIntervalMs);
        }
    }
    while (job.State != JobState.Finished && job.State != JobState.Error && job.State != JobState.Canceled);

    return job;
}

Kódy chyb úlohy

Viz Kódy chyb.

Stažení výsledku úlohy

Následující funkce stáhne výsledky z výstupního assetu do složky "output", abyste mohli prozkoumat výsledky úlohy.

private static async Task DownloadOutputAssetAsync(
    IAzureMediaServicesClient client,
    string resourceGroup,
    string accountName,
    string assetName,
    string outputFolderName)
{
    if (!Directory.Exists(outputFolderName))
    {
        Directory.CreateDirectory(outputFolderName);
    }

    AssetContainerSas assetContainerSas = await client.Assets.ListContainerSasAsync(
        resourceGroup,
        accountName,
        assetName,
        permissions: AssetContainerPermission.Read,
        expiryTime: DateTime.UtcNow.AddHours(1).ToUniversalTime());

    Uri containerSasUrl = new Uri(assetContainerSas.AssetContainerSasUrls.FirstOrDefault());
    BlobContainerClient container = new BlobContainerClient(containerSasUrl);

    string directory = Path.Combine(outputFolderName, assetName);
    Directory.CreateDirectory(directory);

    Console.WriteLine($"Downloading output results to '{directory}'...");

    string continuationToken = null;
    IList<Task> downloadTasks = new List<Task>();

    do
    {
        var resultSegment = container.GetBlobs().AsPages(continuationToken);

        foreach (Azure.Page<BlobItem> blobPage in resultSegment)
        {
            foreach (BlobItem blobItem in blobPage.Values)
            {
                var blobClient = container.GetBlobClient(blobItem.Name);
                string filename = Path.Combine(directory, blobItem.Name);

                downloadTasks.Add(blobClient.DownloadToAsync(filename));
            }
            // Get the continuation token and loop until it is empty.
            continuationToken = blobPage.ContinuationToken;
        }


    } while (continuationToken != "");

    await Task.WhenAll(downloadTasks);

    Console.WriteLine("Download complete.");
}

Vyčištění prostředků v účtu služby Media Services

Upozornění

Je důležité odstranit prostředky, pokud je už nepotřebujete, protože se vám budou účtovat.

Obecně platí, že byste měli vyčistit všechno kromě objektů, které plánujete znovu použít (obvykle znovu použijete transformace a trvalé streamovací lokátory). Pokud chcete, aby byl váš účet po experimentování čistý, odstraňte prostředky, které nechcete znovu použít. Například následující kód odstraní úlohu a výstupní prostředek:

Odstranění prostředků pomocí kódu

private static async Task CleanUpAsync(
   IAzureMediaServicesClient client,
   string resourceGroupName,
   string accountName,
   string transformName,
   string jobName,
   List<string> assetNames,
   string contentKeyPolicyName = null
   )
{
    await client.Jobs.DeleteAsync(resourceGroupName, accountName, transformName, jobName);

    foreach (var assetName in assetNames)
    {
        await client.Assets.DeleteAsync(resourceGroupName, accountName, assetName);
    }

    if (contentKeyPolicyName != null)
    {
        client.ContentKeyPolicies.Delete(resourceGroupName, accountName, contentKeyPolicyName);
    }
}

Můžete také použít rozhraní příkazového řádku.

Odstranění skupiny prostředků pomocí rozhraní příkazového řádku

az group delete --name <your-resource-group-name>

Spuštění ukázkové aplikace

Stisknutím kombinace kláves Ctrl+F5 spusťte aplikaci AnalyzeVideos.

Když program spustíte, úloha vytvoří miniatury každého obličeje, který ve videu najde. Zároveň vytvoří soubor insights.json.

Prozkoumání výstupu

Výstupní soubor analyzování videa se nazývá insights.json. Tento soubor obsahuje přehledy o vašem videu. Popis jednotlivých elementů nalezených v souboru JSON získáte v článku Inteligentní funkce médií.

Multithreading

Upozornění

Následující Azure Media Services v3 nejsou bezpečné pro vlákno. Při práci s aplikací s více vlákny byste měli pro jedno vlákno vygenerovat nový objekt AzureMediaServicesClient.

Další kroky