教學課程:使用 .NET 7.0 透過媒體服務即時串流

媒體服務標誌 v3


警告

Azure 媒體服務將於 2024 年 6 月 30 日淘汰。 如需詳細資訊,請參閱 AMS淘汰指南

在 Azure 媒體服務中,即時事件會負責處理即時串流內容。 即時事件會提供輸入端點 (內嵌 URL),接著您再提供給即時編碼器。 即時事件會使用 RTMP/S 或 Smooth Streaming 通訊協定從即時編碼器接收輸入串流,並使其可供透過一或多個 串流端點進行串流處理。 即時事件也會提供預覽端點 (預覽 URL),您可在進一步處理和傳遞之前先用來預覽及驗證您的資料流。

本教學課程說明如何使用 .NET 7.0 建立 傳遞 實時活動。 當您有能夠多比特率、GOP 對齊內部部署編碼的編碼器時,傳遞即時活動很有用。 它可以降低雲端成本。 如果您想要減少頻寬,並將單一比特率串流傳送至雲端以進行多比特率編碼,您可以使用具有 720P 或 1080P 編碼預設值的轉碼即時事件。

在本教學課程中,您將:

  • 下載範例專案。
  • 檢查執行即時串流的程式碼。
  • 在媒體播放器示範網站上使用 Azure 媒體播放器觀看事件。
  • 設定事件方格以監視即時活動。
  • 清除資源。

必要條件

您需要下列項目才能完成教學課程:

您也需要這些項目來進行即時串流軟體:

  • 用來廣播事件的相機或裝置 (例如筆記型電腦)。
  • 內部部署軟體編碼器,可編碼相機串流,並透過 Real-Time Messaging Protocol (RTMP/S) 將它傳送至媒體服務即時串流服務。 如需詳細資訊,請參閱建議的內部部署即時編碼器。 數據流必須是 RTMP/S 或 Smooth Streaming 格式。 此範例假設您將使用 Open Broadcaster Software (OBS) Studio 將 RTMP/S 廣播至內嵌端點。 安裝 OBS Studio
  • 或者,您可以嘗試 OBS 快速入門,先使用 Azure 入口網站 測試整個程式。

For monitoring the live event using Event Grid and Event Hubs, you can: 1. Follow the steps in Create and monitor Media Services events with Event Grid using the Azure portal or, 1. Follow the steps near the end of this tutorial in the Monitoring Live Events using Event Grid and Event Hubs section of this article.

秘訣

請先檢閱使用媒體服務 v3 進行即時串流,再繼續操作。

下載並設定範例

使用下列命令,將包含即時串流 .NET 範例的 GitHub 存放庫複製到您的機器:

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

即時串流範例位於 Live/LiveEventWithDVR 資料夾中。

在下載的項目中開啟 appsettings.json 。 將值取代為帳戶名稱、訂用帳戶標識碼和資源組名。

重要事項

此範例會對每個資源使用唯一尾碼。 如果您取消偵錯,或在應用程式執行完成之前加以終止,您的帳戶將會出現多個即時事件。 請務必停止執行中的即時事件。 否則將會產生相關費用

開始使用媒體服務 API 搭配 .NET SDK

Program.cs會使用 中的 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);

建立即時事件

本節說明如何建立即時活動的 傳遞 類型, (LiveEventEncodingType 設定為 None) 。 如需可用類型的相關資訊,請參閱即時事件類型。 如果您想要減少整體擷取頻寬,或沒有內部部署多比特率轉碼器,您可以使用 720p 或 1080p 自適性比特率雲端編碼的實時轉碼事件。

建立即時事件時,您可能會想要指定下列項目:

  • 即時事件的內嵌通訊協定。 目前支援 RTMPS 和 Smooth Streaming 通訊協定。 當即時活動正在執行時,您無法變更通訊協定選項。 如果您需要不同的通訊協定,則應為每個串流通訊協定建立個別的即時事件。

  • 內嵌和預覽的 IP 限制。 您可以定義獲允許可將視訊內嵌到此即時活動的 IP 位址。 允許的 IP 位址可以指定為下列其中一個選項:

    • 單一IP位址 (例如10.0.0.0.1或2001:db8::1)

    • IP 範圍,使用IP位址和無類別 Inter-Domain 路由 (CIDR) 子網掩碼 (例如 10.0.0.1/22 或 2001:db8::/48)

    • 使用IP位址和虛線十進位子網掩碼的IP範圍 (,例如10.0.0.0.1 255.255.252.0)

      如果未指定 IP 位址而且也未定義規則,則任何 IP 位址都不允許。 若要允許任何IP位址,請建立規則並設定0.0.0.0.0/0和::/0。 IP 位址必須採用下列其中一種格式:具有四個數位或 CIDR 位址範圍的 IPv4 或 IPv6 位址。 如需詳細資訊,請參閱 使用IP允許清單限制對DRM授權和AES金鑰傳遞的存取

  • 當您建立事件時自動在其上啟動。 當自動啟動設定為 true 時,即時活動會在建立之後開始。 這意味著即時事件只要開始執行,就會立即開始計費。 您必須在即時事件資源上明確呼叫 Stop,才能終止進一步計費。 如需詳細資訊,請參閱即時活動狀態和計費

    待命模式可讓您以較低成本的「配置」狀態啟動即時事件,使其更快進入執行中狀態。 這適用於需要快速將通道送出給串流器的情況。

  • 靜態主機名稱和唯一 GUID。 若要讓內嵌 URL 成為預測性且更容易在硬體式即時編碼器中維護,請將 useStaticHostname 屬性設定為 true。 如需詳細資訊,請參閱即時事件內嵌 URL

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

