Отправка больших файлов в службы мультимедиа Azure в Xamarin

Я пытаюсь загрузить файл .mp4, выбранный с устройства iOS или Android пользователя, в свою учетную запись Azure Media Services.

Этот код работает для небольших файлов (менее ~ 95 МБ):

public static async Task<string> UploadBlob(string blobContainerSasUri, string blobName, byte[] blobContent, string path)
    {
        string responseString;
        int contentLength = blobContent.Length;
        string queryString = (new Uri(blobContainerSasUri)).Query;
        string blobContainerUri = blobContainerSasUri.Split('?')[0];
        string requestUri = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}/{1}{2}", blobContainerUri, blobName, queryString);

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
        request.Method = "PUT";
        request.AllowWriteStreamBuffering = false;
        request.Headers.Add("x-ms-blob-type", "BlockBlob");
        request.ContentLength = contentLength;
        request.Timeout = Int32.MaxValue;
        request.KeepAlive = true;

        int bufferLength = 1048576; //upload 1MB at time, useful for a simple progress bar.

        Stream requestStream = request.GetRequestStream();
        requestStream.WriteTimeout = Int32.MaxValue;

        ProgressViewModel progressViewModel = App.Locator.GetProgressBar(App.Locator.MainViewModel.currentModuleItemId);
        MyVideosPage myVideosPage = App.Locator.GetVideosPage(App.Locator.MainViewModel.currentModuleItemId);

        FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
        int nRead = 0;
        int currentPos = 0;
        while ((nRead = fileStream.Read(blobContent, currentPos, bufferLength)) > 0)
        {

            await requestStream.WriteAsync(blobContent, currentPos, nRead);
            currentPos += nRead;

        }
        fileStream.Close();
        requestStream.Close();

        HttpWebResponse objHttpWebResponse = null;
        try
        {
            // this is where it fails for large files
            objHttpWebResponse = (HttpWebResponse)request.GetResponse();

            Stream responseStream = objHttpWebResponse.GetResponseStream();
            StreamReader stream = new StreamReader(responseStream);

            responseString = stream.ReadToEnd();                       
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            if (objHttpWebResponse != null)
                objHttpWebResponse.Close();
        }
        return responseString;
    }

После вызова этой строки возникает исключение:

(HttpWebResponse)request.GetResponse(); 

Сообщение об исключении: «Тело запроса слишком велико и превышает максимально допустимый предел». Исключение StatusCode — «RequestEntityTooLarge».

Как я могу загрузить большие файлы? Это проблема с HttpWebRequest или Azure Media Services?


person adhdj    schedule 15.08.2018    source источник
comment
Почему бы вам не использовать Azure SDK, который может справиться с большей частью этого за вас, написав CloudBlobBlocks?   -  person Cheesebaron    schedule 16.08.2018


Ответы (1)


Служба хранилища Azure поддерживает одну загрузку снимков (API PutBlob ) до 256 МБ, если вы используете новые версии REST API. Но поскольку вы не указываете версию REST API, вы по умолчанию используете очень старую версию, в которой максимальный поддерживаемый размер одной загрузки составляет 100 МБ.

Используйте заголовок x-ms-version: 2018-03-28, чтобы иметь возможность загружать до 256 МБ в одном HTTP-запросе.

Если вам приходится иметь дело с большими файлами, вам нужно будет использовать блокировку и фиксацию загрузки. Вам нужно будет использовать API PutBlock для промежуточных блоков. из исходного файла. Блоки могут быть до 100 МБ каждый. Затем вам нужно зафиксировать все блоки с помощью PutBlockList API. . Если вам не нужно разбираться с этой логикой самостоятельно, просто используйте SDK Azure Storage для .NET. (поддерживает Xamarin) и используйте метод uploadFromFile. Он простой и упругий.

person sguler    schedule 18.08.2018