Reputation: 243
I'm writing an app which plays an mp3 file.
In Android this is straight forward:
Xamarin.Essentials.FilePicker
to pick the mp3 filepathI tried a similar approach for iOS:
Xamarin.Essentials.FilePicker
to pick the mp3 filepath (either from icloud or on phone)This works in the simulator but throws an exception when trying to create an AVAudioFile. (LibVlcSharp also fails when trying to load the filepath).
NSError err;
AVAudioFile file = new AVAudioFile(new NSUrl(audioUri, false), out err);
//err is null after this call throws an exception
Exception: "Could not initialize an instance of the type 'AVFoundation.AVAudioFile': the native 'initForReading:error:' method returned nil.\nIt is possible to ignore this condition by setting ObjCRuntime.Class.ThrowOnInitFailure to false."
(Setting ThrowOnInitFailure = false
doesn't help as file is still null).
I suspect it's a permissions issue, so I tried using the MPMediaPickerController:
MPMediaPickerController mp = new MPMediaPickerController();
mp.AllowsPickingMultipleItems = false;
mp.ShowsCloudItems = true;
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(mp, true, null);
with MPMediaLibraryAuthorizationStatus
set to Authorized
and the following set in info.plist:
<key>NSAppleMusicUsageDescription</key>
<string>Select a music file</string>
This code does nothing whatsoever.
How can I get this or the file picker method to work?
UPDATE
I've managed to get the MediaPicker working. Will update on that soon.
My next problem is I get an NSUrl
from the MediaPicker. If I pass this directly into the AVAudioEngine
, it plays fine.
But if I save the NSUrl
to a string for serialization purposes, and then try to recreate it with the following code, the same exception above occurs when trying to create 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);
Any ideas?
Upvotes: 0
Views: 203
Reputation: 243
Finally achieved playback. I will document below the major obstacles I encountered and how I resolved them, in case anyone finds this useful.
Displaying MPMediaPickerController
The code above didn't work because I was trying to launch it from a popup window and thus needed to find the popup's corresponding ViewController
instead of the RootViewController
I was using above.
This post had the solution: How to find current UIViewController in Xamarin
Serializing a NSUrl
In order to Serialize an MPMediaItem
you can't simply use the Url string. You need to use:
MPMediaItem.PersistentID
which is a ulong
.
To recreate a NSUrl
from the ulong
, you need to:
MPMediaItem
with that PersistentID
using MPMediaQuery
and MPMediaPropertyPredicate
MPMediaItem
's AssetURL
propertyPlaying audio but no sound comes solution
This one drove me crazy but turns out one of the phone's volume settings was preventing the sound emission.
This post and the following code solved the problem: Swift: Playing audio using AVPlayer - Audio is not playing, cannot hear audio
AVAudioSession.SharedInstance().SetCategory(AVAudioSession.CategoryPlayback);
AVAudioSession.SharedInstance().SetActive(true);
Thanks everyone for your help on this. It was much appreciated. Happy coding!
Upvotes: 0
Reputation: 8260
You could call NSUrl.StartAccessingSecurityScopedResource Method
and check the return value:
NSUrl url = NSUrl.FromString(audioUri);
var securityEnabled = url.StartAccessingSecurityScopedResource();
For more info, you could refer to startAccessingSecurityScopedResource
============= Origin answer======
You may try using AVPlayer.
AVPlayerItem aVPlayerItem = new AVPlayerItem(new NSUrl(audioUri));
AVPlayer aVPlayer = new AVPlayer(aVPlayerItem);
aVPlayer.Play();
also add this in info.plist if you load from a http source
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Hope it works.
Upvotes: 0