Öğretici: Media Services v3 ile videoları analiz etme

media services logosu v3


v2 Media Services mı arayabilirsiniz?

Bu öğreticide Azure Media Services ile videoları analiz etme işlemi gösterilir. Kayıtlı videolar veya ses içerikleri hakkında derin içgörüler kazanmak isteyebileceğiniz çok sayıda senaryo mevcuttur. Örneğin, daha yüksek müşteri memnuniyeti elde etmek isteyen kuruluşlar, müşteri destek kayıtlarını dizinler ve panolarla aranabilir bir katalog haline getirmek için konuşmayı metne dönüştürme işlemini çalıştırabilir.

Bu öğretici şunların nasıl yapıldığını gösterir:

  • Konu başlığında açıklanan örnek uygulamayı indirin.
  • Belirtilen videoyu analiz etmek için kodu inceleme.
  • Uygulamayı çalıştırın.
  • Çıkışı inceleyin.
  • Kaynakları temizleyin.

Azure aboneliğiniz yoksa başlamadan önce ücretsiz bir hesap oluşturun.

Uyumluluk, Gizlilik ve Güvenlik

Önemli bir anımsatıcı olarak, Medya için Azure Video Çözümleyicisi 'nin (eski adı Video Indexer) kullanımınıza uygun olması gerekir. Medya için Video Analyzer'ı veya başka bir Azure hizmetini başkalarının haklarını ihlal eden bir şekilde kullanmamanız gerekir. Biyometrik veriler de dahil olmak üzere herhangi bir videoyu işleme ve depolama için Medya için Video Çözümleyicisi hizmetine yüklemeden önce, videonun kişilerinden gelen tüm uygun onaylar da dahil olmak üzere tüm uygun haklara sahip olmak gerekir. Medya için Video Analyzer'da uyumluluk, gizlilik ve güvenlik hakkında bilgi edinmek için Azure Bilişsel Hizmetler Koşulları. Microsoft'un gizlilik yükümlülükleri ve verilerinizi işlemesi için Microsoft'un Gizlilik Bildirimi,Çevrimiçi Hizmet Şartları (OST) ve Veri İşleme Ekini ("DPA") gözden geçirebilirsiniz. Veri saklama, silme/yok etme gibi daha fazla gizlilik bilgisi OST'de ve burada mevcuttur. Medya için Video Analyzer'ı kullanarak Bilişsel Hizmetler Koşullarına, OST'ye, DPA'ya ve Gizlilik Bildirimi'ne bağlı olduğunu kabul etmiş oluruz.

Önkoşullar

Örneği indirme ve yapılandırma

Aşağıdaki komutu kullanarak, .NET örneğini içeren bir GitHub havuzunu makinenize kopyalayın:

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

Örnek, AnalyzeVideos klasöründe yer alır.

İndirilen projenizde appsettings.jsaçın. Değerleri, API 'lere eriştiğinizkimlik bilgileriyle değiştirin.

Not

Ayrıca, .NET örnekleri deposundaki tüm projeler için ortam değişkenlerinizi yalnızca bir kez ayarlamak üzere, projenin kökündeki . env dosya biçimini de kullanabilirsiniz. sample. env dosyasını kopyalamanız yeterlidir ve sonra Azure portal veya Azure clı 'dan Media Services apı erişimi sayfasından aldığınız bilgileri doldurun. Sample. env dosyasını tüm projelerde kullanmak için yalnızca . env olarak yeniden adlandırın.

. Gitignore dosyası, bu dosyanın otomatik olarak yayınlanmasını engellemek için zaten yapılandırılmış.

Belirtilen videoyu analiz eden kodu inceleme

Bu bölümde, AnalyzeVideos projesinin Program.cs dosyasında tanımlı işlevler incelenmektedir.

Örnek aşağıdaki eylemleri tamamlar:

  1. Videolarınızı analiz etmek için bir Dönüşüm ve İş oluşturur.
  2. Bir giriş Varlığı oluşturur ve videoyu buna yükler. Varlık, işin girişi olarak kullanılır.
  3. İşin çıkışını depolayan bir çıkış varlığı oluşturur.
  4. İşi gönderir.
  5. İşin durumunu denetler.
  6. İşin çalıştırılması sonucu oluşan dosyaları indirir.

.NET SDK Media Services API'leri kullanmaya başlama

.NET ile Media Services API'leri kullanmaya başlamak için bir nesnesi oluşturmanız AzureMediaServicesClient gerekir. Nesnesini oluşturmak için istemcinin Azure'a bağlanmak için kimlik bilgilerini Azure Active Directory. Bir diğer seçenek de içinde uygulanan etkileşimli kimlik doğrulamasını GetCredentialsInteractiveAuthAsync kullanmak.

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,
    };
}

