How to save binary video data to azure blob?

谁说胖子不能爱 提交于 2020-03-05 03:49:09

问题


I am currently using this code to select a file from local disk to my api:

<script language="javascript" type="text/javascript">
$(document).ready(function(){

$(':file').on('change', function () {
  var file = this.files[0];

    if (file.type !== "video/mp4" && file.type!== "video/quicktime") {
        alert("Content must be video .mp4 or .mov")
    }

$(':button').on('click', function () {
    if (file.type == "video/mp4" || file.type == "video/quicktime"){
  $.ajax({
    // Your server script to process the upload
    url: 'azureAPI',
    type: 'POST',

    // Form data
    data: new FormData($('form')[0]),

    // Tell jQuery not to process data or worry about content-type
    // You *must* include these options!
    cache: false,
    contentType: false,
    processData: false,

    // Custom XMLHttpRequest
    xhr: function () {
      var myXhr = $.ajaxSettings.xhr();
      if (myXhr.upload) {
        // For handling the progress of the upload
        myXhr.upload.addEventListener('progress', function (e) {
          if (e.lengthComputable) {
            $('progress').attr({
              value: e.loaded,
              max: e.total,
            });
          }
        }, false);
      }
      return myXhr;
    }
  });
} else {
    alert ("File type must be .mp4 or .mov")
}
});
});
});
</script>

This sends (what I am assuming is) binary data in the form of this:

���
1!QAa"q2B���R�#3br��u�����S6C$%��5�cts�T&D4��U��d���e!1AQa2"q�#����3��B���X"��?��!=��W�u�ٗ�-2���?����ۯ�Կ�i���t����M���Y�-��-Vdϊ�P�<�<U#TY]K��dW
���

I am using Azure, and now trying to send this to Microsoft Video Indexer, which says to send the data as multipart/form-data in the body. (see https://api-portal.videoindexer.ai/docs/services/Operations/operations/Upload-Video?)

I tried sending the binary data in the body, but it said it required string/buffer.

I then tried sending the binary data in the body as var body = Buffer.from(req.body,'binary')

Which sent, but VI responded saying that there was an issue indexing the data, perhaps as I sent with the wrong encoding?

To work around this, I am now trying to save that binary data to a block blob first, then I will call that url after, however I am having trouble saving binary data to Azure block blob using:

var buf = Buffer.from(req.body, 'binary');
blobService.createBlockBlobFromText(container, 'fileName.mp4', buf, {contentSettings: {contentType: 'video/mp4', contentEncoding: 'binary'}}, function (error, result, response) {
    if(!error){
        callback('uploaded');
    } else {
        callback('nope');
    }

});

I tried this, without the contentSettings at first but that saved the data as contentType: application/octet-stream which wasn't opening as a video. I then added contentType, and lasted tried adding contentEncoding as well.

This saved the correct contentType but still the video could not be opened.

Does anyone know how to encode the data correctly to either send in the first instance straight to video indexer, or secondly to save binary data to Azure blob storage?

Thanks for any pointers, apologies if I left anything out.


回答1:


According to my test, if you want to use Azure function to upload file to Azure blob, please refer to the following code.

front-end

<!DOCTYPE html>
<html>
  <script type="text/javascript"
 src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.js">
</script>
<body>

 <form enctype="multipart/form-data">
    <input name="file" type="file" accept="video/*"/>
    <input type="button" value="Upload" />
</form>
<progress></progress>

<script language="javascript" type="text/javascript">
$(document).ready(function(){

$(':file').on('change', function () {
  var file = this.files[0];
    if (file.type !== "video/mp4" && file.type!== "video/quicktime") {
        alert("Content must be video .mp4 or .mov")
    }

$(':button').on('click', function () {

  if (file.type == "video/mp4" || file.type == "video/quicktime"){

    $.ajax({
    // Your server script to process the upload
    url: '',
    type: 'POST',
    crossDomain: true,
    enctype: 'multipart/form-data',
    // Form data
    data: new FormData($('form')[0]),

    // Tell jQuery not to process data or worry about content-type
    // You *must* include these options!
    cache: false,
    contentType: false,
    processData: false,

    success :  function(data){console.log(data);},

    // Custom XMLHttpRequest
    xhr: function () {
      var myXhr = $.ajaxSettings.xhr();
      if (myXhr.upload) {
        // For handling the progress of the upload

        myXhr.upload.addEventListener('progress', function (e) {
          if (e.lengthComputable) {
            $('progress').attr({
              value: e.loaded,
              max: e.total,
            });
          }
        }, false);
      }
      return myXhr;
    }
  });
} else {
    alert ("File type must be .mp4 or .mov")
}
});





});



});

</script>

</body>
</html>

Azure function

var multipart = require('parse-multipart')
var azure = require('azure-storage');
var getStream = require('into-stream')
module.exports = async function (context, request) {
    context.log('JavaScript HTTP trigger function processed a request.');
    // encode body to base64 string
    var bodyBuffer = Buffer.from(request.body);

    var boundary = multipart.getBoundary(request.headers['content-type']);
    // parse the body
    var parts = multipart.Parse(bodyBuffer, boundary);

    const accountname ="blobstorage0516";
            const key = "key";
            const containerName="test";
            var retryOperations = new azure.ExponentialRetryPolicyFilter();
            const blobClient  =azure.createBlobService(accountname,key).withFilter(retryOperations);
            blobClient.createContainerIfNotExists(containerName, function (error) {
                if (error) {
                  context.log(error);
                }
            });

            var options = {
                contentSettings:{contentType: parts[0].type},
                metadata: { fileName: parts[0].filename },
                blockSize:8*1024*1024,
                parallelOperationThreadCount:20,
                timeoutIntervalInMs:30*60*1000
              };
              var stream =getStream(parts[0].data)
              context.log("start")

              var result="ok"
            var speedsummary= blobClient.createBlockBlobFromStream(containerName,parts[0].filename,stream,parts[0].data.length,options,function (error) {


              if (error != null) {
               result=error
              } else {



              }})

               context.res = { body : { results : result}};
              context.done(); 


};

You also can access the video from the bloburl



来源:https://stackoverflow.com/questions/60066451/how-to-save-binary-video-data-to-azure-blob

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!