This redesign completely changes how tags are stored in memory. Now all
arbitrary tag names are supported, where possible. Some extra work will
be needed to support arbitrary tags with TagLib, such as replacing it
with a different library.
Translation pending for a couple of strings.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Ask for permission to access the folders containing container files,
such as .CUE sheets, or .M3U or .PLS playlists.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Process main queue messages by handling the loading in a background
queue, and sync it to the main thread periodically, while pausing to
wait for the results. This allows the file open dialog to return
immediately, and display loading progress on the status bar.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Tabulate first seen information when loading the metadata, rather than
when first adding the tracks to the playlist. This should fix first seen
information when metadata is available, as the information will be
useless without track titles.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The playlist was being pruned of entries marked for deletion, but they
were not being pruned from the set that was then added to the player.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This needs to be called on the main thread, as something may or may not
be enumerating over the data while this thread decides to call it.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Do not clear the progress indicator if a loading task is already running
in the background, but instead return without doing anything.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Refine the global variable usage, eliminating double underscore prefixes
and trusting that static global variables will exist in the object where
the class was created. Got rid of that nasty NSApplication extension
hack that was previously in use.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Metadata loading now filters the request list down to unique file paths
that don't have metadata loaded, makes sure that another instance of the
loader isn't already loading the same files, and waits for previous
instances to complete before beginning another metadata load task. It
also will update the playlist entries for all affected tracks, even if
they were not explicitly selected for loading or reloading.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Handle missing track items in the databse more gracefully, by deleting
the track entries before passing them on to the caller, so problems do
not occur later.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Invalid files may include nil URLs, which should be skipped or stop
playback altogether. Invalid files will be marked as an error, and
stop playback.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Apply the index sort to the fetch request itself, rather than applying
it to the resulting array afterward.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The member that I set myself to indicate deletion has one capital letter
to differentiate it from the built-in "delete" property of managed
objects, which doesn't do what I want, so I had to dodge it with that
capitalization thing.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Completely rewrite the playlist storage once again, this time with a
much faster Core Data implementation. It still uses a little magic for
Album Artwork consolidation, but string consolidation doesn't seem to be
needed to reduce the disk storage size. Works much faster than my silly
implementation, too.
Old implementations are still kept for backwards compatibility with
existing playlists.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Jobs are meant to be serialized, so prevent multiple jobs from queueing
simultaneously, as they are not designed to interact with each other.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Long actions, such as file opening, playlist loading, metadata loading
and refreshing, etc, are now handled through NSProgress. Additionally,
a new status bar change displays the progress of the task instead of
the total duration of the playlist. Finally, app quit is blocked by a
running task, and if the app is quit while a task is running, it will
be delayed until the task completes, at which time the app will
terminate cleanly.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Prevent a race condition with deleting playlist entries while their
metadata is still being loaded by the player.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Significantly reduce the memory footprint of adding tracks to the
playlist, by coalescing the NSString and NSData objects in the info
dictionaries as they are being loaded in the background, into a common
data set which will then be discarded when the whole job is completed.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Metadata versus properties merging, correctly merge over empty fields if
they are assigned with empty strings or zeroed numbers, instead of only
merging over completely missing fields.
Fixes emailed bug, CUE Sheet metadata reading, primarily.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Added a logging method that indicates starting playback of a given URL,
and added a debug build only logging of every metadata load event.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
- Display playlist total duration in units up to weeks and down to just seconds, and only pluralize units as necessary
- Major change: Implemented a SQLite disk backed playlist, track data, and queue storage system, which will be synchronized from the player in real time, and will hopefully survive system or app crashes. Existing plist playlist will be imported on first run, and removed on shutdown.