Makalenin başında kopyalanan kodda işlev, yerel yapılandırma dosyasında GetCredentialsAsync ServiceClientCredentials (appsettings.json) veya deponun kökünde .env ortam değişkenleri dosyası aracılığıyla sağlanan kimlik bilgilerine göre nesnesini oluşturur.

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);
}

Etkileşimli kimlik doğrulaması durumunda işlev, etkileşimli bir kimlik doğrulamasını ve yerel yapılandırma dosyasında GetCredentialsInteractiveAuthAsync ServiceClientCredentials (appsettings.json) veya deponun kökünde .env ortam değişkenleri dosyası aracılığıyla sağlanan bağlantı parametrelerini temel alarak nesneyi oluşturur. Bu durumda, yapılandırma veya ortam değişkenleri dosyasında AADCLIENTID ve AADSECRET gerekli değildir.

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);
}

Bir giriş varlığı oluşturma ve içine yerel dosya yükleme

CreateInputAsset işlevi yeni bir giriş Varlığı oluşturur ve içine belirtilen yerel video dosyasını yükler. Bu Varlık, kodlama işinizde giriş olarak kullanılır. Media Services v3’te bir İşe yapılan giriş, Varlık olabilir veya HTTPS URL’leri üzerinden Media Services hesabınızın kullanımına açtığınız bir içerik olabilir. HTTPS URL'lerinden kodlama hakkında bilgi edinmek için bu makaleye bakın.

Media Services v3’te dosyaları karşıya yüklemek için Azure Depolama API’lerini kullanırsınız. Aşağıdaki .NET kod parçacığı bunun nasıl yapıldığını gösterir.

Aşağıdaki işlev bu eylemleri tamamlar:

  • Bir Varlık oluşturur.

  • Depolamada Varlığın kapsayıcısı için yazılabilir bir SAS URL'si alır.

    SAS URL'lerini almak için varlığın ListContainerSas işlevini kullanıyorsanız, her depolama hesabı için iki depolama hesabı anahtarı olduğu için işlevin birden çok SAS URL'leri döndüren bir işlev olduğunu unutmayın. Depolama hesabının iki anahtarı vardır çünkü depolama hesabı anahtarlarının sorunsuz bir şekilde döndürülerek döndürülebilir (örneğin, birini kullanırken diğer anahtarı değiştirerek yeni anahtarı kullanmaya başlayabilir ve diğer anahtarı döndürebilirsiniz). 1. SAS URL'si depolama anahtarı1 ve ikinci bir depolama anahtarı2'yi temsil eder.

  • SAS URL'sini kullanarak dosyayı depolama alanı içinde kapsayıcıya yükler.

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;
}

İşin sonucunu depolamak için çıkış varlığı oluşturma

Çıktı varlığı, işinizin sonucunu depolar. Proje, bu çıktı varlığının sonuçlarını "output" klasörüne indiren DownloadResults işlevini tanımlar, böylece elinizde neyin olduğunu görebilirsiniz.

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);
}

Bir dönüşüm ve videoları analiz eden bir iş oluşturma

İçerikleri kodlarken veya Media Services, kodlama ayarlarını bir tarif olarak ayarlamak yaygın bir desendir. Daha sonra bu tarifi bir videoya uygulamak üzere bir İş gönderirsiniz. Her yeni video için yeni İşler göndererek bu tarifi kitaplığınız içinde yer alan tüm videolara uyguluyor oluruz. Verilerde tarif Media Services Dönüşüm olarak adlandırılan bir tarif. Daha fazla bilgi için bkz. Dönüşümler ve işler. Bu öğreticide açıklanan örnek, belirtilen videoyu analiz eden bir tarifi tanımlar.

Dönüşüm

Yeni bir Dönüşüm örneği oluştururken çıktı olarak neyi üretmesi istediğinizi belirtmeniz gerekir. TransformOutput gerekli bir parametredir. Her TransformOutput bir Ön ayar içerir. Ön ayar, video ve/veya ses işleme işlemlerinin istenen TransformOutput nesnesini oluşturmak üzere kullanılacak adım adım yönergelerini açıklar. Bu örnekte, VideoAnalyzerPreset ön ayarı kullanılır ve dil ("en-US") oluşturucus na geçirilmektedir ( new VideoAnalyzerPreset("en-US") ). Bu ön ayar, bir videodan birden fazla ses ve video içgörüsü elde etmenizi sağlar. Bir videodan birden fazla ses içgörüsü elde etmeniz gerekiyorsa AudioAnalyzerPreset ön ayarını kullanın.

