Media Services SDK を使用したライブ ストリーミングを行う


このポストは、11 月 4 日に投稿された Getting Started with Live Streaming using the Media Services SDK の翻訳です。

先日、Azure Media Services でライブ ストリーミング サービスのパブリック プレビューの提供が開始されました。この記事ではチュートリアルとして、Azure Media Services .NET SDK を使用したライブ ストリーミングをセットアップする方法について説明します。使用するソース コードの完全版は、GitHub (英語) からダウンロードできます。なお、コードを作成しないお客様は、「Azure 管理ポータルを使用したライブ ストリーミングの開始」をご覧ください。

 

1. コンソール アプリケーションを .NET 4.0 で作成します。NuGet で "windowsazure.mediaservices" というキーワードで検索すると、Media Services .NET SDK (英語) を入手できます。

 

2. お客様の app.config ファイルに次のコードを追加します。アカウント名とアカウント キーは Azure 管理ポータルでご確認ください。

  <appSettings>
    <add key="MediaServicesAccountName" value="Account_NAME" />
    <add key="MediaServicesAccountKey" value="Account_KEY" />
  </appSettings>

 

3. program.cs の CloudMediaContext を使用して Azure Media Services に接続します。

private const string StreamingEndpointName = "streamingendpoint001";
private const string ChannelName = "channel001";
private const string AssetlName = "asset001";
private const string ProgramlName = "program001";

// App.config ファイルから値を読み込む
private static readonly string _mediaServicesAccountName =
ConfigurationManager.AppSettings["MediaServicesAccountName"];

private static readonly string _mediaServicesAccountKey =
ConfigurationManager.AppSettings["MediaServicesAccountKey"];

// サービスのコンテキストで使用するフィールド
private static CloudMediaContext _context = null;
private static MediaServicesCredentials _cachedCredentials = null;

static void Main(string[] args)
{
// Media Services の認証情報を静的クラス変数として作成しキャッシュする
    _cachedCredentials = new MediaServicesCredentials(
    _mediaServicesAccountName,_mediaServicesAccountKey);
 // キャッシュに保存された認証情報から CloudMediaContext を作成する
    _context = new CloudMediaContext(_cachedCredentials);
}

 

4. ライブ チャネルを作成して、そのチャネルを開始します。チャネルとは Azure Media Services の基本的なエンティティで、ライブ ストリームの取り込みに使用します。各チャネルには取り込み URL およびプレビュー URL があり、1 つまたは複数のプログラムをこれに関連付けることができます。チャネルの開始には通常 2 分ほどかかりますが、場合によっては 20 分ほどかかることもあります。チャネルは、すぐに開始する必要はありません。通常は事前にチャネルをセットアップしますが、ライブ イベントの開始直前にセットアップしてもかまいません。

public static IChannel CreateAndStartChannel()
{
    IChannel channel = _context.Channels.Create(
        new ChannelCreationOptions
        {
            Name = ChannelName,
            Input = CreateChannelInput(),
            Preview = CreateChannelPreview(),
            Output = CreateChannelOutput()
        });

    channel.Start();
    Console.WriteLine("Starting Channel " + ChannelName);
    Console.WriteLine("Channel's ingest URL " + channel.Input.Endpoints.FirstOrDefault().Url.ToString());
    Console.WriteLine("Channel's preview URL " + channel.Preview.Endpoints.FirstOrDefault().Url.ToString());

    return channel;
}

 

5. 各メソッドの実装は手順 4 で行っていますので、ここでは、チャネルの作成方法を説明します。チャネルを作成するときに、Fragmented MP4 (Smooth Streaming) と RTMP のどちらの取り込みプロトコルをサポートするかを選択できます。アクセスを制御するにあたって、取り込みポイントへのアクセスを許可する IP アドレスの許可リストを定義する必要があります。このとき、特定のコンピューターのみを指定することも、一定範囲の IP アドレスを許可することもできます。すべての IP アドレスを許可する場合は、“0.0.0.0/0” に設定します。

private static ChannelInput CreateChannelInput()
{
    return new ChannelInput
    {
        StreamingProtocol = StreamingProtocol.FragmentedMP4,
        AccessControl = new ChannelAccessControl
        {
            IPAllowList = new List<IPRange>
            {
                new IPRange
                {
                    Name = "TestChannelInput001",
                    Address = IPAddress.Parse("0.0.0.0"),
                    SubnetPrefixLength = 0
                }
            }
        }
    };
}

 

6. プレビューおよび出力用のチャネルを作成します。

private static ChannelPreview CreateChannelPreview()
{
    return new ChannelPreview
    {
        AccessControl = new ChannelAccessControl
        {
            IPAllowList = new List<IPRange>
            {
                new IPRange
                {
                    Name = "TestChannelPreview001",
                    Address = IPAddress.Parse("0.0.0.0"),
                    SubnetPrefixLength = 0
                }
            }
        }
    };
}

private static ChannelOutput CreateChannelOutput()
{
    return new ChannelOutput
    {
        Hls = new ChannelOutputHls { FragmentsPerSegment = 1 }
    };
}

 

7. チャネルを作成し、取り込み URL とプレビュー URL を出力するには、下記のコードを Main メソッドに追加します。取り込み URL は、ライブ エンコーダーに指定するプッシュの出力先です (Wirecast などのエンコーダーをセットアップする場合は、ライブ エンコーダーの構成に関するブログ記事をご確認ください)。ライブ エンコーダーの構成を完了し起動したら、プレビュー URL でストリームを視聴して、ストリームが正常に取り込まれることを確認します。

IChannel channel = CreateAndStartChannel();

// ライブ エンコーダーに以下の入力エンドポイントを設定する
Console.WriteLine("Channel's ingest URL " + channel.Input.Endpoints.FirstOrDefault().Url.ToString());

// プレビュー エンドポイントを使用してプレビューを行い、
// エンコーダーからの入力が実際にチャネルに届いていることを確認する
Console.WriteLine("Channel's preview URL " + channel.Preview.Endpoints.FirstOrDefault().Url.ToString());

 

8. ストリーミングを保持し視聴者が視聴できるようにするには、プログラムとストリーミング エンドポイントを作成する必要があります。次のコードを Main メソッドに追加します。

// ストリームをプレビューし、チャネルに正しく流れていることを確認したら、
// アセット、プログラム、およびストリーミング ロケーターを作成してイベントを作成する
IProgram program = CreateAndStartProgram(channel);
ILocator locator = CreateLocatorForAsset(program.Asset, program.ArchiveWindowLength);
IStreamingEndpoint streamingEndpoint = CreateAndStartStreamingEndpoint();
GetLocatorsInAllStreamingEndpoints(program.Asset);

Console.ReadLine();

 

9. プログラムでは、ライブ ストリームの公開および保存を制御できます。プログラムは最大で同時に 3 本まで実行できるため、必要に応じてストリームの異なる部分を公開したりアーカイブを作成したりできます。

記録されたコンテンツをプログラムで保持する期間は、ArchiveWindowLength プロパティで指定できます。この値の最小値は 5 分、最大値は 25 時間です。この値は、現在のライブ放送の位置から戻ることができるシーク位置の時間範囲も表しています。この値で指定した時間よりも長いプログラムも実行できますが、その場合、コンテンツのその範囲を超えた部分は逐次破棄されます。

public static IProgram CreateAndStartProgram(IChannel channel)
{
    IAsset asset = _context.Assets.Create(AssetlName, AssetCreationOptions.None);

// チャネルにプログラムを作成する。相互に重複するかまたは連続するかたちで複数のプログラムを作成することが可能。
// ただし、各プログラムの名前は Media Services アカウント内で一意となる必要がある。
    IProgram program = channel.Programs.Create(ProgramlName, TimeSpan.FromHours(3), asset.Id);
    program.Start();

    Console.WriteLine("Starting Program " + Program.ProgramlName);
    return program;
}

 

10. 次に、ストリームへのアクセスに使用するストリーミング ロケーターを作成する必要があります。ストリーミング ロケーターは、プログラムに関連付けられたアセットを、ストリーミング エンドポイントを通じてストリーミングできるようにするものです。ストリーミング ロケーターを作成する際には、アセットへのストリーミング アクセスに適用するアクセス ポリシーを設定できます。

public static ILocator CreateLocatorForAsset(IAsset asset, TimeSpan ArchiveWindowLength)
{
    var locator = _context.Locators.CreateLocator
        (
            LocatorType.OnDemandOrigin,
            asset,
            _context.AccessPolicies.Create
            (
                "Live Stream Policy",
                ArchiveWindowLength,
                AccessPermissions.Read
            )
        );

    return locator;
}

 

11. 最後に、ストリーミング エンドポイントを作成し、ロケーターの URL を取得する必要があります。1 つの Media Services アカウントに対し、複数のストリーミング エンドポイントを設定できます。複数のストリーミング エンドポイントを作成すると、それぞれで構成 (セキュリティ設定、クロス サイトのアクセス ポリシー、スケール ユニットなど) を変えたり、ビデオ オン デマンド (VOD) とライブ ストリーミングを分離させたりすることができます。

public static IStreamingEndpoint CreateAndStartStreamingEndpoint()
{
    var options = new StreamingEndpointCreationOptions
    {
        Name = StreamingEndpointName,
        ScaleUnits = 1,
        AccessControl = GetAccessControl(),
        CacheControl = GetCacheControl()
    };

    IStreamingEndpoint streamingEndpoint = _context.StreamingEndpoints.Create(options);
    streamingEndpoint.Start();

    return streamingEndpoint;
}

private static StreamingEndpointAccessControl GetAccessControl()
{
    return new StreamingEndpointAccessControl
    {
        IPAllowList = new List<IPRange>
        {
            new IPRange
            {
                Name = "Allow all",
                Address = IPAddress.Parse("0.0.0.0"),
                SubnetPrefixLength = 0
            }
        },

        AkamaiSignatureHeaderAuthenticationKeyList = new List<AkamaiSignatureHeaderAuthenticationKey>
        {
            new AkamaiSignatureHeaderAuthenticationKey
            {
                Identifier = "My key",
                Expiration = DateTime.UtcNow + TimeSpan.FromDays(365),
                Base64Key = Convert.ToBase64String(GenerateRandomBytes(16))
            }
        }
    };
}

private static byte[] GenerateRandomBytes(int length)
{
    var bytes = new byte[length];
    using (var rng = new RNGCryptoServiceProvider())
    {
        rng.GetBytes(bytes);
    }

    return bytes;
}

private static StreamingEndpointCacheControl GetCacheControl()
{
    return new StreamingEndpointCacheControl
    {
        MaxAge = TimeSpan.FromSeconds(1000)
    };
}

public static void GetLocatorsInAllStreamingEndpoints(IAsset asset)
{
    var locators = asset.Locators.Where(l => l.Type == LocatorType.OnDemandOrigin);
    var ismFile = asset.AssetFiles.AsEnumerable().FirstOrDefault(a => a.Name.EndsWith(".ism"));
    var template = new UriTemplate("{contentAccessComponent}/{ismFileName}/manifest");
    var urls = locators.SelectMany(l =>
                _context
                    .StreamingEndpoints
                    .AsEnumerable()
                    .Where(se => se.State == StreamingEndpointState.Running)
                    .Select(
                        se =>
                            template.BindByPosition(new Uri("http://" + se.HostName),
                            l.ContentAccessComponent,
                                ismFile.Name)))
                .ToArray();

    foreach(var url in urls){
        Console.WriteLine(url);
    }

}

 

12. これで、プログラムを実行しライブ ストリームを放送する準備ができました。この記事で使用するソース コードの完全版は、GitHub (英語) からダウンロードできます。また、上記のすべての設定は、Azure 管理ポータルからも確認できます。

Comments (0)

Skip to main content