Tutorial: Transmitir em fluxo em direto com os Serviços de Multimédia com o .NET 7.0

Logótipo dos Serviços de Multimédia v3


Aviso

Os Serviços de Multimédia do Azure serão descontinuados a 30 de junho de 2024. Para obter mais informações, veja o Guia de Extinção do AMS.

Nos Serviços de Multimédia do Azure, os eventos em direto são responsáveis pelo processamento de conteúdos de transmissão em fluxo em direto. Um evento em direto fornece um ponto final de entrada (URL de ingestão) que, em seguida, fornece a um codificador em direto. O evento em direto recebe fluxos de entrada do codificador em direto através dos protocolos RTMP/S ou Smooth Streaming e disponibiliza-os para transmissão em fluxo através de um ou mais pontos finais de transmissão em fluxo. Os eventos em direto também fornecem um ponto final de pré-visualização (URL de pré-visualização) que utiliza para pré-visualizar e validar a sua transmissão antes de continuar a processar e entregar.

Este tutorial mostra como utilizar o .NET 7.0 para criar um evento em direto pass-through . Os eventos em direto pass-through são úteis quando tem um codificador capaz de codificar com velocidade de transmissão múltipla e alinhada com GOP no local. Pode ser uma forma de reduzir os custos da cloud. Se quiser reduzir a largura de banda e enviar uma única transmissão em fluxo de velocidade de transmissão para a cloud para codificação com velocidade de transmissão múltipla, pode utilizar um evento em direto de transcodificação com as predefinições de codificação 720P ou 1080P.

Neste tutorial, vai:

  • Transfira um projeto de exemplo.
  • Examine o código que executa a transmissão em fluxo em direto.
  • Veja o evento com o Leitor de Multimédia do Azure no site de demonstração do Media Player.
  • Configure o Event Grid para monitorizar o evento em direto.
  • Limpe os recursos.

Pré-requisitos

Precisa dos seguintes itens para concluir o tutorial:

Também precisa destes itens para software de transmissão em fluxo em direto:

  • Uma câmara ou um dispositivo (como um portátil) que é utilizado para difundir um evento.
  • Um codificador de software no local que codifica a transmissão da câmara e envia-o para o serviço de transmissão em fluxo em direto dos Serviços de Multimédia através do protocolo RTMP/S (Real-Time Messaging Protocol). Para obter mais informações, veja Codificadores em direto no local recomendados. O fluxo tem de estar no formato RTMP/S ou Transmissão em Fluxo Uniforme. Este exemplo pressupõe que irá utilizar o Open Broadcaster Software (OBS) Studio para difundir RTMP/S para o ponto final de ingestão. Instale o OBS Studio.
  • Em alternativa, pode experimentar o Início Rápido do OBS para testar todo o processo com o portal do Azure primeiro.

Para monitorizar o evento em direto com o Event Grid e os Hubs de Eventos, pode: 1. Siga os passos em Criar e monitorizar eventos dos Serviços de Multimédia com o Event Grid com o portal do Azure ou, 1. Siga os passos perto do final deste tutorial na secção Monitorizar Eventos em Direto com o Event Grid e os Hubs de Eventos deste artigo.

Transferir e configurar o exemplo

Clone o repositório do GitHub que contém o exemplo .NET de transmissão em fluxo em direto para o seu computador com o seguinte comando:

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

O exemplo de transmissão em fluxo em direto está na pasta Live/LiveEventWithDVR .

Abra appsettings.json no projeto transferido. Substitua os valores pelo nome da conta, o ID da subscrição e o nome do grupo de recursos.

Importante

Este exemplo utiliza um sufixo exclusivo para cada recurso. Se cancelar a depuração ou terminar a aplicação sem a executar, acabará com vários eventos em direto na sua conta. Certifique-se de que para os eventos em direto em execução. Caso contrário, ser-lhe-á faturado!

Começar a utilizar as APIs dos Serviços de Multimédia com o SDK .NET

Program.cs cria uma referência ao recurso da conta dos Serviços de Multimédia com as opções de appsettings.json:

var mediaServicesResourceId = MediaServicesAccountResource.CreateResourceIdentifier(
    subscriptionId: options.AZURE_SUBSCRIPTION_ID.ToString(),
    resourceGroupName: options.AZURE_RESOURCE_GROUP,
    accountName: options.AZURE_MEDIA_SERVICES_ACCOUNT_NAME);
