C# 上载到Azure Media Services/blob存储,SasLocator未显示上载的文件
所以我想将视频从客户端桌面应用程序上传到Azure媒体服务(当然使用Azure存储) 我正在尝试结合以下几点:C# 上载到Azure Media Services/blob存储,SasLocator未显示上载的文件,c#,azure,azure-storage,azure-mobile-services,C#,Azure,Azure Storage,Azure Mobile Services,所以我想将视频从客户端桌面应用程序上传到Azure媒体服务(当然使用Azure存储) 我正在尝试结合以下几点: 此旧文档: 和此相关的新文档: 第一个演示了我的场景的完美示例,但第二个演示了如何使用BlobTransferClient上载多个文件并具有“进度”指示器 问题:它似乎确实上传了,上传后我没有收到任何错误,但Azure门户/存储帐户中没有显示任何内容。 它似乎是上传的,因为任务需要很长时间,任务管理器显示wifi上传进度,Azure存储显示(成功)请求正在发出 因此,服务器端,我暂
- 此旧文档:
- 和此相关的新文档:李>
BlobTransferClient
上载多个文件并具有“进度”指示器
问题:它似乎确实上传了,上传后我没有收到任何错误,但Azure门户/存储帐户中没有显示任何内容。
它似乎是上传的,因为任务需要很长时间,任务管理器显示wifi上传进度,Azure存储显示(成功)请求正在发出
因此,服务器端,我暂时创建了一个SasLocator:
public async Task<VideoUploadModel> GetSasLocator(string filename)
{
var assetName = filename + DateTime.UtcNow;
IAsset asset = await _context.Assets.CreateAsync(assetName, AssetCreationOptions.None, CancellationToken.None);
IAccessPolicy accessPolicy = _context.AccessPolicies.Create(assetName, TimeSpan.FromMinutes(10),
AccessPermissions.Write);
var locator = _context.Locators.CreateLocator(LocatorType.Sas, asset, accessPolicy);
var blobUri = new UriBuilder(locator.Path);
blobUri.Path += "/" + filename;
var model = new VideoUploadModel()
{
Filename = filename,
AssetName = assetName,
SasLocator = blobUri.Uri.AbsoluteUri,
AssetId = asset.Id
};
return model;
}
我还尝试在Azure中手动上载资产。因此,点击资产菜单中的“上传”,然后对其进行编码。这一切都很好
更新2:
深入挖掘后,我提出了以下尚未生产验证的方法,以使其目前起作用:
1.直接从存储中获取共享访问签名并将其上载到存储中:
public static async Task<string> GetMediaSasLocator(string filename)
{
CloudBlobContainer cont = await GetMediaContainerAsync();
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy()
{
SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(60),
Permissions = SharedAccessBlobPermissions.Write,
SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5)
};
await cont.FetchAttributesAsync();
return cont.Uri.AbsoluteUri + "/" + filename + cont.GetSharedAccessSignature(policy);
}
公共静态异步任务GetMediaSasLocator(字符串文件名)
{
CloudBlobContainer cont=等待GetMediaContainerAsync();
SharedAccessBlobPolicy策略=新的SharedAccessBlobPolicy()
{
SharedAccessExpiryTime=DateTimeOffset.UtcNow.AddMinutes(60),
权限=SharedAccessBlobPermissions.Write,
SharedAccessStartTime=DateTimeOffset.UtcNow.AddMinutes(-5)
};
等待继续获取属性同步();
返回cont.Uri.AbsoluteUri+“/”+文件名+cont.GetSharedAccessSignature(策略);
}
有了这个SaS,我可以像更新1中显示的那样上传,那里没有任何变化
2.创建一个Azure函数(已经计划好了),用于处理资产创建、文件上传到资产、编码和发布。
这是通过遵循本教程完成的:然后实现中所示的代码
因此,这个“有效”,但还不是完美的,我的客户端WPF应用程序中仍然没有我的进度指示器,Azure功能需要相当长的时间才能完成,因为我们基本上是在文件已经在Azure存储中之后将其再次“上载”到资产。我宁愿使用一种方法从一个容器复制到一个资产容器
我之所以提到这一点,是因为Azure函数需要一个固定的给定容器名称,因为资产在存储帐户中创建自己的容器,所以您无法在这些帐户上触发Azure函数。因此,要使用Azure函数,我似乎真的必须将其上载到一个固定的容器名,然后再执行其余操作
问题仍然存在:为什么通过
BlobTransferClient
将视频文件上载到Azure存储不起作用?如果它能工作,我如何基于多个容器触发Azure函数。最好使用类似asset-{name}/{name}.avi的“路径” 最终,我需要在UploadBlob
方法中指定基本URL,因此不需要SasLocator URL中的文件名本身,而只需要容器名
一旦我修复了这个问题,我还注意到它没有上传到我在服务器端生成的SasLocator中提供的文件名(它包括customerID前缀)。我不得不使用另一个方法重载来获得正确的文件名
public async Task UploadVideoFilesToBlobStorage(List<VideoUploadModel> videos, CancellationToken cancellationToken)
{
var blobTransferClient = new BlobTransferClient();
//register events
blobTransferClient.TransferProgressChanged += BlobTransferClient_TransferProgressChanged;
//files
_videoCount = _videoCountLeft = videos.Count;
foreach (var video in videos)
{
var blobUri = new Uri(video.SasLocator);
//create the sasCredentials
var sasCredentials = new StorageCredentials(blobUri.Query);
//get the URL without sasCredentials, so only path and filename.
var blobUriBaseFile = new Uri(blobUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path,
UriFormat.UriEscaped));
//get the URL without filename (needed for BlobTransferClient (seems to me like a issue)
var blobUriBase = new Uri(blobUriBaseFile.AbsoluteUri.Replace("/"+video.Filename, ""));
var blobClient = new CloudBlobClient(blobUriBaseFile, sasCredentials);
//upload using stream, other overload of UploadBlob forces to put online filename of local filename
using (FileStream fs = new FileStream(video.FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
await blobTransferClient.UploadBlob(blobUriBase, video.Filename, fs, null, cancellationToken, blobClient,
new NoRetry(), "video/x-msvideo");
}
_videoCountLeft -= 1;
}
blobTransferClient.TransferProgressChanged -= BlobTransferClient_TransferProgressChanged;
}
private void BlobTransferClient_TransferProgressChanged(object sender, BlobTransferProgressChangedEventArgs e)
{
Console.WriteLine("progress, seconds remaining:" + e.TimeRemaining.Seconds);
double bytesTransfered = e.BytesTransferred;
double bytesTotal = e.TotalBytesToTransfer;
double thisProcent = bytesTransfered / bytesTotal;
double procent = thisProcent;
//devide by video amount
int videosUploaded = _videoCount - _videoCountLeft;
if (_videoCountLeft > 0)
{
procent = (thisProcent + videosUploaded) / _videoCount;
}
procent = procent * 100;//to real %
UploadProgressChangedEvent?.Invoke((int)procent, videosUploaded, _videoCount);
}
公共异步任务上载视频文件到全局存储(列出视频,CancellationToken CancellationToken)
{
var blobTransferClient=new blobTransferClient();
//注册事件
blobTransferClient.TransferProgressChanged+=blobTransferClient\u TransferProgressChanged;
//档案
_videoCount=\u videoCountLeft=视频。计数;
foreach(视频中的var视频)
{
var blobUri=新Uri(video.SasLocator);
//创建sass凭据
var sasceredentials=新的StorageCredentials(blobUri.Query);
//获取不带凭据的URL,因此仅获取路径和文件名。
var blobUriBaseFile=新Uri(blobUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path,
UriFormat.UriFormat);
//获取不带文件名的URL(BlobTransferClient所需(在我看来似乎是个问题)
var blobUriBase=新Uri(blobUriBaseFile.AbsoluteUri.Replace(“/”+video.Filename,”);
var blobClient=新的CloudBlobClient(blobUriBaseFile,sascdentials);
//使用流上传,UploadBlob的其他重载强制将本地文件名的文件名放在网上
使用(FileStream fs=newfilestream(video.FilePath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
{
等待blobTransferClient.UploadBlob(blobUriBase,video.Filename,fs,null,cancellationToken,blobClient,
新NoRetry(),“视频/x-msvideo”);
}
_videoCountLeft-=1;
}
blobTransferClient.TransferProgressChanged-=blobTransferClient\u TransferProgressChanged;
}
私有无效BlobTransferClient\u TransferProgressChanged(对象发送方,BlobTransferProgressChangedEventArgs e)
{
Console.WriteLine(“进度,剩余秒数:+e.TimeLeving.seconds”);
double ByTestTransfered=e.ByTestTransfered;
double ByTestTotal=e.Total ByTestOtTransfer;
double thisProcent=通过测试转移/通过测试总计;
双procent=此procent;
//按视频量划分
int videosupload=\u videoCount-\u videoCountLeft;
如果(\u videoCountLeft>0)
{
procent=(thisProcent+videosUploaded)/\u videoCount;
}
procent=procent*100;//到实值%
UploadProgressChangedEvent?.Invoke((int)procent,videosUploaded,\u videoCount);
}
实际上Microsoft.WindowsAzure.MediaServices.Client.BlobTransferClientpublic static async Task<string> GetMediaSasLocator(string filename)
{
CloudBlobContainer cont = await GetMediaContainerAsync();
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy()
{
SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(60),
Permissions = SharedAccessBlobPermissions.Write,
SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5)
};
await cont.FetchAttributesAsync();
return cont.Uri.AbsoluteUri + "/" + filename + cont.GetSharedAccessSignature(policy);
}
public async Task UploadVideoFilesToBlobStorage(List<VideoUploadModel> videos, CancellationToken cancellationToken)
{
var blobTransferClient = new BlobTransferClient();
//register events
blobTransferClient.TransferProgressChanged += BlobTransferClient_TransferProgressChanged;
//files
_videoCount = _videoCountLeft = videos.Count;
foreach (var video in videos)
{
var blobUri = new Uri(video.SasLocator);
//create the sasCredentials
var sasCredentials = new StorageCredentials(blobUri.Query);
//get the URL without sasCredentials, so only path and filename.
var blobUriBaseFile = new Uri(blobUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path,
UriFormat.UriEscaped));
//get the URL without filename (needed for BlobTransferClient (seems to me like a issue)
var blobUriBase = new Uri(blobUriBaseFile.AbsoluteUri.Replace("/"+video.Filename, ""));
var blobClient = new CloudBlobClient(blobUriBaseFile, sasCredentials);
//upload using stream, other overload of UploadBlob forces to put online filename of local filename
using (FileStream fs = new FileStream(video.FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
await blobTransferClient.UploadBlob(blobUriBase, video.Filename, fs, null, cancellationToken, blobClient,
new NoRetry(), "video/x-msvideo");
}
_videoCountLeft -= 1;
}
blobTransferClient.TransferProgressChanged -= BlobTransferClient_TransferProgressChanged;
}
private void BlobTransferClient_TransferProgressChanged(object sender, BlobTransferProgressChangedEventArgs e)
{
Console.WriteLine("progress, seconds remaining:" + e.TimeRemaining.Seconds);
double bytesTransfered = e.BytesTransferred;
double bytesTotal = e.TotalBytesToTransfer;
double thisProcent = bytesTransfered / bytesTotal;
double procent = thisProcent;
//devide by video amount
int videosUploaded = _videoCount - _videoCountLeft;
if (_videoCountLeft > 0)
{
procent = (thisProcent + videosUploaded) / _videoCount;
}
procent = procent * 100;//to real %
UploadProgressChangedEvent?.Invoke((int)procent, videosUploaded, _videoCount);
}