utilize downloaded files within detail activities

This commit is contained in:
dkanada 2021-05-09 13:44:31 +09:00
commit 395b1227c9
11 changed files with 100 additions and 15 deletions

View file

@ -61,6 +61,7 @@ public class App extends Application {
.addMigrations(JellyDatabase.Migration2)
.addMigrations(JellyDatabase.Migration3)
.addMigrations(JellyDatabase.Migration4)
.addMigrations(JellyDatabase.Migration5)
.build();
}

View file

@ -0,0 +1,29 @@
package com.dkanada.gramophone.database;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import com.dkanada.gramophone.model.Song;
import java.util.UUID;
@Entity(tableName = "cache")
public class Cache {
@NonNull
@PrimaryKey
public String id;
@ColumnInfo(defaultValue = "1")
public Boolean cache;
public Cache() {
this.id = UUID.randomUUID().toString();
}
public Cache(Song song) {
this.id = song.id;
this.cache = true;
}
}

View file

@ -0,0 +1,19 @@
package com.dkanada.gramophone.database;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import com.dkanada.gramophone.model.Song;
import java.util.List;
@Dao
public interface CacheDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertCache(Cache cache);
@Query("SELECT * FROM songs LEFT JOIN cache USING(id) WHERE songs.id IN (:ids)")
List<Song> getSongs(List<String> ids);
}

View file

@ -10,14 +10,16 @@ import com.dkanada.gramophone.model.User;
@androidx.room.Database(
entities = {
Cache.class,
Song.class,
QueueSong.class,
User.class
},
version = 4,
version = 5,
exportSchema = false
)
public abstract class JellyDatabase extends RoomDatabase {
public abstract CacheDao cacheDao();
public abstract SongDao songDao();
public abstract QueueSongDao queueSongDao();
public abstract UserDao userDao();
@ -52,4 +54,12 @@ public abstract class JellyDatabase extends RoomDatabase {
+ "name TEXT, server TEXT, token TEXT)");
}
};
public static final Migration Migration5 = new Migration(4, 5) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE cache (id TEXT NOT NULL PRIMARY KEY,"
+ "cache INTEGER NOT NULL)");
}
};
}

View file

@ -4,6 +4,7 @@ import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Transaction;
import com.dkanada.gramophone.App;
import com.dkanada.gramophone.model.Song;
@ -22,6 +23,7 @@ public abstract class QueueSongDao {
@Query("SELECT * from queueSongs WHERE queue = :queue ORDER BY `index`")
public abstract List<QueueSong> getQueueSongs(int queue);
@Transaction
public List<Song> getQueue(int queue) {
List<QueueSong> queueSongs = getQueueSongs(queue);
List<Song> songs = new ArrayList<>();
@ -34,6 +36,7 @@ public abstract class QueueSongDao {
return songs;
}
@Transaction
public void setQueue(List<Song> songs, int queue) {
List<QueueSong> queueSongs = new ArrayList<>();
for (int i = 0; i < songs.size(); i++) {

View file

@ -48,6 +48,8 @@ public class Song implements Parcelable {
public int bitDepth;
public int channels;
public boolean cache;
public Song() {
this.id = UUID.randomUUID().toString();
}

View file

@ -2,13 +2,13 @@ package com.dkanada.gramophone.service;
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import com.dkanada.gramophone.App;
import com.dkanada.gramophone.BuildConfig;
import com.dkanada.gramophone.database.Cache;
import com.dkanada.gramophone.model.Song;
import com.dkanada.gramophone.util.MusicUtil;
@ -50,11 +50,7 @@ public class DownloadService extends Service {
try {
URL url = new URL(MusicUtil.getDownloadUri(song));
URLConnection connection = url.openConnection();
File root = new File(App.getInstance().getCacheDir(), "music");
String path = song.artistName + "/" + song.albumName + "/";
String name = song.discNumber + "." + song.trackNumber + " - " + song.title + "." + song.container;
File audio = new File(root, path + name);
File audio = new File(MusicUtil.getFileUri(song));
audio.getParentFile().mkdirs();
audio.createNewFile();
@ -64,7 +60,7 @@ public class DownloadService extends Service {
connection.connect();
byte[] data = new byte[4096];
byte[] data = new byte[262144];
int count;
while ((count = input.read(data)) != -1) {
@ -73,6 +69,8 @@ public class DownloadService extends Service {
input.close();
output.close();
App.getDatabase().cacheDao().insertCache(new Cache(song));
} catch (Exception e) {
e.printStackTrace();
}

View file

@ -96,15 +96,14 @@ public class LocalPlayer implements Playback {
@Override
public void setDataSource(Song song) {
String uri = MusicUtil.getTranscodeUri(song);
MediaItem mediaItem = exoPlayer.getCurrentMediaItem();
if (mediaItem != null && mediaItem.playbackProperties.uri.toString().equals(uri)) {
if (mediaItem != null && mediaItem.mediaId.equals(song.id)) {
return;
}
exoPlayer.clearMediaItems();
appendDataSource(MusicUtil.getTranscodeUri(song));
appendDataSource(song);
exoPlayer.seekTo(0, 0);
}
@ -114,12 +113,19 @@ public class LocalPlayer implements Playback {
exoPlayer.removeMediaItem(1);
}
appendDataSource(MusicUtil.getTranscodeUri(song));
appendDataSource(song);
}
private void appendDataSource(String path) {
Uri uri = Uri.parse(path);
private void appendDataSource(Song song) {
File audio = new File(MusicUtil.getFileUri(song));
Uri uri = Uri.fromFile(audio);
if (!song.cache || !audio.exists()) {
uri = Uri.parse(MusicUtil.getTranscodeUri(song));
}
MediaItem mediaItem = MediaItem.fromUri(uri);
mediaItem = mediaItem.buildUpon().setMediaId(song.id).build();
exoPlayer.addMediaItem(mediaItem);
}

View file

@ -42,6 +42,10 @@ class UnknownMediaSourceFactory(dataSourceFactory: DataSource.Factory) : MediaSo
}
override fun createMediaSource(mediaItem: MediaItem): MediaSource {
if (mediaItem.playbackProperties?.uri.toString().contains("file://")) {
return progressiveMediaSource.createMediaSource(mediaItem)
}
val type: String? = runBlocking {
httpGet(mediaItem.playbackProperties!!.uri.toString())
}

View file

@ -21,6 +21,7 @@ import org.jellyfin.apiclient.interaction.ApiClient;
import org.jellyfin.apiclient.interaction.Response;
import org.jellyfin.apiclient.model.dto.UserItemDataDto;
import java.io.File;
import java.util.List;
import java.util.Locale;
@ -82,6 +83,15 @@ public class MusicUtil {
return builder.toString();
}
public static String getFileUri(Song song) {
File root = new File(App.getInstance().getCacheDir(), "music");
String path = "/" + song.artistName + "/" + song.albumName + "/";
String name = song.discNumber + "." + song.trackNumber + " - " + song.title + "." + song.container;
return root + path + name;
}
@NonNull
public static Intent createShareSongFileIntent(@NonNull final Song song, Context context) {
try {

View file

@ -170,11 +170,14 @@ public class QueryUtil {
@Override
public void onResponse(ItemsResult result) {
List<Song> songs = new ArrayList<>();
List<String> ids = new ArrayList<>();
for (BaseItemDto itemDto : result.getItems()) {
songs.add(new Song(itemDto));
ids.add(itemDto.getId());
}
callback.onLoadMedia(songs);
App.getDatabase().songDao().insertSongs(songs);
callback.onLoadMedia(App.getDatabase().cacheDao().getSongs(ids));
}
@Override