【问题标题】:Upload a long video to web API server from xamarin从 xamarin 将长视频上传到 Web API 服务器
【发布时间】:2018-02-05 07:33:01
【问题描述】:

我正在拍摄一个时长为 5 分钟的视频并尝试将其上传到 API,但 API 的响应是错误的,并且该视频不存在于数据库中。我将小型视频上传到 API。

我发现视频的大小很大,上传需要更多时间,并且 API 在一段时间后超时。如何在不减少内容的情况下减小视频的大小,或在几秒钟内将长时间的视频上传到 API。

请帮帮我..

这是我的代码

private async void TakeVideo_Clicked(object sender, EventArgs e)
{
    if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakeVideoSupported)
    {
        await DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
        return;
    }

    var _file = await CrossMedia.Current.TakeVideoAsync(new Plugin.Media.Abstractions.StoreVideoOptions
    {
        Name = "video.mp4",
        Directory = "Videos",
    });

    if (_file == null)
    {
        return;
    }
    else
    {
        _path = _file.Path;

        using (var _streamReader = new StreamReader(_file.GetStream()))
        {
            var _array = default(byte[]);                 

            using (MemoryStream _memoryStream = new MemoryStream())
            {
                _streamReader.BaseStream.CopyTo(_memoryStream);

                _array = _memoryStream.ToArray();                        

                if (await DisplayAlert(App._confirmation, "Do you want to save the video?", "Yes", "Cancel"))
                {
                    FileUploadAsync(_array, false);
                    activity_Indicator.IsVisible = true;
                    activity_Indicator.IsRunning = true;
                }
                else
                {
                    return;
                }
            }
        }
    }
}

public async void FileUploadAsync(byte[] fileUpload, bool IsImage)
    {
        APIResponse _response = await App.DataManager.UpdateFilesAsync(ID, fileUpload, IsImage);

        if (_response != null)
        {
            activity_Indicator.IsRunning = false;

            if (IsImage)
            {
                DependencyService.Get<IAlertPlayer>().AlertMessege("Image upload successfully");
            }
            else
            {
                DependencyService.Get<IAlertPlayer>().AlertMessege("Video upload successfully");
            }
        }
        else
        {
            DisplayAlertMessage();
        }
    }      

  public async Task<APIResponse>UpdateFilesAsync(int id,byte[] file,bool IsImage)
    {
        Url _url = new Url(BaseURL).AppendPathSegment("sample/UploadFiles");

        _url.QueryParams["ID"] = id;

        return await Service.POSTFILE<APIResponse>(_url, file,IsImage);
    }

这是我的 POST 方法

public async Task<T> POSTFILE<T>(Url url, byte[] uploadFile, bool IsImage)
    {
        try
        {
            using (MultipartFormDataContent content = new MultipartFormDataContent())
            {
                ByteArrayContent filecontent = new ByteArrayContent(uploadFile);

                if (IsImage)
                {
                    filecontent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
                    {
                        FileName = Guid.NewGuid().ToString() + ".png"
                    };
                }
                else
                {
                    filecontent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
                    {
                        FileName = Guid.NewGuid().ToString() + ".mp4"
                    };
                }

                content.Add(filecontent);

                using (HttpResponseMessage response = await Client.PostAsync(url, content))
                {
                    string result = await response.Content.ReadAsStringAsync();
                    return JsonConvert.DeserializeObject<T>(result);
                }
            }
        }
        catch (Exception ex)
        {

        }

        return default(T);
    }
}

【问题讨论】:

标签: c# xaml xamarin.forms xamarin.android


【解决方案1】:

这就是我在 Xamarin.iOS 上使用视频压缩的方法。你可以把它变成一个服务,然后根据平台实现适当的压缩逻辑。最后,如果您使用 IIS,请确保增加 视频上传限制

        var asset = AVAsset.FromUrl(NSUrl.FromFilename(path));
        AVAssetExportSession exportSession = new AVAssetExportSession(asset, AVAssetExportSessionPreset.HighestQuality);

        exportSession.OutputUrl = NSUrl.FromFilename(pathService.GetCompressedPath());
        exportSession.OutputFileType = AVFileType.Mpeg4;
        exportSession.ShouldOptimizeForNetworkUse = true;

        await exportSession.ExportTaskAsync(); //This can cause an error so check the status

        Stream exportStream = File.OpenRead(path);

        return exportStream;

Android 实现

        //create File from string.
        var file = new Java.IO.File(path);
        var outputFile = new Java.IO.File(pathService.GetCompressedPath());

        await Transcoder.For720pFormat().ConvertAsync(file, outputFile, null);

        Stream exportStream = File.OpenRead(outputFile.Path);

        System.Diagnostics.Debug.WriteLine("Stream read from file");

        return exportStream;

【讨论】:

  • 安卓没有
  • 不,我没有找到解决方案
  • @AswathyKR 我用我的 Android 实现更新了帖子
  • @sedders123 从哪里可以得到转码器,pathService.GetCompressedPath() 的 pathService 是什么?
【解决方案2】:

很遗憾,没有针对视频压缩的跨平台解决方案,因此您必须以特定于平台的方式实现此压缩。如果您搜索这些,每个平台都应该有这样的解决方案。

或者,您可以将HttpClient.Timeout 调整为更大的值(默认为 100 秒),以便在文件很大时上传不会超时。当然,价值取决于您的要求。您甚至可以将其设置为几乎无限 (TimeSpan.MaxValue),但这样您就有可能创建永无止境的请求,并且您必须使用 CancellationTokenSource 添加某种手动取消。

【讨论】:

  • 有什么办法可以减少字节数组而不丢失其内容
  • 不,不幸的是不是,你只能通过某种压缩来减少它(有一些可用的压缩算法),但是当数据是二进制并且你无论如何都需要时压缩不是很有效转移一切
  • 问题是如果你想传输一个视频,减少字节数组必然意味着丢失它的内容,除非你使用无损压缩来做到这一点
  • @AswathyKR 我已经在我的项目中解决了这个问题。我将使用一些示例代码来更新它,这些示例代码可能会有所帮助,但稍后会
  • @KING 你能分享一下代码吗,现在对我来说很紧急
猜你喜欢
  • 2011-06-28
  • 2013-03-14
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多