Search code examples
azureazure-media-services

Transferring files from previously deleted azure media service to new media service- is it possible?


Is it possible to transfer files from an old media service account which has been accidentally deleted to a new media services account.

Microsoft tech support have been no help. I'm able to copy over the files to the new media service account, but when i test to see if I can publish one of the assets in the portal, It gives me successful streaming urls, but when I try to access those I get a network error

<serverError>
  <status>404</status>
  <subStatus>1000</subStatus>
  <hresult>MPE_STORAGE_RESOURCE_NOT_FOUND</hresult>
  <activityId>80028340-0004-F800-B63F-84710C7967BB</activityId>
  <serviceId>4A42CB8E-4542-0C18-2C0D-4B460D96B604</serviceId>
</serverError>

I don't think it can find the manifest file. which is named pc124m190o_AdaptiveStreaming_manifest.xml

The name of the metadata file could also be a potential problem

5f7e8f45-87e9-49ce-a2ae-7bb673bf0b0f_metadata.xml

has anyone successfully done this?

Here is the code I'm using to copy the files. Maybe the error is here?

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

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

         // CreateAssetFromExistingBlobs(sourceContainer);

          

        List<string> containers=GetAllContainerNames(sourceCloudBlobClient);

        foreach(string item in containers)
        {
            CloudBlobContainer sourceContainer =
             sourceCloudBlobClient.GetContainerReference(item);
            CreateAssetFromExistingBlobs(sourceContainer);
            Console.WriteLine("finished " + item);
        }

       
    }



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

Here is what my media storage window looks like enter image description here


Solution

  • The manifest file you mentioned is technically not required for streaming. What is missing is that when you copied the files to your new Storage account the new Media Services account knows nothing of them. You must create new assets and copy the files into the new assets for Media Services to see them. I recommend doing an import with Azure Media Services Explorer in your new account from the Storage account.