AKAudioPlayer and Music Library assets

641 views
Skip to first unread message

Christopher Pearson

unread,
May 10, 2016, 6:26:45 PM5/10/16
to AudioKit Users Group
I'm trying to use AKAudioPlayer to loop a user selectable audio track in my app.

I'm using MPMediaPickerControllerDelegate to allow the user to select a track.  This all works and I get a MPMediaItem back from the system controller.

I then pass the items .assetURL?.absoluteString to a new instance of AKAudioPlayer where it immediately blows up

fatal error: 'try!' expression unexpectedly raised an error: Error Domain=com.apple.coreaudio.avfaudio Code=2003334207 "(null)" UserInfo={failed call=ExtAudioFileOpenURL((CFURLRef)fileURL, &_extAudioFile)}: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-703.0.18.8/src/swift/stdlib/public/core/ErrorType.swift, line 54


The line that's crashing is in AKAudioPlayer.init(_ file: String) on the line:

audioFile = try! AVAudioFile(forReading: url)


Am I doing this right? I get an odd URL for the file which might be the issue?  It looks like this: ipod-library://item/item.mp3?id=1259119331107901091 though it may be m4a etc according to the actual file type.


I cannot add the asset to the app for copyright reasons and it also allows some amount of user choice which will be of benefit in this case.


I'm currently using the v3.1.2 as my AK build, compiled along with my app, though it also crashes with the same issue on develop.


ps: been away for a while but my app's had great reception within the Stormtrooper community, something that wouldn't have been possible without AudioKit.

Aurelius Prochazka Ph.D.

unread,
May 11, 2016, 12:24:41 PM5/11/16
to AudioKit Users Group
For AK2 we had an example project that used the media library and I remember someone on this list was going to try to port it to AK3, but I guess it never happened.  This will come up in another project I am working too, so it's on our list.  If you want to make a Github issue for "Create an example using the ipod library media picker for source audio" that would make sure to keep it on our radars too.

Glad to hear that your app has been a success!

Aure

Christopher Pearson

unread,
May 13, 2016, 10:29:44 AM5/13/16
to AudioKit Users Group
Ask and you shall receive:


Thanks for the reply.

Chris.

Dale A. Jackson

unread,
Jun 24, 2016, 9:41:44 PM6/24/16
to AudioKit Users Group
I dug into this a little more after running into similar issues and discovered that it blows up because the NSURL created in AKAudioPlayer's reloadFile() has an odd extra set of characters on the end (something along the lines of --ie:// if I remember right).  The debugger actually reports it as a CFURL in memory, so maybe there's a bug in the toll-free bridging that's occurring?  I'm not sure on the why, BUT...

I fixed this by just having the AKAudioPlayer init accept an NSURL instead, passing the .assetURL, and saving it into a var in AKAudioPlayer that reloadFile uses to init the AVAudioFile.  Worked like a charm, and I haven't had any issues yet.  No exporting song to local asset library necessary (that is what the SongProcessor example is doing right?).

Other than the fact that this breaks the playgrounds relying on it accepting a String (which should be easy to fix, though I haven't tried yet), are there any functional consequences or limitations of implementing AKAudioPlayer this way?  I've only just discovered AudioKit a few days ago, and haven't had a chance to completely pour over all the source code to see where it might break. Plus I'm not at all familiar with the intricacies of Apple's audio frameworks (though AudioKit has taught me A LOT, so thanks for writing such readable code!).

Aurelius Prochazka Ph.D.

unread,
Jun 24, 2016, 9:44:53 PM6/24/16
to AudioKit Users Group
Oh wow, wouldn't that be a great improvement to the SongProcessor example!  I think we're doing it that way because it was necessary in AudioKit2, but with AK3 we're a lot closer to the metal.  Laurent, Brandon, and I are really pushing on improving AKAudioPlayer so I am sure they'll be interested in hearing this as well.  If you want you can add it and make a pull request, but I am sure one of us will be all over this over the weekend!

Aure

Dale A. Jackson

unread,
Jun 24, 2016, 10:31:30 PM6/24/16
to AudioKit Users Group
Glad I could help!  I work the entire weekend, so I won't have a chance to put together a pull request that fixes all the playgrounds (and anything else I notice) until Monday night / Tuesday morning.  If I don't see anything on the repository related to this by then, I'll submit one.

laurent veliscek

unread,
Jun 25, 2016, 5:26:55 AM6/25/16
to AudioKit Users Group
Hi Dale !

Did you ckeck AKAudioFile and AKAudioPlayer in the develop branch ?

AKAudioPlayer cannot be initialized any more using a string file path. We now provide an AKAudioFile class (that inherits from AVAudioFile).

The idea behind was to make it simpler to load/create AVAudioFiles and to embed some utilities.
Check the playground AKAudioFile page.

AKAudioFile made AKAudioPlayer safer and can help to avoid some crashes at run-time.
AKAudioPlayer has been fixed. (master branch version has serious bugs when using "pause", and played completion callback doesn't work as expected).

There's an AKTapeRecorder page that combines an AKNodeRecorder with an AKAudioPlayer and seems to work pretty fine.

If you plan to commit any change to AKAudioPlayer or AKAudioFile, you can experiment using their playground pages so you'll be sure that nothing is broken.


Best regards,

:-)

Laurent.




Dale A. Jackson

unread,
Jun 25, 2016, 5:27:15 AM6/25/16
to AudioKit Users Group
Oh I forgot to mention: 

It should be noted that for full length tracks the app's memory footprint will balloon way up due to loading the entire file in that PCM buffer. 5 MB to 200 MB on some of the longer songs.  I actually laughed when I saw the number jump.  Hooray for uncompressed audio!

Calling .scheduleFile() instead of .scheduleBuffer() in AKAudioPlayer is a solution, but also removes the option to loop. Couldn't figure out an easy way to loop that doesn't involve a full buffer of the file. For now I just have an if-else in place that calls scheduleBuffer if the looping var is true; scheduleFile otherwise. 

laurent veliscek

unread,
Jun 25, 2016, 5:44:41 AM6/25/16
to AudioKit Users Group
You should really have a look at the develop branch of audiokit.

Master branch version of AKAudioPlayer is really obsolete now, and most issues you're facing now have been fixed.
(I don't want to let you loose your time fixing things that has been already fixed...)

I tried to set shorter buffer for AKAudioPlayer, but I failed to make it work properly.

May be you can investigate for a better implementation for AKAudioPlayer, but please start from the latest version !...

Laurent.

Dale A. Jackson

unread,
Jun 25, 2016, 5:51:41 AM6/25/16
to AudioKit Users Group
Welp, now I know to check there as well =) I didn't know the develop branch would have such drastic improvements. Also yea, I sent that second reply before your response was posted.

Looks excellent, much better than my hacked up version.  Thanks for letting me know!

Aurelius Prochazka Ph.D.

unread,
Jun 25, 2016, 6:32:25 AM6/25/16
to AudioKit Users Group
Yeah, develop is far ahead and AudioKit 3.2 will probably be launched next week sometime.  I wanted the audio playing API to settle down a bit before release it onto master, plus there a few other important updates I'll probably finish this weekend.

Aure
Reply all
Reply to author
Forward
0 new messages