azure upload blob to ams(CreateFromBlob)

Encountered error: The destination storage credentials must contain the account key credentials, parameter name: destinationStorageCredentials

Solution: the parameter values of AccountName and AccountKey are wrong

AccountName is the name of the storage account

How to obtain the AccountKey value: open the storage account > access secret key > key1 or key2

Azure upload asset SDK

    public class AzureMediaServiceController : ApiController
    {
        // Read values from the App.config file.

        private static readonly string _AADTenantDomain =
            ConfigurationManager.AppSettings["AMSAADTenantDomain"];
        private static readonly string _RESTAPIEndpoint =
            ConfigurationManager.AppSettings["AMSRESTAPIEndpoint"];
        private static readonly string _AMSClientId =
            ConfigurationManager.AppSettings["AMSClientId"];
        private static readonly string _AMSClientSecret =
            ConfigurationManager.AppSettings["AMSClientSecret"];

        private static CloudMediaContext _context = null;

        [HttpPost, Route("api/AzureMediaService/DeliverVideo")]
        // GET: AMSDeliverVideo
        public string DeliverVideo(string fileName)
        {
            GetCloudMediaContext();
            IAsset inputAsset = UploadFile(fileName, AssetCreationOptions.None);
            var strsasUri = PublishAssetGetURLs(inputAsset);
            return strsasUri;
        }
        /// <summary>
        /// Get media file context
        /// </summary>
        private void GetCloudMediaContext()
        {
            AzureAdTokenCredentials tokenCredentials =
                new AzureAdTokenCredentials(_AADTenantDomain,
                    new AzureAdClientSymmetricKey(_AMSClientId, _AMSClientSecret),
                    AzureEnvironments.AzureCloudEnvironment);

            var tokenProvider = new AzureAdTokenProvider(tokenCredentials);

            _context = new CloudMediaContext(new Uri(_RESTAPIEndpoint), tokenProvider);
        }

        /// <summary>
        /// Create new assets and upload video files
        /// </summary>
        /// <param name="fileName">Upload file name,as:F:\BigBuck.mp4</param>
        static public IAsset UploadFile(string fileName, AssetCreationOptions options)
        {
            IAsset inputAsset = _context.Assets.CreateFromFile(
                fileName,
                options,
                (af, p) =>
                {
                    Console.WriteLine("Uploading '{0}' - Progress: {1:0.##}%", af.Name, p.Progress);
                });
            return inputAsset;
        }
        static public string PublishAssetGetURLs(IAsset asset)
        {
            // Publish the output asset by creating an Origin locator for adaptive streaming,
            // and a SAS locator for progressive download.
            //For streaming media (for example MPEG DASH,HLS Or smooth streaming) OnDemandOrigin Locator
            //_context.Locators.Create(
            //    LocatorType.OnDemandOrigin,
            //    asset,
            //    AccessPermissions.Read,
            //    TimeSpan.FromDays(30));

            //Access signature for downloading media files
            _context.Locators.Create(
                LocatorType.Sas,
                asset,
                AccessPermissions.Read,
                TimeSpan.FromDays(30));


            IEnumerable<IAssetFile> mp4AssetFiles = asset
                    .AssetFiles
                    .ToList()
                    .Where(af => af.Name.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase));


            // Get the URls for progressive download for each MP4 file that was generated as a result
            // of encoding.
            //List<Uri> mp4ProgressiveDownloadUris = mp4AssetFiles.Select(af => af.GetSasUri()).ToList();
            string mp4ProgressiveDownloadUris = mp4AssetFiles.Select(af => af.GetSasUri()).FirstOrDefault().OriginalString;

            return mp4ProgressiveDownloadUris;
            // Display the URLs for progressive download.   
            // mp4ProgressiveDownloadUris.ForEach(uri => Console.WriteLine(uri + "\n"));    

        }


        string storageConnectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
        string accountName = ConfigurationManager.AppSettings["AccountName"];
        string accountKey = ConfigurationManager.AppSettings["AccountKey"];

        /// <summary>
        /// upload blob File to ams in
        /// </summary>
        /// <param name="fileName">file name</param>
        public string UploadBlobFile(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                return string.Empty;
            CloudStorageAccount storageAccount = null;
            CloudBlobContainer cloudBlobContainer = null;
            if (CloudStorageAccount.TryParse(storageConnectionString, out storageAccount))
            {
                try
                {
                    // Establish CloudBlobClient,It represents the Blob Storage endpoint.
                    CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();

                    //fileName = "https://qdlsstorage.blob.core.windows.net/video/20190514165259-Magic video.mp4";
                    //Get container name and file name through connection
                    var index = fileName.IndexOf(accountName, StringComparison.CurrentCultureIgnoreCase);
                    var temp = fileName.Substring(index + 1);
                    var fs = temp.Split('/');
                    var containerName = fs[1];
                    fileName = fs[2]; This code is modified according to your own situation. I wrote this because of the full path of transmission

                    // Obtain Blob container 
                    cloudBlobContainer = cloudBlobClient.GetContainerReference(containerName);
                    GetCloudMediaContext();
                    var storageCredentials = new StorageCredentials(accountName, accountKey);
                    var cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(fileName);

                    cloudBlockBlob.FetchAttributes();//This sentence is the key. If you don't add this sentence, you will report an error. I will put the error information below
                    var inputAsset = _context.Assets.CreateFromBlob(cloudBlockBlob, storageCredentials, AssetCreationOptions.None);
                    var strsasUri = PublishAssetGetURLs(inputAsset);
                    return strsasUri;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }

            }

            return null;
        }
    }

 

Error message:

<?xml version="1.0" encoding="utf-8"?><m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><m:code /><m:message xml:lang="en-US">AssetFile ContentFileSize must not be negative</m:message></m:error>

Reference address: https://github.com/Azure/azure-sdk-for-media-services-extensions/issues/40 (this is the information found through Google, Baidu can't do it at all)

 

The method of directly uploading files to assets:

                var virtualPath = "/UploadFile/Files/";
                        var path = HttpContext.Current.Server.MapPath(virtualPath);
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }
                        var fileFullPath = $"{path}{fileName}";
                        try
                        {
                            file.SaveAs(fileFullPath);
                            var ams = new AzureMediaServiceController();
                            url = ams.DeliverVideo(fileFullPath);
                            result = true;
                            msg = $@"Upload video succeeded";
                            File.Delete(fileFullPath);
                        }
                        catch (Exception ex)
                        {
                            msg = "Upload file write failed:" + ex.InnerException + ex.Message + ex.InnerException?.InnerException + "fileFullPath=" + fileFullPath;
                        }

Because the HTML file upload control is used, the full path of the file address passed to the interface is wrong, so it can only be saved to the local interface server, uploaded to azure, and then deleted.

 

Upload blob to ams

               var ams = new AzureMediaServiceController();
                        var t = ams.UploadBlobFile(fileUrl);

Tags: C# SDK encoding xml Windows

Posted on Sun, 10 Nov 2019 14:02:00 -0800 by johnkelly