我遇到了Windows Azure Blob存储的两个问题。
我正在开发一个记录视频的PhoneGap / Cordova移动应用程序,然后使用javascript将视频上传到Azure Blob存储。我正在使用Gaurav Mantri博客文章中的一个很好的javascript配方:http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/
问题1:上传过程非常缓慢。我使用PUT BLOCK Api,其中视频文件一次上传一个块(大约256 KB /文件),最终整个文件使用PUT BLOCK LIST提交。一个小的mp4视频,例如14秒/ 10 MB,上传需要5-10分钟!会发生什么事情是很多块会被快速上传,然后突然间进程将暂停几分钟而没有任何反应(通常是40-60%的块被上传),然后它会在暂停之前快速上传另一批块再次。
以下是我用来上传的javascript片段:
reader.onloadend = function (evt) {
if (evt.target.readyState == FileReader.DONE)
{
var requestData = new Uint8Array(evt.target.result);
var blockId = blockIdPrefix + pad(blockIds.length, 6);
blockIds.push(btoa(blockId));
var uri = submitUri + '&comp=block&blockid=' + blockIds[blockIds.length-1];
$.support.cors = true;
$.ajax({
url: uri,
type: "PUT",
data: requestData,
processData: false,
beforeSend: function(xhr) {
xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
//xhr.setRequestHeader('Content-Length', requestData.length);
},
success: function (data, status) {
bytesUploaded += requestData.length;
var percentComplete = ((parseFloat(bytesUploaded) / parseFloat(selectedFile.size)) * 100).toFixed(2);
console.log(percentComplete + " %");
uploadFileInBlocks();
},
error: function(xhr, desc, err) {
console.log(desc);
console.log(err);
}
});
}
};
function uploadFileInBlocks() {
if (totalBytesRemaining > 0) {
var fileContent = selectedFile.slice(currentFilePointer, currentFilePointer + maxBlockSize);
reader.readAsArrayBuffer(fileContent);
currentFilePointer += maxBlockSize;
totalBytesRemaining -= maxBlockSize;
if (totalBytesRemaining < maxBlockSize) {
maxBlockSize = totalBytesRemaining;
}
} else {
commitBlockList();
}
}
存储帐户配置为使用CORS,并且已从Azure管理工作室生成SAS uri(SAS uri不像其他许多示例那样动态生成)。除了地理冗余帐户之外,我还尝试过切换到本地冗余存储帐户,但这并不能使上传速度更快。不幸的是,由于代码在我的Android手机上运行,我无法跟踪Fiddler或tcpdump的流量。
从Blob存储文档:
&#34;可以用两种方式之一创建块blob。可以通过调用Put Blob操作上载小于或等于64 MB大小的块blob。必须将大于64 MB的块blob作为一组块上载,每个块的大小必须小于或等于4 MB。通过调用Put Block List,可以按指定的顺序将一组成功上载的块组合成单个连续的blob。块blob当前支持的最大大小为200 GB。&#34;
我正在使用SAS URI中指定的存储版本2014-02-14:appname.blob.core.windows.net/asset-10146439-dbe1-4af9-85df-a94cf91ef2ec?sr=c&sv= 2014年2月14日&安培; ST = 2014-08-13T18%3A01%3A52Z&安培; SE = 2014-10-18T19%3A01%3A52Z&安培; SP =&RWL放大器; SIG = mysignature
我认为上传速度要快得多的原因是因为当我使用PUT BLOB api上传例如10 MB的文件时 - 它发生得非常快(大约20-30秒)。但是,正如上面的文档所述,PUT BLOB只能用于小于64 MB的文件,这导致了我的第二个问题:
问题2:当我使用PUT BLOB api时,会在视频文件的开头插入Content-Disposition标头,使播放失败(视频应该从html5视频元素播放)。如何在使用PUT BLOB时避免自动插入Content-Disposition标头?我在上传时尝试将x-ms-blob-content-disposition显式设置为空字符串,但不幸的是它似乎没有效果(标题仍然存在)。
与PUT BLOB一起使用的代码是:
var ft = new FileTransfer(),
options = new FileUploadOptions();
options.httpMethod = "PUT";
options.chunkedMode = false;
options.headers = {
'x-ms-blob-type': 'BlockBlob'
,'Content-Type': 'video/mp4'
};
ft.upload(mediaFile.toURL(), submitUri,
function (e) {
console.log("upload success!");
},
function (e) {
alert("Upload failed");
}, options);
我还尝试了第三种方法,即使用XMLHttpRequest上传文件,这会产生一个没有Content-Disposition标头的文件,但是视频文件以某种方式被破坏 - 它无法播放,不能播放甚至在将它下载到桌面时(我已经在十六进制编辑器中打开了视频文件,文件的起始字节看起来与来自有效mp4文件的字节完全一样......也许是精通mp4格式的人可以找出问题所在,这里有一个这样一个破损的视频文件的例子:https://onedrive.live.com/redir?resid=B3105327829B3E0C!23617&authkey=!AHoS6cZJmDlIN-E&ithint=file%2cmp4
var ajaxRequest = new XMLHttpRequest();
var rawData = null;
try {
reader = new FileReader();
reader.onload = function (evt) {
rawData = reader.result;
ajaxRequest.open('PUT', submitUri, true);
ajaxRequest.setRequestHeader('Content-Type', 'video/mp4');
ajaxRequest.setRequestHeader('x-ms-blob-type', 'BlockBlob');
ajaxRequest.send(rawData);
console.log("done uploading!")
}
reader.readAsBinaryString(selectedFile)
非常感谢任何指示,谢谢!