var credential = new DefaultAzureCredential(includeInteractiveCredentials: true);
var armClient = new ArmClient(credential);
var mediaServicesAccount = armClient.GetMediaServicesAccountResource(mediaServicesResourceId);

Criar um evento em direto

Esta secção mostra como criar um tipo pass-through de evento em direto (LiveEventEncodingType definido como Nenhum). Para obter informações sobre os tipos disponíveis, veja Tipos de eventos em direto. Se quiser reduzir a largura de banda de ingestão geral ou não tiver um transcodificador de velocidade de transmissão múltipla no local, pode utilizar um evento de transcodificação em direto para codificação na cloud de velocidade de transmissão adaptável de 720p ou 1080p.

Poderá querer especificar os seguintes itens quando estiver a criar o evento em direto:

  • O protocolo de ingestão do evento em direto. Atualmente, os protocolos RTMPS e Smooth Streaming são suportados. Não pode alterar a opção de protocolo enquanto o evento em direto estiver em execução. Se precisar de protocolos diferentes, crie um evento em direto separado para cada protocolo de transmissão em fluxo.

  • Restrições de IP na ingestão e pré-visualização. Pode definir os endereços IP que têm permissão para ingerir um vídeo neste evento em direto. Os endereços IP permitidos podem ser especificados como uma destas opções:

    • Um único endereço IP (por exemplo, 10.0.0.1 ou 2001:db8::1)

    • Um intervalo de IP que utiliza um endereço IP e uma máscara de sub-rede cidr (Classless Inter-Domain Routing) (por exemplo, 10.0.0.1/22 ou 2001:db8::/48)

    • Um intervalo de IP que utiliza um endereço IP e uma máscara de sub-rede decimal pontilhada (por exemplo, 10.0.0.1 255.255.252.0)

      Se não forem especificados endereços IP e não existir uma definição de regra, não será permitido nenhum endereço IP. Para permitir qualquer endereço IP, crie uma regra e defina 0.0.0.0/0 e ::/0. Os endereços IP têm de estar num dos seguintes formatos: endereços IPv4 ou IPv6 com quatro números ou um intervalo de endereços CIDR. Para obter mais informações, veja Restringir o acesso à licença DRM e à entrega de chaves AES com listas de permissões de IP.

  • Inicie automaticamente um evento à medida que o cria. Quando o início automático estiver definido como verdadeiro, o evento em direto será iniciado após a criação. Isto significa que a faturação começa assim que o evento em direto começa a ser executado. Tem de chamar Stop explicitamente o recurso do evento em direto para parar a faturação adicional. Para obter mais informações, veja Estados e faturação de eventos em direto.

    Os modos de espera estão disponíveis para iniciar o evento em direto num estado "alocado" de baixo custo que torna mais rápido passar para um estado de execução. É útil para situações como piscinas quentes que precisam de distribuir canais rapidamente aos transmissores.

  • Um nome de anfitrião estático e um GUID exclusivo. Para que um URL de ingestão seja preditivo e fácil de manter num codificador em direto baseado em hardware, defina a useStaticHostname propriedade como verdadeira. Para obter informações detalhadas, veja URLs de ingestão de eventos em direto.

    var liveEvent = await mediaServicesAccount.GetMediaLiveEvents().CreateOrUpdateAsync(
        WaitUntil.Completed,
        liveEventName,
        new MediaLiveEventData(mediaServicesAccount.Get().Value.Data.Location)
        {
            Description = "Sample Live Event from the .NET SDK sample",
            UseStaticHostname = true,
            // 1) Set up the input settings for the Live event...
            Input = new LiveEventInput(streamingProtocol: LiveEventInputProtocol.Rtmp)
            {
                StreamingProtocol = LiveEventInputProtocol.Rtmp,
                AccessToken = "acf7b6ef-8a37-425f-b8fc-51c2d6a5a86a", // used to make the ingest URL unique
                KeyFrameIntervalDuration = TimeSpan.FromSeconds(2),
                IPAllowedIPs =
                {
                    new IPRange
                    {
                        Name = "AllowAllIpV4Addresses",
                        Address = IPAddress.Parse("0.0.0.0"),
                        SubnetPrefixLength = 0
                    },
                    new IPRange
                    {
                        Name = "AllowAllIpV6Addresses",
                        Address = IPAddress.Parse("0::"),
                        SubnetPrefixLength = 0
                    }
                }
            },
            // 2) Set the live event to use pass-through or cloud encoding modes...
            Encoding = new LiveEventEncoding()
            {
                EncodingType = LiveEventEncodingType.PassthroughBasic
            },
            // 3) Set up the Preview endpoint for monitoring
            Preview = new LiveEventPreview
            {
                IPAllowedIPs =
                {
                    new IPRange()
                    {
                        Name = "AllowAllIpV4Addresses",
                        Address = IPAddress.Parse("0.0.0.0"),
                        SubnetPrefixLength = 0
                    },
                    new IPRange()
                    {
                        Name = "AllowAllIpV6Addresses",
                        Address = IPAddress.Parse("0::"),
                        SubnetPrefixLength = 0
                    }
                }
            },
            // 4) Set up more advanced options on the live event. Low Latency is the most common one. Set
            //    this to Default or Low Latency. When using Low Latency mode, you must configure the Azure
            //    Media Player to use the quick start heuristic profile or you won't notice the change. In
            //    the AMP player client side JS options, set -  heuristicProfile: "Low Latency Heuristic
            //    Profile". To use low latency optimally, you should tune your encoder settings down to 1
            //    second GOP size instead of 2 seconds.
            StreamOptions =
            {
                StreamOptionsFlag.LowLatency
            },
            // 5) Optionally enable live transcriptions if desired. This is only supported on
            //    PassthroughStandard, and the transcoding live event types. It is not supported on Basic
            //    pass-through type.
            // WARNING: This is extra cost, so please check pricing before enabling.
            //Transcriptions =
            //{
            //    new LiveEventTranscription
            //    {
            //        // The value should be in BCP-47 format (e.g: 'en-US'). See https://go.microsoft.com/fwlink/?linkid=2133742
            //        Language = "en-us",
            //        TrackName = "English" // set the name you want to appear in the output manifest
            //    }
            //}
        },
        autoStart: false);
    

