如何在Xamarin Forms iOS上从文件系统播放mp3?

gpnt7bae  于 2023-06-25  发布在  iOS
关注(0)|答案(2)|浏览(130)

我正在写一个可以播放mp3文件的应用程序。
在Android中,这是直接的:
1.使用Xamarin.Essentials.FilePicker选择mp3文件路径
1.使用Android.MediaPlayer播放mp3文件路径
我在iOS上尝试了类似的方法:
1.使用Xamarin.Essentials.FilePicker选择mp3文件路径(从iCloud或手机上)
1.使用AVAudioEngine播放mp3文件路径
这在模拟器中起作用,但在尝试创建AVAudioFile时会引发异常。(LibVlcSharp在尝试加载文件路径时也会失败)。

NSError err;
AVAudioFile file = new AVAudioFile(new NSUrl(audioUri, false), out err);
//err is null after this call throws an exception

异常:“无法初始化类型“AVFoundation. AVAudioFile”的示例:本机'initForReading:error:'方法返回nil。\n可以通过将ObjCRuntime.Class.ThrowOnInitFailure设置为false来忽略此条件。”
(设置ThrowOnInitFailure = false没有帮助,因为文件仍然为空)。
我怀疑是权限问题,所以尝试使用MPMediaPickerController

MPMediaPickerController mp = new MPMediaPickerController();
mp.AllowsPickingMultipleItems = false;
mp.ShowsCloudItems = true;
  UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(mp, true, null);

MPMediaLibraryAuthorizationStatus设置为Authorized,并在info.plist中设置以下内容:

<key>NSAppleMusicUsageDescription</key>
<string>Select a music file</string>

这个代码什么都不做。
如何让这个方法或文件选择器方法工作?

更新

我已经设法让MediaPicker工作。很快就会更新。
我的下一个问题是我从MediaPicker得到一个NSUrl。如果我把它直接传递到AVAudioEngine,它就能正常运行。
但是,如果我将NSUrl保存为一个字符串以用于序列化目的,然后尝试使用以下代码重新创建它,则在尝试创建AVAudioFile时会出现上述相同的异常。

//url1 works fine
NSUrl url1 = mediaItemCollection.Items[0].AssetURL;
AVAudioFile file = new AVAudioFile(url1, out err);
        
//url2 throws the same exception above
string str = mediaItemCollection.Items[0].AssetURL.AbsoluteString;
NSUrl url2 = new NSUrl(str, false) 
AVAudioFile file = new AVAudioFile(url2, out err);

有什么想法吗

nkhmeac6

nkhmeac61#

你可以调用NSUrl.StartAccessingSecurityScopedResource Method并检查返回值:

NSUrl url = NSUrl.FromString(audioUri);
var securityEnabled = url.StartAccessingSecurityScopedResource();

有关详细信息,请参阅startAccessingSecurityScopedResource
================原点答案====
您可以尝试使用AVPlayer。

AVPlayerItem aVPlayerItem = new AVPlayerItem(new NSUrl(audioUri));
AVPlayer aVPlayer = new AVPlayer(aVPlayerItem);
aVPlayer.Play();

如果从http源加载,也要在info.plist中添加这个

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>

希望能成功。

smdnsysy

smdnsysy2#

终于实现了回放。我将在下面记录我遇到的主要障碍以及我是如何解决它们的,以防有人发现这很有用。

显示MPMediaPickerController

上面的代码不起作用,因为我试图从弹出窗口启动它,因此需要找到弹出窗口对应的ViewController,而不是我上面使用的RootViewController
这篇文章有解决方案:How to find current UIViewController in Xamarin

序列化NSUrl

为了序列化一个MPMediaItem,你不能简单地使用URL字符串。您需要用途:
MPMediaItem.PersistentIDulong
要从ulong重新创建NSUrl,您需要:
1.使用MPMediaQueryMPMediaPropertyPredicate再次查询介质库中的MPMediaItemPersistentID
1.使用查询结果MPMediaItemAssetURL属性

播放音频但没有声音的解决方案

这一个让我疯狂,但原来手机的音量设置之一是防止声音发射。
这篇文章和下面的代码解决了这个问题:Swift: Playing audio using AVPlayer - Audio is not playing, cannot hear audio

AVAudioSession.SharedInstance().SetCategory(AVAudioSession.CategoryPlayback);
AVAudioSession.SharedInstance().SetActive(true);

谢谢大家在这方面的帮助。非常感谢。快乐编码!

相关问题