Dönüşüm oluştururken, önce aşağıdaki kodda gösterildiği gibi Get yöntemini kullanarak birinin zaten var olup olamay olduğunu kontrol edin. Media Services v3’te varlıklar üzerindeki Get yöntemleri, varlığın mevcut olmaması durumunda null değerini döndürür (büyük/küçük harfe duyarlı ad denetimi).

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;
}

İş

Yukarıda bahsedildiği gibi Transform nesnesi tarif, Job ise bu Transform nesnesini belirli bir giriş videosu veya ses içeriğine uygulamak için Media Services’e gönderilen gerçek istektir. İş, giriş videonun konumu ve çıkışın konumu gibi bilgileri belirtir. Videonuzun konumunu, Media Services hesabınızda bulunan HTTPS URL’lerini, SAS URL’lerini veya Varlıkları kullanarak belirtebilirsiniz.

Bu örnekte, iş girdisi yerel bir videodur.

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;
}

İşin tamamlanmasını bekleyin

İş biraz zaman alır. Olduğunda, size bildirilecek. İşin tamamlanması hakkında bildirim almaya ilişkin farklı seçenekler mevcuttur. En basit seçenek (burada gösterilmiştir) yoklama kullanmaktır.

Yoklama, olası gecikme süresi nedeniyle üretim uygulamaları için önerilen en iyi yöntem değildir. Yoklama, bir hesap üzerinde gereğinden fazla kullanılırsa kısıtlanabilir. Geliştiricilerin onun yerine Event Grid kullanmalıdır.

Event Grid yüksek kullanılabilirlik, tutarlı performans ve dinamik ölçek için tasarlanmıştır. Event Grid ile uygulamalarınız neredeyse tüm Azure hizmetleri ve özel kaynaklardan gelen olayları takip edip bu olaylara yanıt verebilir. Basit, HTTP tabanlı reaktif olay işleme özelliği, olayların akıllı filtrelenmesi ve yönlendirilmesi sayesinde etkili çözümler oluşturmanıza yardımcı olur. Daha fazla bilgi için bkz. Olayları özel bir web uç noktasına yönlendirme.

İş genellik şu aşamalardan geçer: Zamanlandı, Kuyruğa Alındı, İşleniyor, Tamamlandı (son aşama). İş bir hatayla karşılaştı ise Hata durumunu alırsınız. İş iptal etme sürecinde ise İptal Ediliyor ve işlem tamam olduğunda İptal Edildi olarak kabul edilir.

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;
}

İş hata kodları

Bkz. Hata kodları.

İşin sonucunu indirme

Aşağıdaki işlev, işin sonuçlarını incelemek için çıktı Varlığı'nın sonuçlarını "output" klasörüne indirir.

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.");
}

Media Services hesabınızdaki kaynakları temizleme

Uyarı

Kaynakları sizin için faturalandırılacaksınız, artık gerekmiyorsa silmeniz önemlidir.

Genel olarak, yeniden kullanmayı planladığınız nesneler dışında her şeyi temizlemeniz gerekir (genellikle Dönüşümleri yeniden kullanır ve StreamingLocators'da kalıcı olur). Denemeden sonra hesabınız temiz olacaksa, yeniden kullanmayı planlamayabilirsiniz kaynakları silin. Örneğin, aşağıdaki kod işi ve çıktı varlını siler:

Kod ile kaynakları silme

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);
    }
}

CLI'sini de kullanabilirsiniz.

CLı ile bir kaynak grubunu silme

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

Örnek uygulamayı çalıştırma

AnalyzeVideos uygulamasını çalıştırmak için Ctrl+F5 tuşlarına basın.

Programı çalıştırdığınızda iş, videoda bulduğu her yüz için küçük resimler üretir. Ayrıca, insights.json dosyasını oluşturur.

Çıktıyı inceleme

Analiz edilen videoların çıktı dosyası insights.json olarak adlandırılır. Bu dosya, videonuz hakkında içgörüler içerir. Json dosyasındaki öğelerin açıklamalarını Medya zekası makalesinde bulabilirsiniz.

Çoklu iş parçacığı kullanımı

Uyarı

Azure Media Services v3 VM'leri iş parçacığı güvenli değildir. Çok iş parçacıklı bir uygulamayla çalışırken iş parçacığı başına yeni bir AzureMediaServicesClient nesnesi oluşturabilirsiniz.

Sonraki adımlar