Search code examples
androidazure-blob-storageazure-media-services

How to upload media (.mp4) file using Azure SAS url from Android device


I am building rich video library on android and trying to upload video, as i do not want client to access my media key and other details i have making call to my server and return SAS url as a response which client will use to upload media

Just wondering what is best way to achieve uploading here, i tried with okHttp library and scuceeded most of the time ()few times i got scoket timeout exception for large file) but not sure how performant okHttp with azure,

intheory it is always good to chunk media file and upload, so could anyone one tell me what is the best way to upload file in azure blob from android using SAS url


Solution

  • Instead of uploading large files, you could try to cut them into blocks and then upload separate pieces of no larger than 4Mb. And once all the pieces (Blocks) are uploaded, you need to commit them all and give the order in which they should appear.

    enter image description here

    enter image description here

    enter image description here

    For more info, you can refer to this similar topic from SO.

    Edit:

    Here is an example Java code that works with OkHttp 3.6.0, and SAS URL.

    public class UploadBlobUsingSASUrl {
    
        public static void main(String[] args) throws IOException {
    
            UploadBlobUsingSASUrl uploadHandler = new UploadBlobUsingSASUrl();
    
            String sasSignature = "?sv=2016-05-31&ss=bfqt&srt=sco&sp=rwdlacup&se=2017-03-30T23:39:00Z&st=2017-03-20T15:39:00Z&spr=https&sig=A2m1O5qZf79L7925DHMJtfkBRI6GVFhYcrGLStBo%2BL0%3D";
            String blobStorageEndpoint = "https://<your-account>.blob.core.windows.net/<your-container>/<your-blob>" + sasSignature;
    
            InputStream inStream = new FileInputStream("<file-path>");
            BufferedInputStream bis = new BufferedInputStream(inStream);
            List<String> blockIds = new ArrayList<String>();
    
            int counter = 1;
            while (bis.available() > 0) {
                int blockSize = 4 * 1024 * 1024; // 4 MB;
                int bufferLength = bis.available() > blockSize ? blockSize : bis.available();
    
                byte[] buffer = new byte[bufferLength];
                bis.read(buffer, 0, buffer.length);
                String blockId = Base64.getEncoder().encodeToString(("Block-" + counter++).getBytes("UTF-8"));
                uploadHandler.UploadBlock(blobStorageEndpoint, buffer, blockId);
                blockIds.add(blockId);
            }
    
            uploadHandler.CommitBlockList(blobStorageEndpoint, blockIds);
    
            bis.close();
            inStream.close();
        }
    
        public void UploadBlock(String baseUri, byte[] blockContents, String blockId) throws IOException {
    
            OkHttpClient client = new OkHttpClient();
    
            MediaType mime = MediaType.parse("");
            RequestBody body = RequestBody.create(mime, blockContents);
    
            String uploadBlockUri = baseUri + "&comp=block&blockId=" + blockId;
    
            Request request = new Request.Builder()
                    .url(uploadBlockUri)
                    .put(body)
                    .addHeader("x-ms-version", "2015-12-11")
                    .addHeader("x-ms-blob-type", "BlockBlob")
                    .build();
    
            client.newCall(request).execute();
    
        }
    
        public void CommitBlockList(String baseUri, List<String> blockIds) throws IOException {
    
            OkHttpClient client = new OkHttpClient();
    
            StringBuilder blockIdsPayload = new StringBuilder();
            blockIdsPayload.append("<?xml version='1.0' ?><BlockList>");
            for (String blockId : blockIds) {
                blockIdsPayload.append("<Latest>").append(blockId).append("</Latest>");
            }
            blockIdsPayload.append("</BlockList>");
    
            String putBlockListUrl = baseUri + "&comp=blocklist";
            MediaType contentType = MediaType.parse("");
            RequestBody body = RequestBody.create(contentType, blockIdsPayload.toString());
    
            Request request = new Request.Builder()
                    .url(putBlockListUrl)
                    .put(body)
                    .addHeader("x-ms-version", "2015-12-11")
                    .build();
    
            client.newCall(request).execute();
        }