【问题标题】:How to get videos with PHVideo from iCloud on Xamarin iOS?如何在 Xamarin iOS 上从 iCloud 获取带有 PHVideo 的视频?
【发布时间】:2020-12-17 07:32:52
【问题描述】:

我在 Xamarin.Forms 应用程序上使用 DependencyService 实现了多媒体选择器(用于图像和视频)。我对 iCloud 视频有疑问。 当我选择 icloud 上的视频时,我无法获取它。

我的实现是:

async void FinishedPickingAssets(object sender, MultiAssetEventArgs args)
         {
             IList<MediaFile> results = new List<MediaFile>();
             TaskCompletionSource<IList<MediaFile>> tcs = new TaskCompletionSource<IList<MediaFile>>();
    
             try 
             { 
                 var options = new PHImageRequestOptions()
                 {
                     NetworkAccessAllowed = true
                 };
    
                 options.Synchronous = false;
                 options.ResizeMode = PHImageRequestOptionsResizeMode.Fast;
                 options.DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat;
                 bool completed = false;
                 for (var i = 0; i < args.Assets.Length; i++)
                 {
                     var asset = args.Assets[i];
    
                     string fileName = string.Empty;
                     if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0))
                     {
                         fileName = PHAssetResource.GetAssetResources(asset).FirstOrDefault().OriginalFilename;
                         fileName = Path.GetFileNameWithoutExtension(fileName) + "(" + i.ToString() + ")" + Path.GetExtension(fileName);
                     }
    
                     switch (asset.MediaType)
                     {
                         case PHAssetMediaType.Video:
                         {
                                 var vOptions = new PHVideoRequestOptions();
                                 vOptions.NetworkAccessAllowed = true;
                                 vOptions.Version = PHVideoRequestOptionsVersion.Original;
                                 vOptions.DeliveryMode = PHVideoRequestOptionsDeliveryMode.Automatic;
                                 string videoUrl = "";
    
                                 PHImageManager.DefaultManager.RequestAvAsset(asset, vOptions, (avAsset, audioMix, vInfo) => 
                                 {
                                     DispatchQueue.MainQueue.DispatchAsync(() => {
    
                                         var error = vInfo.ObjectForKey(PHImageKeys.Error);
                                            
                                         if (avAsset != null)
                                         {
                                             videoUrl = ((AVFoundation.AVUrlAsset)avAsset).Url.Path;
                                         }
                                         var meFile = new MediaFile()
                                         {
                                             FileName = fileName,
                                             FilePath = videoUrl
                                         };
    
                                         using (Stream source = File.OpenRead(videoUrl))
                                         {
                                             meFile.FileSize = source.Length;
                                         }
                                         results.Add(meFile);
                                         OnMediaPicked?.Invoke(this, meFile);
    
                                         if (args.Assets.Length == results.Count && !completed)
                                         {
                                             completed = true;
                                             tcs.TrySetResult(results);
                                         }
                                     });
                                 });
                         }
                         break;
                     default:
                         PHImageManager.DefaultManager.RequestImageData(asset, options, (data, dataUti, orientation, info) =>
                         {
    
                             string path = FileHelper.GetOutputPath(MediaFileType.Image, TemporalDirectoryName, fileName);
    
                             if (!File.Exists(path))
                             {
                                 Debug.WriteLine(dataUti);
                                 var imageData = data;
                                 imageData?.Save(path, true);
                             }
    
                             var meFile = new MediaFile()
                             {
                                 FileName = fileName,
                                 FilePath = path,
                                 FileSize = File.ReadAllBytes(path).Length
                             };
    
                             results.Add(meFile);
                             OnMediaPicked?.Invoke(this, meFile);
                             if (args.Assets.Length == results.Count && !completed)
                             {
                                 completed = true;
                                 tcs.TrySetResult(results);
                             }
    
                         });
                         break;
                     }
                 }
             }
             catch
             {
                 tcs.TrySetResult(results);
    
                 string automationId = "UnexpectedSituationMessage";
                 GeneralOperations.OpenToastMessage("Unexpected Situation", automationId);
             }
    
             mediaPickTcs?.TrySetResult(await tcs.Task);
         }

当我尝试选择 iCloud 对象时,我收到以下错误:

如何从 icloud 中拍摄多选视频?

提前谢谢你。

【问题讨论】:

  • 1005 错误意味着您被拒绝访问。这可能有多种原因。 1. 网站管理员屏蔽了整个IP地址范围。 2.您使用的VPN服务被网站屏蔽。 3. Cloudflare 或其他类似服务因违反其条款或任何可疑行为而阻止了您的 IP 地址。尝试使用 VPN 或代理服务器更改您的 IP 地址或卸载/禁用您的 VPN 服务。然后再试一次。
  • 感谢您的回复。但我不确定我的问题的原因是这个。因为在第一次尝试时我得到了错误,但开始将视频拉到手机上。将视频拉到手机后,我可以第二次获取它。此外,我可以使用相同的 IP 地址手动拉取。
  • 您的权利设置是否正确?您是否在构建设置中设置了权利?
  • 是的,我正确设置了权利。其实我找到了解决办法。当手机内存不足时,视频存储在 iCloud 中(仅显示视频缩略图)。我的问题是当我尝试使用选择器选择视频时,它找不到视频,因为视频在 icloud 中。如果由于文件在 iCloud 中而无法访问该文件,我发现可以使用以下代码捕获错误: var error = vInfo.ObjectForKey(PHImageKeys.Error);如果错误不为空,我会向客户端显示一条消息(因为文件在 icloud 中,首先您必须将其下载到手机)。

标签: xamarin.forms xamarin.ios icloud multimedia phimagemanager


【解决方案1】:

首先确保您已开启 iCloud 照片。


 1. Go to Settings > [your name] > iCloud.
 2. Tap Photos.
 3. If you need to, tap to turn on iCloud Photos.

然后检查视频和照片是否显示在您设备上的 Photo App 中。

对于多项选择和多项自定义,您可以从 nuget 安装插件 GMImagePicker.Xamarin

【讨论】:

  • 嗨,我已经在使用 GMImagePicker。我的共享代码 sn-p 是它的 FinishedPickingAssets 方法。如下所示:var picker = new GMImagePickerController (); picker.FinishedPickingAssets += FinishedPickingAssets; await PresentViewControllerAsync (picker, true); 我无法使用 GMImagePicker 在 iCloud 中获取视频的路径和大小信息。我检查了 iCloud 照片是否已打开。但我意识到我第一次收到物品时遇到了麻烦。我第一次收到错误,但正在拉视频。
  • 当我收到错误后等待时,视频从 iCloud 中提取。这就是为什么我第二次可以得到它。但我想第一次等到将视频拉到手机上。
  • 能否将样本分享到 github,以便我在自己这边进行测试?
  • 这是一个大型定制项目的一部分。这就是为什么我现在不能分享。但我会尝试做演示项目。我会分享。谢谢。
  • 好的,上传后我会尽快检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-05
  • 2015-07-26
  • 2018-09-13
  • 1970-01-01
  • 2023-03-27
  • 2016-07-04
  • 2015-02-28
相关资源
最近更新 更多