当前位置 : 主页 > 手机开发 > ROM >

azure 上传blob到ams(CreateFromBlob)

来源:互联网 收集:自由互联 发布时间:2021-06-10
遇到的错误:The destination storage credentials must contain the account key credentials,参数名: destinationStorageCredentials 解决方法:AccountName与AccountKey参数值错误 AccountName就是存储账户名字 AccountKey值

遇到的错误:The destination storage credentials must contain the account key credentials,参数名: destinationStorageCredentials

解决方法:AccountName与AccountKey参数值错误

AccountName就是存储账户名字

AccountKey值获取方式:打开存储账户-->访问秘钥-->key1或者key2

Azure上传资产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>
        /// 获取媒体文件上下文
        /// </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>
        /// 创建新资产并上传视频文件
        /// </summary>
        /// <param name="fileName">上传文件名称,如: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.
            //用于流媒体(例如 MPEG DASH、HLS 或平滑流式处理)的 OnDemandOrigin 定位符
            //_context.Locators.Create(
            //    LocatorType.OnDemandOrigin,
            //    asset,
            //    AccessPermissions.Read,
            //    TimeSpan.FromDays(30));

            //用于下载媒体文件的访问签名
            _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>
        /// 上传blob文件到ams中
        /// </summary>
        /// <param name="fileName">文件名</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
                {
                    // 创建CloudBlobClient,它代表存储帐户的Blob存储端点。
                    CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();

                    //fileName = "https://qdlsstorage.blob.core.windows.net/video/20190514165259-魔术视频.mp4";
                    //通过连接获取容器名字和文件名字
                    var index = fileName.IndexOf(accountName, StringComparison.CurrentCultureIgnoreCase);
                    var temp = fileName.Substring(index + 1);
                    var fs = temp.Split(/);
                    var containerName = fs[1];
                    fileName = fs[2]; 这一段代码根据你们自己的情况进行修改,我这个是因为传递的全路径才这么写的

                    // 获取Blob容器 
                    cloudBlobContainer = cloudBlobClient.GetContainerReference(containerName);
                    GetCloudMediaContext();
                    var storageCredentials = new StorageCredentials(accountName, accountKey);
                    var cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(fileName);

                    cloudBlockBlob.FetchAttributes();//这一句是关键,如果不加这一句就会报错,我把报错信息放到下面 var inputAsset = _context.Assets.CreateFromBlob(cloudBlockBlob, storageCredentials, AssetCreationOptions.None);
                    var strsasUri = PublishAssetGetURLs(inputAsset);
                    return strsasUri;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }

            }

            return null;
        }
    }

 

报错信息:

<?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>

参考地址:https://github.com/Azure/azure-sdk-for-media-services-extensions/issues/40  (这是通过谷歌找到的资料,百度根本不行)

 

直接上传文件到资产中调用方法:

                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 = $@"上传视频成功";
                            File.Delete(fileFullPath);
                        }
                        catch (Exception ex)
                        {
                            msg = "上传文件写入失败:" + ex.InnerException + ex.Message + ex.InnerException?.InnerException + "fileFullPath=" + fileFullPath;
                        }

因为使用的是HTML自带的file上传控件,传递给接口的文件地址全路径是错误的,所以只能保存到接口服务器本地,上传到azure上去之后再删除这个文件。

 

上传blob到ams

               var ams = new AzureMediaServiceController();
                        var t = ams.UploadBlobFile(fileUrl);
网友评论