我可以使用从 FilePicker 导入的文件作为 MediaPlayer 源吗

Posted

技术标签:

【中文标题】我可以使用从 FilePicker 导入的文件作为 MediaPlayer 源吗【英文标题】:Can I use an imported file from FilePicker as a MediaPlayer source 【发布时间】:2020-09-06 05:26:28 【问题描述】:

我正在开发一个使用 MediaPlayer 播放音频的应用程序。当要播放的音频文件已经在 Assets 文件夹中时,它可以工作。但是,我的目标是使用FilePicker 插件让用户从他们的设备中选择要播放的文件。

从 FilePicker,我可以得到一个路径(这似乎是一个 Uri),比如 content://com.android.providers.downloads.documents/document/6531。但是,尝试通过此路径(作为字符串和 Uri)使用 MediaPlayer 会导致 Java.IO.IOException: 'setDataSource failed.: status=0x80000000'

我假设不可能在 Assets 文件夹之外的文件上使用 MediaPlayer。所以我的问题变成了有没有办法在提供路径时将资产添加到项目的资产文件夹中?还是我错了,有没有办法在给定 Uri 的情况下使用 MediaPlayer?

这是处理导入的按钮的代码:

Button browse = FindViewById<Button>(Resource.Id.browse);
browse.Click += async delegate

   var fileImp = await CrossFilePicker.Current.PickFile();
   if (fileImp != null)
   
      path = fileImp.FilePath;
   
;

在将路径发送到另一个类之后:

public void load()

   player = new MediaPlayer();

   player.SetDataSource(path);

   player.Prepare();

另一种设置数据源的尝试也不起作用,并得到相同的错误:

public void load()

   player = new MediaPlayer();

   Android.Net.Uri uri = Android.Net.Uri.Parse(songFileString);

   player.SetDataSource(Application.Context, uri);

   player.Prepare();

感谢任何帮助,谢谢。

【问题讨论】:

现在可以用了吗? @LeoZhu-MSFT 我还没有时间完全实现你的解决方案的后续,但是错误仍然存​​在,是的。我认为这与 Xamarin 不支持从 Assets 文件夹外部处理 Assets 的事实有关。相反,我的下一步是尝试让程序在播放之前将所选文件添加到 Assets 文件夹中。 好的,有任何更新请告诉我 【参考方案1】:

content://com.android.providers.downloads.documents/document/6531

您可以尝试将 uri 转换为文件路径。

string filePath = null;
Android.Net.Uri uri = Android.Net.Uri.Parse(path);
if (DocumentsContract.IsDocumentUri(this, uri))

    string docId = DocumentsContract.GetDocumentId(uri);
    if (uri.Authority.Equals("com.android.providers.media.documents"))
    
        string id = docId.Split(":")[1];
        string selection = MediaStore.Video.Media.InterfaceConsts.Id + "=" + id;
        filePath = getfilePath(MediaStore.Video.Media.ExternalContentUri, selection);
    
    else if (uri.Authority.Equals("com.android.providers.downloads.documents"))
    
        Android.Net.Uri contentUri = ContentUris.WithAppendedId(Android.Net.Uri.Parse("content://downloads/public_downloads"), long.Parse(docId));
        filePath = getfilePath(contentUri, null);
    

else if (uri.Scheme.Equals("content", StringComparison.OrdinalIgnoreCase))

    filePath = getfilePath(uri, null);

else if (uri.Scheme.Equals("file", StringComparison.OrdinalIgnoreCase))

    filePath = uri.Path;

getfilePath方法:

private string getfilePath(Android.Net.Uri uri, string selection)

  string path = null;
  var cursor = ContentResolver.Query(uri, null, selection, null, null);
  if (cursor != null)
  
    if (cursor.MoveToFirst())
    
        path = cursor.GetString(cursor.GetColumnIndex(MediaStore.Video.Media.InterfaceConsts.Data));
    
    cursor.Close();
  
  return path;

【讨论】:

感谢您的回答。不幸的是,在 getFilePath 方法中,我收到来自var cursor 行的错误Java.Lang.IllegalArgumentException: 'Unknown URI: content://downloads/public_downloads/6531'。经过一些研究,我了解到这可能是因为下载目录的名称,但是我尝试将“public_downloads”更改为“my_downloads”,但它仍然不起作用,因为 filePath 会返回为空。 @mayomatsuda 尝试使用getDataColumn of ths FileUtils,将其转换为C#

以上是关于我可以使用从 FilePicker 导入的文件作为 MediaPlayer 源吗的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin FilePicker 阻止 UserDialog

filepicker.io 的 Facebook 权限

如何在没有 FilePicker 的情况下在固定位置保存和加载 InkCanvas gif 文件

FilePicker 通过沉浸式 Unity 应用程序挂在 HoloLens 上

FilePicker 以字符串形式返回名称和路径

HTML filepicker multi - 获取正在使用的文件