3

(Note: The code here is Monotouch/C#, however Objective-C Answers are welcome!)

Im using AVPlayer as my app plays iPod library files as well as local mp3/m4a files. The playback of iPod library files is fine, however I cannot seem to get the AVPlayer to play local mp3 files.

For example, this code works:

NSUrl url;
AVAudioPlayer player2;

url = NSUrl.FromFilename(Path.Combine(Constants.TrackCacheLocation , songPath));

/* The url variable has the value file://localhost/private/var/mobile/Applications/B1ED2576-4398-43F3-8573-2FA3A0342265/Documents/Cache/Remote/dcaad4ff-452e-4d91-8788-c018e6b286f2.mp3 */

player2 = AVAudioPlayer.FromUrl(url);
player2.Play();

The above works fine, note that it's using AVAudioPlayer.

This doesn't (using AVPlayer):

NSUrl url;
AVPlayer player2;

url = NSUrl.FromFilename(Path.Combine(Constants.TrackCacheLocation , songPath));

/* The url variable has the value file://localhost/private/var/mobile/Applications/B1ED2576-4398-43F3-8573-2FA3A0342265/Documents/Cache/Remote/dcaad4ff-452e-4d91-8788-c018e6b286f2.mp3 */

player2 = AVPlayer.FromUrl(url);
player2.Play();

Creating an NSUrl from a local or remote web server also works (with AVPlayer), eg: http://10.0.0.1/testing/test.mp3 delays about a second or two while loading, then starts to play fine. I have a feeling im not creating my NSUrl correctly (even though it works fine for AVAudioPlayer). Any one any have ideas what could be going wrong?

Also, if I check the CurrentItem.Status of the AVPlayer it remains Unknown, it never changes to ReadyToPlay

Dermot
  • 1,713
  • 2
  • 18
  • 29

1 Answers1

1

Many API that uses NSUrl or NSUrlRequest parameters are async by design and will have issues (or even crash) if defined as a local variable (e.g. that will be collected when your method returns when still needed by the native code).

You code above does not supply enough information about where they are created. If you're using local variables then try to promote them as fields and ensure they will exists (e.g. don't re-assign them) until you don't need the AVPlayer anymore.

Community
  • 1
  • 1
poupou
  • 43,413
  • 6
  • 77
  • 174
  • The avplayer is created at a class level. As its a music playing app, the class stays in scope permanently. The nsurl is being declared within the method. Note that the avplayer is working fine with zero problems for iTunes library files and remote urls, it's just local file system files refuse to play – Dermot Feb 29 '12 at 14:40
  • It could be unrelated but *please try it* since local and remote access to an URL will use different code paths and will behave differently (only testing it, pretty easy, can tell you for sure). – poupou Feb 29 '12 at 14:49
  • Just tested this will all variables as class level variables, still no luck getting it working. The Track is definitely valid, as it plays with AVAudioPlayer (suggesting the url is valid too) and also exports via Xcode and plays in iTunes fine. – Dermot Mar 01 '12 at 07:14
  • I sugest you to fill a bug report at http://bugzilla.xamarin.com and attach a sample that we can use to reproduce your issue. – poupou Mar 01 '12 at 12:47
  • For a workaround, I swap in and out AVPlayer and AVAudioPlayer depending on where I am playing music from. It works fairly cleanly. I will get a sample app together and submit a bug report though, as it would be nice to use AVPlayer for all audio. – Dermot Mar 01 '12 at 23:10
  • This is now working with zero changes (other than passing the url to AVPlayer now instead of AVAudioPlayer). I guess it was fixed in some release along the way. – Dermot Aug 27 '12 at 05:49
  • I have same problem with Objective-C, so I think this is not a Monotouch issue. I think the problem here is related to streaming, because AVPlayer is for streaming while AVAudioPlayer is for local reproduction. – Borzh Feb 03 '15 at 20:49