description
Experiencing the JSON.stringify on a media item returns "{}" instead of a real stringified output that I can parse.
var win = Ti.UI.createWindow({
backgroundColor : '#fff'
});
var btn = Ti.UI.createButton({
title : 'Trigger'
});
btn.addEventListener('click', function() {
Titanium.Media.openMusicLibrary({
allowMultipleSelections : false,
mediaTypes : Titanium.Media.MUSIC_MEDIA_TYPE_MUSIC | Titanium.Media.MUSIC_MEDIA_TYPE_ANY_AUDIO,
success : function(event) {
// called when media returned from the MusicLibrary
alert("Results: " + JSON.stringify(event.items[0]));
},
cancel : function() {
alert("Aborting ");
},
error : function(error) {
// called when there's an error
var a = Titanium.UI.createAlertDialog({
title : 'Music Library'
});
if (error.code == Titanium.Media.NO_MUSIC_PLAYER) {
a.setMessage('Please run this test on device.');
} else {
a.setMessage('Unexpected error: ' + error.code);
}
a.show();
}
});
});
win.add(btn);
win.open();
Thanks
Just check the docs on the available methods. Media items cannot automatically be stringified. Also ensure to run on device and include the
NSAppleMusicUsageDescription
key.Example of stringified objects:
when I use JSON.parse on the stringifiedItem in the code above. will the output be a media item that I can play using the musicPlayer?
As discussed in an earlier ticket, you should provide the Ti.Media.Item to the Ti.Media.AudioPlayer and check the docs for both API's. Like this:
More docs: - http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Media.MusicPlayer-method-setQueue - http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Media.Item - http://www.clearlyinnovative.com/titanium-appcelerator-quickie-using-system-music-player (a bit outdated, but explains the concept)
I know how to use them... the thing is I would like to save the music picked by the user. and I want to use JSON.stringify on a media item in order to do this, I think you know why (in case you don't know I am planning on using JSON.parse on the saved string and I am hoping to get a media item from that action, a media item I can play using the music player, like you did above) but the output of JSON.stringify on the media item is just an empty object ("{}") and when I parse that? well guess what, I get an empty object that I can do absolutely nothing with. So if you by any chance find a way to save media items (I mean store them like in Ti.App.Properties) I will be more than glad to hear about it. In case you don't know about any then this is a bug (because we should be able to store this information) and let me know when you solve. do you understand the problem now?
I do an did before. But it's still the same thing: The Ti.MediaItem has no properties like other API's like Ti.Blob or Ti.UI.ListItem. The properties are received from the native side generically (see [this method](https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiMediaItem.m#L52) for details). This has been done to keep the properties flexible and only return the properties that are actually called. We would also never store them in Ti.App.Properties, because the API is simply not made for that and would make no sense here. And as said before, you would just need to build an object with the properties that you need and stringify that, I don't see any problem with that. The change would be to have manual properties for all item properties, causing the performance, compile time and flexibility to drop a bit, which isn't suitable as well.
Hans I don't want the user to choose a song every time they go into the app. I want them to choose once and when they quit the app I want the song they chose to be saved so I can use it next time they enter the app
the code above doesn't play the song the user picked. Which means that I cannot save the media item in the way you suggested and still play it using the music player. (this is the functionality I am looking for, not just saving information but actually playing it). (By the way when I change the second to last row with "musicPlayer.setQueue([item])" everything works fine so the problem is not my code but the fact that you can't play the media item after stringifying like you suggested) I am pretty sure there is a way to save media items like so using native ios programing. if you have any other suggestions please notify me otherwise I suggest you add this ability in the next sdk release
You cannot save media items, not in Titanium and not natively (see reference [here](http://stackoverflow.com/a/8624460/5537752)). You would query items based on their properties, like you can do with
Ti.Media.queryMusicLibrary
, quere you would pass the track information and get matches to that specific predicate. One thing we should improve is to expose theMPMediaItemPropertyPersistentID
property as the "persistentID", so you could store that one in your user defaults / Ti.App.Properties and use it as the argument formusicPlayer.setQueue()
. The following works after my patch:In your case, you could check if the track exists already and start your player afterwards. Is that something you could think of? Then I'd add it as part of [this PR](https://github.com/appcelerator/titanium_mobile/pull/8817) and you can patch your SDK right now. It would also be part of 6.1.0 then. *EDIT*: If just [added](https://github.com/appcelerator/titanium_mobile/pull/8817/commits/deeb9f46bd700f4490a0fc31824b59518130f131) the above discussed changes to the existing PR. If you agree, we'd resolve this ticket and get the PR handled in the other ticket, so we can include it into the core asap.
Thanks Hans :) . this solves my problem. just a few questions: 1. from what sdk version is the "persistentID" property available and how can I check if a certain ID already exists? 2. from what sdk version will I be able to use musicPlayer.setQueue() with persistentID? please notify me when the master branch will include these functionalities. thanks again :)
Cool! So the PR is open and will be in 6.1.0 (final release not sure, yet). As soon the PR is merged, you cam grab a build and use it. Or you can go to Github and change the files manually (remove the red parts and replace it with the green ones). I will resolve this ticket as Duplicte now and ensure that the other gets reviewing in time.
thanks! who do I need to talk to in order to get notify when the PR is merged?
Just ensure you follow TIMOB-24372 and check when the status changes to "Resolved - Fixed". I will also ping you when it's done!
Closing ticket as duplicate, please see TIMOB-24372.
Was the PR merged yet? Can I use persistentID with the current master version?
Hey Tamir, yeah you can (even with 6_1_X)! Use the
persistentID
on the Ti.Media.Item. See the example given in TIMOB-24372.Great!, thanks Hans. Just one more question, how can I check if a given persistentID is indeed present in the user's music library?
It should always be present, because it is the "primary-key" used by iOS to identify the asset. See the [Apple docs](https://developer.apple.com/reference/mediaplayer/mpmediaitempropertypersistentid) for more infos.
but what if the user happens to delete the item with the given persistentID. What will happen then? and how can I know when such thing happened?
You mean if you pass an identifier to the player that does not exist? I didn't actually tested that case but I think the player would through an error event.
and how would I know if the identifier does not exist before I pass it to the player? and how can I listen to that error event you mentioned? (I mean code wise).
Hans, May I suggest that you would be able to request the whole mediaItem (meaning an actual mediaItem like the ones we get from openMusicLibrary) using the persistentID... I am sure this would be very helpful to many people :) thanks;
Hans the current builds on the build server are all fucked up!! can you please instruct me on how to merge the PR myself?