Obter URLs de inserção

Depois de o Evento em Direto ser criado, pode obter URLs de ingestão que irá fornecer ao codificador em direto. O codificador utiliza estes URLs para exibir uma transmissão um fluxo direto.

// Get the RTMP ingest URL. The endpoints is a collection of RTMP primary and secondary,
// and RTMPS primary and secondary URLs.
Console.WriteLine($"The RTMP ingest URL to enter into OBS Studio is:");
Console.WriteLine(liveEvent.Data.Input.Endpoints.First(x => x.Uri.Scheme == "rtmps").Uri);
Console.WriteLine("Make sure to enter a Stream Key into the OBS Studio settings. It can be");
Console.WriteLine("any value or you can repeat the accessToken used in the ingest URL path.");
Console.WriteLine();

Obter o URL de pré-visualização

Utilize previewEndpoint para pré-visualizar e verificar se a entrada do codificador está a ser recebida.

Importante

Certifique-se de que o vídeo está a fluir para o URL de pré-visualização antes de continuar.

// Use the previewEndpoint to preview and verify that the input from the encoder is actually
// being received The preview endpoint URL also support the addition of various format strings
// for HLS (format=m3u8-cmaf) and DASH (format=mpd-time-cmaf) for example. The default manifest
// is Smooth.
string previewEndpoint = liveEvent.Data.Preview.Endpoints.First().Uri.ToString();
Console.WriteLine($"The preview URL is:");
Console.WriteLine(previewEndpoint);
Console.WriteLine();
Console.WriteLine($"Open the live preview in your browser and use the Azure Media Player to monitor the preview playback:");
Console.WriteLine($"https://ampdemo.azureedge.net/?url={HttpUtility.UrlEncode(previewEndpoint)}&heuristicprofile=lowlatency");
Console.WriteLine();
Console.WriteLine("Start the live stream now, sending the input to the ingest URL and verify");
Console.WriteLine("that it is arriving with the preview URL.");
Console.WriteLine("IMPORTANT: Make sure that the video is flowing to the Preview URL before continuing!");
Console.WriteLine("Press enter to continue...");
Console.ReadLine();

Criar e gerir eventos em direto e saídas em direto

Depois de a transmissão em fluxo em direto do codificador no local ser transmitida em fluxo para o evento em direto, pode iniciar o evento em direto ao criar um recurso, uma saída em direto e um localizador de transmissão em fluxo. O fluxo é arquivado e está disponível para visualizadores através do ponto final de transmissão em fluxo.

A próxima secção irá explicar a criação do recurso e a saída em direto.

Criar um recurso

Crie um recurso para a saída em direto a utilizar.

