C# 上载到Azure Media Services/blob存储,SasLocator未显示上载的文件

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存储显示(成功)请求正在发出 因此,服务器端,我暂

所以我想将视频从客户端桌面应用程序上传到Azure媒体服务(当然使用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);
}