遇到的錯誤:The destination storage credentials must contain the account key credentials,參數名: destinationStorageCredentials 解決方法: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);