// Create an Asset for the Live Output to use. Think of this as the "tape" that will be recorded
// to. The asset entity points to a folder/container in your Azure Storage account
Console.Write($"Creating the output Asset '{assetName}'...".PadRight(60));
var asset = (await mediaServicesAccount.GetMediaAssets().CreateOrUpdateAsync(
    WaitUntil.Completed,
    assetName,
    new MediaAssetData
    {
        Description = "My video description"
    })).Value;
Console.WriteLine("Done");

Criar uma saída em direto

As saídas em direto começam quando são criadas e param quando são eliminadas. Quando elimina a saída em direto, não está a eliminar o elemento de saída ou o conteúdo no recurso. O elemento com a gravação está disponível para transmissão em fluxo a pedido, desde que exista e exista um localizador de transmissão em fluxo associado ao mesmo.

// Create the Live Output - think of this as the "tape recorder for the live event". Live
// outputs are optional, but are required if you want to archive the event to storage, use the
// asset for on-demand playback later, or if you want to enable cloud DVR time-shifting. We will
// use the asset created above for the "tape" to record to.
Console.Write($"Creating Live Output...".PadRight(60));
var liveOutput = (await liveEvent.GetMediaLiveOutputs().CreateOrUpdateAsync(
    WaitUntil.Completed,
    liveOutputName,
    new MediaLiveOutputData
    {
        AssetName = asset.Data.Name,
        // The HLS and DASH manifest file name. This is recommended to
        // set if you want a deterministic manifest path up front.
        // archive window can be set from 3 minutes to 25 hours.
        // Content that falls outside of ArchiveWindowLength is
        // continuously discarded from storage and is non-recoverable.
        // For a full event archive, set to the maximum, 25 hours.
        ManifestName = manifestName,
        ArchiveWindowLength = TimeSpan.FromHours(1)
    })).Value;
Console.WriteLine("Done");

Criar um localizador de transmissão

Nota

Quando a sua conta dos Serviços de Multimédia é criada, é adicionado um ponto final de transmissão em fluxo predefinido à sua conta no estado parado. Para começar a transmitir em fluxo os seus conteúdos e tirar partido do empacotamento dinâmico e da encriptação dinâmica, o ponto final de transmissão em fluxo a partir do qual pretende transmitir conteúdo tem de estar no estado de execução.

Publica um recurso ao criar um localizador de transmissão em fluxo. O evento em direto (até ao comprimento da janela do DVR) é visualizável até à expiração ou eliminação do localizador de transmissão em fluxo, o que ocorrer primeiro. É assim que disponibiliza o vídeo para que a sua audiência de visualização veja em direto e a pedido. O mesmo URL pode ser utilizado para watch o evento em direto, a janela do DVR ou o recurso a pedido quando o evento em direto estiver concluído e a saída em direto for eliminada.

var streamingLocator = (await mediaServicesAccount.GetStreamingLocators().CreateOrUpdateAsync(
    WaitUntil.Completed,
    streamingLocatorName,
    new StreamingLocatorData
    {
        AssetName = asset.Data.Name,
        StreamingPolicyName = "Predefined_ClearStreamingOnly",
        Filters =
        {
            filter.Data.Name
        }
    })).Value;

Ver o evento

Execute o código. Utilize os URLs de transmissão em fluxo de saída para watch o seu evento em direto. Copie o URL do localizador de transmissão em fluxo. Pode utilizar um leitor de multimédia à sua escolha. Pode utilizar o site de demonstração do Media Player para testar a sua transmissão em fluxo. Introduza o URL no campo URL e selecione Atualizar leitor.

Monitorizar Eventos em Direto com o Event Grid e os Hubs de Eventos

O projeto de exemplo pode utilizar o Event Grid e os Hubs de Eventos para monitorizar o Evento em Direto. Pode configurar e utilizar o Event Grid com o seguinte

