improve handling of file updates
This commit is contained in:
parent
da159cace2
commit
4429c50dec
@ -76,6 +76,14 @@ public class MediaMetadataExtractor extends HashMap<String, ArrayList<String>> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this file contains any (interesting) tags
|
||||||
|
* @return true if file is considered to be tagged
|
||||||
|
*/
|
||||||
|
public boolean isTagged() {
|
||||||
|
return (containsKey(TITLE) || containsKey(ALBUM) || containsKey(ARTIST));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to populate this instance with tags found in given path
|
* Attempts to populate this instance with tags found in given path
|
||||||
*
|
*
|
||||||
|
@ -157,114 +157,119 @@ public class MediaScanner implements Handler.Callback {
|
|||||||
if (isBlacklisted(file))
|
if (isBlacklisted(file))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
long dbEntryMtime = mBackend.getSongMtime(songId) * 1000; // this is in unixtime -> convert to 'ms'
|
long dbEntryMtime = mBackend.getSongMtime(songId) * 1000; // this is in unixtime -> convert to 'ms'
|
||||||
long fileMtime = file.lastModified();
|
long fileMtime = file.lastModified();
|
||||||
boolean needsPurge = false;
|
boolean needsInsert = true;
|
||||||
|
boolean needsCleanup = false;
|
||||||
|
|
||||||
if (dbEntryMtime >= fileMtime) {
|
if (dbEntryMtime >= fileMtime) {
|
||||||
Log.v("VanillaMusic", "Skipping already known song with id "+songId);
|
return false; // on-disk mtime is older than db mtime -> nothing to do
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbEntryMtime != 0) {
|
if (dbEntryMtime != 0) {
|
||||||
|
// file on disk is newer: delete old entry and re-insert it
|
||||||
// fixme: drops play counts :-(
|
// fixme: drops play counts :-(
|
||||||
mBackend.delete(MediaLibrary.TABLE_SONGS, MediaLibrary.SongColumns._ID+"="+songId, null);
|
mBackend.delete(MediaLibrary.TABLE_SONGS, MediaLibrary.SongColumns._ID+"="+songId, null);
|
||||||
needsPurge = true;
|
needsCleanup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaMetadataExtractor tags = new MediaMetadataExtractor(path);
|
MediaMetadataExtractor tags = new MediaMetadataExtractor(path);
|
||||||
if (tags.isEmpty())
|
if (tags.isTagged() == false) {
|
||||||
return false; // file does not contain audio data
|
needsInsert = false; // does not have any useable metadata: wont insert even if it is a playable file
|
||||||
|
}
|
||||||
|
|
||||||
// Get tags which always must be set
|
if (needsInsert) {
|
||||||
String title = tags.getFirst(MediaMetadataExtractor.TITLE);
|
// Get tags which always must be set
|
||||||
if (title == null)
|
String title = tags.getFirst(MediaMetadataExtractor.TITLE);
|
||||||
title = "Untitled";
|
if (title == null)
|
||||||
|
title = "Untitled";
|
||||||
|
|
||||||
String album = tags.getFirst(MediaMetadataExtractor.ALBUM);
|
String album = tags.getFirst(MediaMetadataExtractor.ALBUM);
|
||||||
if (album == null)
|
if (album == null)
|
||||||
album = "No Album";
|
album = "No Album";
|
||||||
|
|
||||||
String artist = tags.getFirst(MediaMetadataExtractor.ARTIST);
|
String artist = tags.getFirst(MediaMetadataExtractor.ARTIST);
|
||||||
if (artist == null)
|
if (artist == null)
|
||||||
artist = "No Artist";
|
artist = "No Artist";
|
||||||
|
|
||||||
|
|
||||||
long albumId = MediaLibrary.hash63(album);
|
long albumId = MediaLibrary.hash63(album);
|
||||||
long artistId = MediaLibrary.hash63(artist);
|
long artistId = MediaLibrary.hash63(artist);
|
||||||
|
|
||||||
ContentValues v = new ContentValues();
|
ContentValues v = new ContentValues();
|
||||||
v.put(MediaLibrary.SongColumns._ID, songId);
|
v.put(MediaLibrary.SongColumns._ID, songId);
|
||||||
v.put(MediaLibrary.SongColumns.TITLE, title);
|
v.put(MediaLibrary.SongColumns.TITLE, title);
|
||||||
v.put(MediaLibrary.SongColumns.TITLE_SORT, MediaLibrary.keyFor(title));
|
v.put(MediaLibrary.SongColumns.TITLE_SORT, MediaLibrary.keyFor(title));
|
||||||
v.put(MediaLibrary.SongColumns.ALBUM_ID, albumId);
|
v.put(MediaLibrary.SongColumns.ALBUM_ID, albumId);
|
||||||
v.put(MediaLibrary.SongColumns.DURATION, tags.getFirst(MediaMetadataExtractor.DURATION));
|
v.put(MediaLibrary.SongColumns.DURATION, tags.getFirst(MediaMetadataExtractor.DURATION));
|
||||||
v.put(MediaLibrary.SongColumns.SONG_NUMBER, tags.getFirst(MediaMetadataExtractor.TRACK_NUMBER));
|
v.put(MediaLibrary.SongColumns.SONG_NUMBER, tags.getFirst(MediaMetadataExtractor.TRACK_NUMBER));
|
||||||
v.put(MediaLibrary.SongColumns.YEAR, tags.getFirst(MediaMetadataExtractor.YEAR));
|
v.put(MediaLibrary.SongColumns.YEAR, tags.getFirst(MediaMetadataExtractor.YEAR));
|
||||||
v.put(MediaLibrary.SongColumns.PATH, path);
|
v.put(MediaLibrary.SongColumns.PATH, path);
|
||||||
mBackend.insert(MediaLibrary.TABLE_SONGS, null, v);
|
mBackend.insert(MediaLibrary.TABLE_SONGS, null, v);
|
||||||
|
|
||||||
v.clear();
|
|
||||||
v.put(MediaLibrary.AlbumColumns._ID, albumId);
|
|
||||||
v.put(MediaLibrary.AlbumColumns.ALBUM, album);
|
|
||||||
v.put(MediaLibrary.AlbumColumns.ALBUM_SORT, MediaLibrary.keyFor(album));
|
|
||||||
v.put(MediaLibrary.AlbumColumns.PRIMARY_ARTIST_ID, artistId);
|
|
||||||
v.put(MediaLibrary.AlbumColumns.PRIMARY_ALBUM_YEAR,tags.getFirst(MediaMetadataExtractor.YEAR));
|
|
||||||
v.put(MediaLibrary.AlbumColumns.DISC_NUMBER, tags.getFirst(MediaMetadataExtractor.DISC_NUMBER));
|
|
||||||
mBackend.insert(MediaLibrary.TABLE_ALBUMS, null, v);
|
|
||||||
|
|
||||||
v.clear();
|
|
||||||
v.put(MediaLibrary.ContributorColumns._ID, artistId);
|
|
||||||
v.put(MediaLibrary.ContributorColumns._CONTRIBUTOR, artist);
|
|
||||||
v.put(MediaLibrary.ContributorColumns._CONTRIBUTOR_SORT, MediaLibrary.keyFor(artist));
|
|
||||||
mBackend.insert(MediaLibrary.TABLE_CONTRIBUTORS, null, v);
|
|
||||||
|
|
||||||
v.clear();
|
|
||||||
v.put(MediaLibrary.ContributorSongColumns._CONTRIBUTOR_ID, artistId);
|
|
||||||
v.put(MediaLibrary.ContributorSongColumns.SONG_ID, songId);
|
|
||||||
v.put(MediaLibrary.ContributorSongColumns.ROLE, MediaLibrary.ROLE_ARTIST);
|
|
||||||
mBackend.insert(MediaLibrary.TABLE_CONTRIBUTORS_SONGS, null, v);
|
|
||||||
|
|
||||||
// Composers are optional: only add if we found it
|
|
||||||
String composer = tags.getFirst(MediaMetadataExtractor.COMPOSER);
|
|
||||||
if (composer != null) {
|
|
||||||
long composerId = MediaLibrary.hash63(composer);
|
|
||||||
v.clear();
|
v.clear();
|
||||||
v.put(MediaLibrary.ContributorColumns._ID, composerId);
|
v.put(MediaLibrary.AlbumColumns._ID, albumId);
|
||||||
v.put(MediaLibrary.ContributorColumns._CONTRIBUTOR, composer);
|
v.put(MediaLibrary.AlbumColumns.ALBUM, album);
|
||||||
v.put(MediaLibrary.ContributorColumns._CONTRIBUTOR_SORT, MediaLibrary.keyFor(composer));
|
v.put(MediaLibrary.AlbumColumns.ALBUM_SORT, MediaLibrary.keyFor(album));
|
||||||
|
v.put(MediaLibrary.AlbumColumns.PRIMARY_ARTIST_ID, artistId);
|
||||||
|
v.put(MediaLibrary.AlbumColumns.PRIMARY_ALBUM_YEAR,tags.getFirst(MediaMetadataExtractor.YEAR));
|
||||||
|
v.put(MediaLibrary.AlbumColumns.DISC_NUMBER, tags.getFirst(MediaMetadataExtractor.DISC_NUMBER));
|
||||||
|
mBackend.insert(MediaLibrary.TABLE_ALBUMS, null, v);
|
||||||
|
|
||||||
|
v.clear();
|
||||||
|
v.put(MediaLibrary.ContributorColumns._ID, artistId);
|
||||||
|
v.put(MediaLibrary.ContributorColumns._CONTRIBUTOR, artist);
|
||||||
|
v.put(MediaLibrary.ContributorColumns._CONTRIBUTOR_SORT, MediaLibrary.keyFor(artist));
|
||||||
mBackend.insert(MediaLibrary.TABLE_CONTRIBUTORS, null, v);
|
mBackend.insert(MediaLibrary.TABLE_CONTRIBUTORS, null, v);
|
||||||
|
|
||||||
v.clear();
|
v.clear();
|
||||||
v.put(MediaLibrary.ContributorSongColumns._CONTRIBUTOR_ID, composerId);
|
v.put(MediaLibrary.ContributorSongColumns._CONTRIBUTOR_ID, artistId);
|
||||||
v.put(MediaLibrary.ContributorSongColumns.SONG_ID, songId);
|
v.put(MediaLibrary.ContributorSongColumns.SONG_ID, songId);
|
||||||
v.put(MediaLibrary.ContributorSongColumns.ROLE, MediaLibrary.ROLE_COMPOSER);
|
v.put(MediaLibrary.ContributorSongColumns.ROLE, MediaLibrary.ROLE_ARTIST);
|
||||||
mBackend.insert(MediaLibrary.TABLE_CONTRIBUTORS_SONGS, null, v);
|
mBackend.insert(MediaLibrary.TABLE_CONTRIBUTORS_SONGS, null, v);
|
||||||
}
|
|
||||||
|
|
||||||
// A song might be in multiple genres
|
// Composers are optional: only add if we found it
|
||||||
if (tags.containsKey(MediaMetadataExtractor.GENRE)) {
|
String composer = tags.getFirst(MediaMetadataExtractor.COMPOSER);
|
||||||
ArrayList<String> genres = tags.get(MediaMetadataExtractor.GENRE);
|
if (composer != null) {
|
||||||
for (String genre : genres) {
|
long composerId = MediaLibrary.hash63(composer);
|
||||||
long genreId = MediaLibrary.hash63(genre);
|
|
||||||
v.clear();
|
v.clear();
|
||||||
v.put(MediaLibrary.GenreColumns._ID, genreId);
|
v.put(MediaLibrary.ContributorColumns._ID, composerId);
|
||||||
v.put(MediaLibrary.GenreColumns._GENRE, genre);
|
v.put(MediaLibrary.ContributorColumns._CONTRIBUTOR, composer);
|
||||||
v.put(MediaLibrary.GenreColumns._GENRE_SORT, MediaLibrary.keyFor(genre));
|
v.put(MediaLibrary.ContributorColumns._CONTRIBUTOR_SORT, MediaLibrary.keyFor(composer));
|
||||||
mBackend.insert(MediaLibrary.TABLE_GENRES, null, v);
|
mBackend.insert(MediaLibrary.TABLE_CONTRIBUTORS, null, v);
|
||||||
|
|
||||||
v.clear();
|
v.clear();
|
||||||
v.put(MediaLibrary.GenreSongColumns._GENRE_ID, genreId);
|
v.put(MediaLibrary.ContributorSongColumns._CONTRIBUTOR_ID, composerId);
|
||||||
v.put(MediaLibrary.GenreSongColumns.SONG_ID, songId);
|
v.put(MediaLibrary.ContributorSongColumns.SONG_ID, songId);
|
||||||
mBackend.insert(MediaLibrary.TABLE_GENRES_SONGS, null, v);
|
v.put(MediaLibrary.ContributorSongColumns.ROLE, MediaLibrary.ROLE_COMPOSER);
|
||||||
|
mBackend.insert(MediaLibrary.TABLE_CONTRIBUTORS_SONGS, null, v);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (needsPurge)
|
// A song might be in multiple genres
|
||||||
|
if (tags.containsKey(MediaMetadataExtractor.GENRE)) {
|
||||||
|
ArrayList<String> genres = tags.get(MediaMetadataExtractor.GENRE);
|
||||||
|
for (String genre : genres) {
|
||||||
|
long genreId = MediaLibrary.hash63(genre);
|
||||||
|
v.clear();
|
||||||
|
v.put(MediaLibrary.GenreColumns._ID, genreId);
|
||||||
|
v.put(MediaLibrary.GenreColumns._GENRE, genre);
|
||||||
|
v.put(MediaLibrary.GenreColumns._GENRE_SORT, MediaLibrary.keyFor(genre));
|
||||||
|
mBackend.insert(MediaLibrary.TABLE_GENRES, null, v);
|
||||||
|
|
||||||
|
v.clear();
|
||||||
|
v.put(MediaLibrary.GenreSongColumns._GENRE_ID, genreId);
|
||||||
|
v.put(MediaLibrary.GenreSongColumns.SONG_ID, songId);
|
||||||
|
mBackend.insert(MediaLibrary.TABLE_GENRES_SONGS, null, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end if (needsInsert)
|
||||||
|
|
||||||
|
|
||||||
|
if (needsCleanup)
|
||||||
mBackend.cleanOrphanedEntries();
|
mBackend.cleanOrphanedEntries();
|
||||||
|
|
||||||
Log.v("VanillaMusic", "MediaScanner: inserted "+path);
|
Log.v("VanillaMusic", "MediaScanner: inserted "+path);
|
||||||
return true;
|
return (needsInsert || needsCleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user