取得內嵌 URL

建立即時事件之後,您即可取得將提供給即時編碼器的內嵌 URL。 編碼器會使用這些 URL 來輸入即時串流。

// 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();

取得預覽 URL

使用 previewEndpoint 來預覽及確認正在接收來自編碼器的輸入。

重要事項

請先確定影片流向預覽 URL,再繼續操作。

// 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();

建立及管理即時事件與即時輸出

從內部部署編碼器即時串流至即時活動之後,您可以建立資產、實時輸出和串流定位器來開始即時活動。 數據流已封存,可透過串流端點供檢視者使用。

下一節將逐步解說如何建立資產和即時輸出。

建立資產

建立供即時輸出使用的資產。

// 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");

建立即時輸出

即時輸出會在建立後隨即啟動,並在刪除後隨即停止。 當您刪除即時輸出時,您不會刪除資產中的輸出資產或內容。 只要其存在且有相關聯的串流定位器,錄製的資產就可供隨選串流使用。

// 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");

建立串流定位器

注意

建立媒體服務帳戶時,預設串流端點會新增至處於停止狀態的帳戶。 若要開始串流內容並利用動態封裝和動態加密功能,您想要串流內容的串流端點必須處於執行中狀態。

您可以建立串流定位器來發佈資產。 即時活動 (至 DVR 視窗長度,) 可檢視,直到串流定位器的到期或刪除,以先傳回。 您可以如何讓觀看對象能夠觀看即時和隨選觀看影片。 相同的 URL 可用來 watch 即時活動、DVR 視窗或即時活動完成且刪除即時輸出時的隨選資產。

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

監看事件

執行程式碼。 使用輸出串流 URL 來 watch 即時活動。 複製串流定位器 URL。 您可以使用您選擇的媒體播放器。 您可以使用 媒體播放器示範網站 來測試您的串流。 在 [URL] 字段中輸入 URL,然後選取 [更新播放機]。

使用事件方格和事件中樞監視即時事件

範例專案可以使用事件方格和事件中樞來監視即時事件。 您可以使用下列項目來設定及使用事件方格

若要啟用監視:

  1. 使用 Azure 入口網站 建立事件中樞命名空間和事件中樞
    1. 使用 Azure 入口網站 頂端的文字框搜尋「事件中樞」。
    2. 從清單中選取 [事件中樞 ],然後依照指示建立事件中樞命名空間。
    3. 流覽至事件中樞命名空間資源。
    4. 從入口網站功能表的 [實體] 區段選取 [事件中樞]。
    5. 在事件中樞命名空間中建立事件中樞。
    6. 流覽至事件中樞資源。
    7. 選取 [訪問控制 ],然後選取 [ 新增],然後選取 [ 新增角色指派]。
    8. 選取 [Azure 事件中樞 數據接收者],然後授與您自己存取權。
    9. 選取 [訪問控制 ],然後選取 [ 新增],然後選取 [ 新增角色指派]。
    10. 選取 Azure 事件中樞 數據傳送者,然後將它授與媒體服務帳戶所建立的受控識別。
  2. 使用 Azure 入口網站 來建立 Azure 記憶體帳戶。
    1. 建立記憶體帳戶之後,流覽至記憶體帳戶資源。
    2. 選取 [訪問控制 ],然後選取 [ 新增],然後選取 [ 新增角色指派]。
    3. 選取 [ 記憶體 Blob 數據參與者 ],然後將此存取權授與自己。
  3. 建立事件訂閱
    1. 流覽至媒體服務帳戶。
    2. 從入口網站功能選取 [事件 ]。
    3. 選取 [+ 事件訂用帳戶]。
    4. 輸入訂用帳戶名稱和系統發行項名稱。
    5. [端點類型] 設定為 Event Hub
    6. 將事件中樞設定為先前建立的事件中樞,並將受控識別設定為先前授與事件中樞發件者存取權的身分識別
  4. 更新 appsetttings.json 檔案。
    1. 將EVENT_HUB_NAMESPACE設定為命名空間的完整名稱。 它應該類似 myeventhub.servicebus.windows.net
    2. 設定EVENT_HUB_NAME。
    3. 設定AZURE_STORAGE_ACCOUNT_NAME。

再次執行範例。 啟用事件中樞整合后,範例會在編碼器連線並中斷與即時事件連線時記錄事件。 也會記錄各種其他事件。

執行範例之後,如果不再需要事件中樞和記憶體帳戶,請加以刪除。

清除媒體服務帳戶中的資源

如果您已完成串流事件,而想要清除先前佈建的資源,請遵循下列程序:

  1. 停止從編碼器串流。
  2. 停止即時事件。 即時事件在停止後,就不會產生任何費用。 當您需要再次啟動它時,可以使用相同的內嵌URL,因此您不需要重新設定編碼器。
  3. 除非您想要繼續提供即時活動的封存作為隨選串流,否則請停止串流端點。 如果即時事件處於已停止狀態,就不會產生任何費用。
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");
}

清除剩餘資源

如果您不再需要在本教學課程中建立的媒體服務和記憶體帳戶,請刪除您稍早建立的資源群組。

執行下列 CLI 命令:


az group delete --name amsResourceGroup

取得說明及支援

您可以連絡媒體服務並提出問題,或遵循下列其中一種方法來追蹤我們的更新: