JXA - set iTunes track location (with whitespace)

Hello,

I’m trying to set the location of a track but it gives me a “Can’t convert types” error when I try to set it to a path with whitespaces.

Application('Music').tracks.whose({name: "audio"})[0].location();											// "/path/to/audio.mp3"
Application('Music').tracks.whose({name: "audio"})[0].location = "/new/path/to/audio.mp3";					// "/new/path/to/audio.mp3"
Application('Music').tracks.whose({name: "audio"})[0].location = "/new/path/with whitespace/to/audio.mp3";	// Error -1700: Can't convert types

// Even with Path().toString() instead of a path string it won't work

Thanks in advance for answering!

Model: MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)
AppleScript: 2.7
Browser: Firefox 78.0
Operating System: macOS 10.14

==============

SOLVED:

Changing the whitespaces into %20 seems to work!


Application('Music').tracks.whose({name: 'audio'})[0].location = "/new/path/with%20whitespace/to/audio.mp3";
// I recommend using the encodeURI function
Application('Music').tracks.whose({name: 'audio'})[0].location = encodeURI("/new/path/with whitespace/to/audio.mp3");

I guess that you face the well known problem striking in shell scripts.

The space characters embedded in path names must be quoted.

In shell scripts we replace :
“/new/path/with whitespace/to/audio.mp3”

by

quoted form of “/new/path/with whitespace/to/audio.mp3”

but I don’t know which is the equivalent with JXA.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 7 juin 2020 17:04:55

Thank you for answering!

I’ll use Applescript for the time being since there isn’t really a clear documentation on JXA.

Maybe your problem is related to what I read in :
https://developer.apple.com/library/archive/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/Articles/OSX10-10.html#//apple_ref/doc/uid/TP40014508-CH109-SW1

Paths

When you need to interact with files, such as a document in TextEdit, you will need a path object, not just a string with a path in it. You can use the Path constructor to instantiate paths.

TextEdit = Application(‘TextEdit’)
path = Path(‘/Users/username/Desktop/foo.rtf’)
TextEdit.open(path)
Note: Get the string value of the Path by calling the toString method.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 8 juin 2020 10:31:32

I just tried with the Path object, but it gives me this error: “Error: Error: Can’t get object.”


var track = Application('Music').tracks.whose({name: 'audio'})[0];
track.location = Path("/new/path/with whitespace/to/audio.mp3"); // Error: Error: Can't get object.

Looks like it will only work with Applescript… :confused:


tell application "Music"
	set location of tracks whose name is equal to "audio" to "/new/path/with whitespace/to/audio.mp3" # {application "Music"}
end tell

Also you may need to check your music prefs.

I don’t use Music but in iTunes the last pref tab has an
Option to “keep iTunes music organized”

This forces iTunes to change the location and file name based
On the Artist / Album / Title.

If this is set you may not be able to change the location
As it will conflict with this option.

As response to technomorph:
I tried again with the “keep iTunes music organized” option disabled, but same result unfortunately…

However, I just tried replacing the whitespace with %20 and apparently this works!


Application('Music').tracks.whose({name: 'audio'})[0].location = "/new/path/with%20whitespace/to/audio.mp3"; // "/new/path/with whitespace/to/audio.mp3"

Anyway, thank you for responding everyone!