Para ativar a monitorização:

  1. Utilizar o portal do Azure para criar o Espaço de Nomes dos Hubs de Eventos e um Hub de Eventos
    1. Procure "Hubs de Eventos" com a caixa de texto na parte superior do portal do Azure.
    2. Selecione Hub de Eventos na lista e, em seguida, siga as instruções para criar um Espaço de Nomes dos Hubs de Eventos.
    3. Navegue para o recurso Espaço de Nomes dos Hubs de Eventos.
    4. Selecione Hubs de Eventos na secção Entidades do menu do portal.
    5. Crie um Hub de Eventos no espaço de nomes dos Hubs de Eventos.
    6. Navegue para o recurso dos Hubs de Eventos.
    7. Selecione Controlo de acesso e, em seguida, Adicionaratribuição de função.
    8. Selecione o Hubs de Eventos do Azure Recetor de Dados e, em seguida, conceda acesso a si próprio.
    9. Selecione Controlo de acesso e, em seguida, Adicionaratribuição de função.
    10. Selecione o Hubs de Eventos do Azure Remetente de Dados e, em seguida, conceda-o à Identidade Gerida criada para a conta dos Serviços de Multimédia.
  2. Utilize o portal do Azure para criar uma conta de Armazenamento do Azure.
    1. Depois de criar a conta de armazenamento, navegue para o recurso da Conta de Armazenamento.
    2. Selecione Controlo de acesso e, em seguida, Adicionaratribuição de função.
    3. Selecione o Contribuidor de Dados do Blob de Armazenamento e, em seguida, conceda este acesso a si próprio.
  3. Criar uma Subscrição de Eventos
    1. Navegue para a conta dos Serviços de Multimédia.
    2. Selecione Eventos no menu do portal.
    3. Selecione + Subscrição de Eventos.
    4. Introduza um nome de subscrição e um nome de artigo do sistema.
    5. Defina o Tipo de Ponto Final como Event Hub.
    6. Defina os Hubs de Eventos para os Hubs de Eventos criados anteriormente e defina a Identidade Gerida para a identidade à qual foi concedido anteriormente o acesso de Remetente aos Hubs de Eventos
  4. Atualize o appsetttings.json ficheiro.
    1. Defina EVENT_HUB_NAMESPACE para o nome completo do espaço de nomes. Deve ser semelhante a myeventhub.servicebus.windows.net.
    2. Defina EVENT_HUB_NAME.
    3. Defina AZURE_STORAGE_ACCOUNT_NAME.

Execute o exemplo novamente. Com a integração dos Hubs de Eventos ativada, o exemplo regista eventos quando o codificador se liga e desliga do Evento em Direto. São também registados vários outros eventos.

Depois de executar o exemplo, elimine os Hubs de Eventos e a conta de armazenamento, se já não forem necessários.

Limpar os recursos na conta dos Serviços de Multimédia

Se tiver concluído eventos de transmissão em fluxo e quiser limpar os recursos aprovisionados anteriormente, utilize o seguinte procedimento:

  1. Pare a transmissão em fluxo do codificador.
  2. Pare o evento em direto. Depois de o evento em direto ser interrompido, não incorre em custos. Quando precisar de o iniciar novamente, pode utilizar o mesmo URL de ingestão para não ter de reconfigurar o codificador.
  3. Pare o ponto final de transmissão em fluxo, a menos que pretenda continuar a fornecer o arquivo do seu evento em direto como uma transmissão a pedido. Se o evento em direto estiver num estado parado, não irá incorrer em custos.
if (liveOutput != null)
{
    Console.Write("Deleting the Live Output...".PadRight(60));
    await liveOutput.DeleteAsync(WaitUntil.Completed);
    Console.WriteLine("Done");
}

if (liveEvent?.Data.ResourceState == LiveEventResourceState.Running)
{
    Console.Write("Stopping the Live Event...".PadRight(60));
    await liveEvent.StopAsync(WaitUntil.Completed, new LiveEventActionContent() { RemoveOutputsOnStop = true });
    Console.WriteLine("Done");
}

if (liveEvent != null)
{
    Console.Write("Deleting the Live Event...".PadRight(60));
    await liveEvent.DeleteAsync(WaitUntil.Completed);
    Console.WriteLine("Done");
}

if (streamingLocator != null)
{
    Console.Write("Deleting the Streaming Locator...".PadRight(60));
    await streamingLocator.DeleteAsync(WaitUntil.Completed);
    Console.WriteLine("Done");
}

if (asset != null)
{
    Console.Write("Deleting the Asset...".PadRight(60));
    await asset.DeleteAsync(WaitUntil.Completed);
    Console.WriteLine("Done");
}

Limpar os recursos restantes

Se já não precisar dos Serviços de Multimédia e das contas de armazenamento que criou para este tutorial, elimine o grupo de recursos que criou anteriormente.

Execute o seguinte comando da CLI:


az group delete --name amsResourceGroup

Obter ajuda e suporte

Pode contactar os Serviços de Multimédia com perguntas ou seguir as nossas atualizações através de um dos seguintes métodos: