将现有 Blob 复制到媒体服务资产
本文说明了如何使用 Azure 媒体服务 .NET SDK 扩展将 Blob 从存储帐户复制到新的 Azure 媒体服务 (AMS) 资产中。
扩展方法适用于:
- 常规资产。
- 实时存档资产(FragBlob 格式)。
- 属于不同媒体服务帐户(甚至跨不同数据中心)的源和目标资产。 但是,这样做可能会产生费用。 有关定价的详细信息,请参阅数据传输。
Note
在不使用媒体服务 API 的情况下,不应该尝试更改媒体服务生成的 blob 容器内容。
本文展示了两个代码示例:
- 将 Blob 从一个 AMS 帐户中的资产复制到另一个 AMS 帐户中的新资产。
- 将 Blob 从某个存储帐户复制到一个 AMS 帐户中的新资产。
在两个 AMS 帐户之间复制 Blob
先决条件
两个媒体服务帐户。 请参阅如何创建媒体服务帐户一文。
下载示例
用户可以执行本文中的步骤,也可以单击 此处下载包含本文所述代码的示例。
设置项目
- 按照使用 .NET 进行媒体服务开发中所述来设置开发环境。
- 将 appSettings 节添加到 .config 文件,并根据媒体服务帐户、目标存储帐户和源资产 ID 更新值。
<appSettings>
<add key="AMSSourceAADTenantDomain" value="tenant"/>
<add key="AMSSourceRESTAPIEndpoint" value="endpoint"/>
<add key="SourceAMSClientId" value="clientID"/>
<add key="SourceAMSClientSecret" value="clientSecret"/>
<add key="SourceAssetID" value="nb:cid:UUID:<id>"/>
<add key="AMSDestAADTenantDomain" value="tenant"/>
<add key="AMSDestRESTAPIEndpoint" value="endpoint"/>
<add key="DestAMSClientId" value="clientID"/>
<add key="DestAMSClientSecret" value="clientSecret"/>
<add key="DestStorageAccountName" value="name"/>
<add key="DestStorageAccountKey" value="key"/>
</appSettings>
将 Blob 从一个 AMS 帐户中的资产复制到另一个 AMS 帐户中的资产
以下代码使用单个扩展通过扩展的 IAsset.Copy 方法将源资产中的所有文件复制到目标资产。
using System;
using Microsoft.WindowsAzure.MediaServices.Client;
using System.Linq;
using System.Configuration;
using Microsoft.WindowsAzure.Storage.Auth;
namespace CopyExistingBlobsIntoAsset
{
class Program
{
static string _sourceAADTenantDomain =
ConfigurationManager.AppSettings["AMSSourceAADTenantDomain"];
static string _sourceRESTAPIEndpoint =
ConfigurationManager.AppSettings["AMSSourceRESTAPIEndpoint"];
static string _sourceClientId =
ConfigurationManager.AppSettings["SourceAMSClientId"];
static string _sourceClientSecret =
ConfigurationManager.AppSettings["SourceAMSClientSecret"];
static string _destAADTenantDomain =
ConfigurationManager.AppSettings["AMSDestAADTenantDomain"];
static string _destRESTAPIEndpoint =
ConfigurationManager.AppSettings["AMSDestRESTAPIEndpoint"];
static string _destClientId =
ConfigurationManager.AppSettings["DestAMSClientId"];
static string _destClientSecret =
ConfigurationManager.AppSettings["DestAMSClientSecret"];
static string _destStorageAccountName =
ConfigurationManager.AppSettings["DestStorageAccountName"];
static string _destStorageAccountKey =
ConfigurationManager.AppSettings["DestStorageAccountKey"];
static string _sourceAssetID =
ConfigurationManager.AppSettings["SourceAssetID"];
private static CloudMediaContext _sourceContext = null;
private static CloudMediaContext _destContext = null;
static void Main(string[] args)
{
AzureAdTokenCredentials tokenCredentials1 = new AzureAdTokenCredentials(_sourceAADTenantDomain,
new AzureAdClientSymmetricKey(_sourceClientId, _sourceClientSecret),
AzureEnvironments.AzureChinaCloudEnvironment);
AzureAdTokenCredentials tokenCredentials2 = new AzureAdTokenCredentials(_destAADTenantDomain,
new AzureAdClientSymmetricKey(_destClientId, _destClientSecret),
AzureEnvironments.AzureChinaCloudEnvironment);
var tokenProvider1 = new AzureAdTokenProvider(tokenCredentials1);
var tokenProvider2 = new AzureAdTokenProvider(tokenCredentials2);
// Create the context for your source Media Services account.
_sourceContext = new CloudMediaContext(new Uri(_sourceRESTAPIEndpoint), tokenProvider1);
// Create the context for your destination Media Services account.
_destContext = new CloudMediaContext(new Uri(_destRESTAPIEndpoint), tokenProvider2);
// Get the credentials of the default Storage account bound to your destination Media Services account.
StorageCredentials destinationStorageCredentials =
new StorageCredentials(_destStorageAccountName, _destStorageAccountKey);
// Get a reference to the source asset in the source context.
IAsset sourceAsset = _sourceContext.Assets.Where(asset => asset.Id == _sourceAssetID).First();
// Create an empty destination asset in the destination context.
IAsset destinationAsset = _destContext.Assets.Create(sourceAsset.Name, AssetCreationOptions.None);
// Copy the files in the source asset instance into the destination asset instance.
// There is an additional overload with async support.
sourceAsset.Copy(destinationAsset, destinationStorageCredentials);
Console.WriteLine("Done");
}
}
}
将 Blob 从存储帐户复制到 AMS 帐户
先决条件
- 一个需要从其中复制 Blob 的存储帐户。
- 一个需要将 Blob 复制到其中的 AMS 帐户。
设置项目
- 按照使用 .NET 进行媒体服务开发中所述来设置开发环境。
- 将 appSettings 节添加到 .config 文件,并根据源存储和目标 AMS 帐户更新值。
<appSettings>
<add key="SourceStorageAccountName" value="name" />
<add key="SourceStorageAccountKey" value="key" />
<add key="NameOfBlobContainerYouWantToCopy" value="BlobContainerName"/>
<add key="AMSAADTenantDomain" value="tenant"/>
<add key="AMSRESTAPIEndpoint" value="endpoint"/>
<add key="AMSClientId" value="clientID"/>
<add key="AMSClientSecret" value="clientSecret"/>
<add key="AMSStorageAccountName" value="name"/>
<add key="AMSStorageAccountKey" value="key"/>
</appSettings>
将 Blob 从某个存储帐户复制到一个 AMS 帐户中的新资产
以下代码将存储帐户中的 Blob 复制到媒体服务资产中。
Note
不同 AMS 策略的策略限制为 1,000,000 个(例如,对于定位器策略或 ContentKeyAuthorizationPolicy)。 如果始终使用相同的日期/访问权限,则应使用相同的策略 ID,例如,用于要长期就地保留的定位符的策略(非上传策略)。 有关详细信息,请参阅本文。
using System;
using System.Configuration;
using System.Linq;
using Microsoft.WindowsAzure.MediaServices.Client;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
namespace CopyExistingBlobsIntoAsset
{
class Program
{
// Read values from the App.config file.
private static readonly string _sourceStorageAccountName =
ConfigurationManager.AppSettings["SourceStorageAccountName"];
private static readonly string _sourceStorageAccountKey =
ConfigurationManager.AppSettings["SourceStorageAccountKey"];
private static readonly string _NameOfBlobContainerYouWantToCopy =
ConfigurationManager.AppSettings["NameOfBlobContainerYouWantToCopy"];
private static readonly string _AMSAADTenantDomain =
ConfigurationManager.AppSettings["AMSAADTenantDomain"];
private static readonly string _AMSRESTAPIEndpoint =
ConfigurationManager.AppSettings["AMSRESTAPIEndpoint"];
private static readonly string _AMSClientId =
ConfigurationManager.AppSettings["AMSClientId"];
private static readonly string _AMSClientSecret =
ConfigurationManager.AppSettings["AMSClientSecret"];
private static readonly string _AMSStorageAccountName =
ConfigurationManager.AppSettings["AMSStorageAccountName"];
private static readonly string _AMSStorageAccountKey =
ConfigurationManager.AppSettings["AMSStorageAccountKey"];
// Field for service context.
private static CloudMediaContext _context = null;
private static CloudStorageAccount _sourceStorageAccount = null;
private static CloudStorageAccount _destinationStorageAccount = null;
static void Main(string[] args)
{
AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(_AMSAADTenantDomain,
new AzureAdClientSymmetricKey(_AMSClientId, _AMSClientSecret),
AzureEnvironments.AzureChinaCloudEnvironment);
var tokenProvider = new AzureAdTokenProvider(tokenCredentials);
// Create the context for your source Media Services account.
_context = new CloudMediaContext(new Uri(_AMSRESTAPIEndpoint), tokenProvider);
_sourceStorageAccount =
new CloudStorageAccount(new StorageCredentials(_sourceStorageAccountName,
_sourceStorageAccountKey), true);
_destinationStorageAccount =
new CloudStorageAccount(new StorageCredentials(_AMSStorageAccountName,
_AMSStorageAccountKey), true);
CloudBlobClient sourceCloudBlobClient =
_sourceStorageAccount.CreateCloudBlobClient();
CloudBlobContainer sourceContainer =
sourceCloudBlobClient.GetContainerReference(_NameOfBlobContainerYouWantToCopy);
CreateAssetFromExistingBlobs(sourceContainer);
Console.WriteLine("Done");
}
static private IAsset CreateAssetFromExistingBlobs(CloudBlobContainer sourceBlobContainer)
{
CloudBlobClient destBlobStorage = _destinationStorageAccount.CreateCloudBlobClient();
// Create a new asset.
IAsset asset = _context.Assets.Create("NewAsset_" + Guid.NewGuid(), AssetCreationOptions.None);
IAccessPolicy writePolicy = _context.AccessPolicies.Create("writePolicy",
TimeSpan.FromHours(24), AccessPermissions.Write);
ILocator destinationLocator =
_context.Locators.CreateLocator(LocatorType.Sas, asset, writePolicy);
// Get the asset container URI and Blob copy from mediaContainer to assetContainer.
CloudBlobContainer destAssetContainer =
destBlobStorage.GetContainerReference((new Uri(destinationLocator.Path)).Segments[1]);
if (destAssetContainer.CreateIfNotExists())
{
destAssetContainer.SetPermissions(new BlobContainerPermissions
{
PublicAccess = BlobContainerPublicAccessType.Blob
});
}
var blobList = sourceBlobContainer.ListBlobs();
foreach (CloudBlockBlob sourceBlob in blobList)
{
var assetFile = asset.AssetFiles.Create((sourceBlob as ICloudBlob).Name);
ICloudBlob destinationBlob = destAssetContainer.GetBlockBlobReference(assetFile.Name);
CopyBlob(sourceBlob, destAssetContainer);
sourceBlob.FetchAttributes();
assetFile.ContentFileSize = (sourceBlob as ICloudBlob).Properties.Length;
assetFile.Update();
Console.WriteLine("File {0} is of {1} size", assetFile.Name, assetFile.ContentFileSize);
}
asset.Update();
destinationLocator.Delete();
writePolicy.Delete();
// Set the primary asset file.
// If, for example, we copied a set of Smooth Streaming files,
// set the .ism file to be the primary file.
// If we, for example, copied an .mp4, then the mp4 would be the primary file.
var ismAssetFile = asset.AssetFiles.ToList().
Where(f => f.Name.EndsWith(".ism", StringComparison.OrdinalIgnoreCase)).ToArray().FirstOrDefault();
// The following code assigns the first .ism file as the primary file in the asset.
// An asset should have one .ism file.
if (ismAssetFile != null)
{
ismAssetFile.IsPrimary = true;
ismAssetFile.Update();
}
return asset;
}
/// <summary>
/// Copies the specified blob into the specified container.
/// </summary>
/// <param name="sourceBlob">The source container.</param>
/// <param name="destinationContainer">The destination container.</param>
static private void CopyBlob(ICloudBlob sourceBlob, CloudBlobContainer destinationContainer)
{
var signature = sourceBlob.GetSharedAccessSignature(new SharedAccessBlobPolicy
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24)
});
var destinationBlob = destinationContainer.GetBlockBlobReference(sourceBlob.Name);
if (destinationBlob.Exists())
{
Console.WriteLine(string.Format("Destination blob '{0}' already exists. Skipping.", destinationBlob.Uri));
}
else
{
// Display the size of the source blob.
Console.WriteLine(sourceBlob.Properties.Length);
Console.WriteLine(string.Format("Copy blob '{0}' to '{1}'", sourceBlob.Uri, destinationBlob.Uri));
destinationBlob.StartCopy(new Uri(sourceBlob.Uri.AbsoluteUri + signature));
while (true)
{
// The StartCopyFromBlob is an async operation,
// so we want to check if the copy operation is completed before proceeding.
// To do that, we call FetchAttributes on the blob and check the CopyStatus.
destinationBlob.FetchAttributes();
if (destinationBlob.CopyState.Status != CopyStatus.Pending)
{
break;
}
//It's still not completed. So wait for some time.
System.Threading.Thread.Sleep(1000);
}
// Display the size of the destination blob.
Console.WriteLine(destinationBlob.Properties.Length);
}
}
}
}
后续步骤
现即可编码已上传的资产。 有关详细信息,请参阅 对资产进行编码。