fix: retrieve codec metadata and lyrics asynchronously

This commit is contained in:
Lei Nelissen
2024-10-25 00:25:01 +02:00
parent 4dd0d6e0e5
commit 77db5a51d2
9 changed files with 125 additions and 88 deletions

View File

@@ -1,6 +1,5 @@
import { Album, AlbumTrack } from '@/store/music/types';
import { fetchApi } from './lib';
import {retrieveAndInjectLyricsToTracks} from '@/utility/JellyfinApi/lyrics.ts';
const albumOptions = {
SortBy: 'AlbumArtist,SortName',
@@ -73,5 +72,5 @@ export async function retrieveAlbumTracks(ItemId: string) {
const singleAlbumParams = new URLSearchParams(singleAlbumOptions).toString();
return fetchApi<{ Items: AlbumTrack[] }>(({ user_id }) => `/Users/${user_id}/Items?${singleAlbumParams}`)
.then((data) => retrieveAndInjectLyricsToTracks(data.Items));
.then((d) => d.Items);
}

View File

@@ -1,48 +1,6 @@
import { Lyrics } from '@/store/music/types';
import { fetchApi } from './lib';
import {AlbumTrack} from '@/store/music/types.ts';
interface Metadata {
Artist: string
Album: string
Title: string
Author: string
Length: number
By: string
Offset: number
Creator: string
Version: string
IsSynced: boolean
}
interface LyricData {
Text: string
Start: number
}
export interface Lyrics {
Metadata: Metadata
Lyrics: LyricData[]
}
async function retrieveTrackLyrics(trackId: string): Promise<Lyrics | null> {
return fetchApi<Lyrics>(`/Audio/${trackId}/Lyrics`)
.catch((e) => {
console.error('Error on fetching track lyrics: ', e);
return null;
});
}
export async function retrieveAndInjectLyricsToTracks(tracks: AlbumTrack[]): Promise<AlbumTrack[]> {
return Promise.all(tracks.map(async (track) => {
if (!track.HasLyrics) {
track.Lyrics = null;
return track;
}
track.Lyrics = await retrieveTrackLyrics(track.Id);
return track;
}));
export async function retrieveTrackLyrics(trackId: string): Promise<Lyrics> {
return fetchApi<Lyrics>(`/Audio/${trackId}/Lyrics`);
}

View File

@@ -1,6 +1,5 @@
import { AlbumTrack, Playlist } from '@/store/music/types';
import { asyncFetchStore, fetchApi } from './lib';
import {retrieveAndInjectLyricsToTracks} from '@/utility/JellyfinApi/lyrics.ts';
const playlistOptions = {
SortBy: 'SortName',
@@ -35,5 +34,5 @@ export async function retrievePlaylistTracks(ItemId: string) {
const singlePlaylistParams = new URLSearchParams(singlePlaylistOptions).toString();
return fetchApi<{ Items: AlbumTrack[] }>(`/Playlists/${ItemId}/Items?${singlePlaylistParams}`)
.then((d) => retrieveAndInjectLyricsToTracks(d.Items));
.then((d) => d.Items);
}

View File

@@ -1,9 +1,7 @@
import { AlbumTrack } from '@/store/music/types';
import { AlbumTrack, CodecMetadata } from '@/store/music/types';
import { Platform } from 'react-native';
import { Track } from 'react-native-track-player';
import { fetchApi, getImage } from './lib';
import store from '@/store';
import {retrieveAndInjectLyricsToTracks} from '@/utility/JellyfinApi/lyrics';
import { asyncFetchStore, fetchApi, getImage } from './lib';
const trackOptionsOsOverrides: Record<typeof Platform.OS, Record<string, string>> = {
ios: {
@@ -30,7 +28,7 @@ const baseTrackOptions: Record<string, string> = {
* Generate the track streaming url from the trackId
*/
export function generateTrackUrl(trackId: string) {
const credentials = store.getState().settings.credentials;
const credentials = asyncFetchStore().getState().settings.credentials;
const trackOptions = {
...baseTrackOptions,
UserId: credentials?.user_id || '',
@@ -52,8 +50,6 @@ export async function generateTrack(track: AlbumTrack): Promise<Track> {
// Also construct the URL for the stream
const url = generateTrackUrl(track.Id);
const response = await fetch(url, { method: 'HEAD' });
return {
url,
backendId: track.Id,
@@ -62,10 +58,6 @@ export async function generateTrack(track: AlbumTrack): Promise<Track> {
album: track.Album,
duration: track.RunTimeTicks,
artwork: getImage(track.Id),
hasLyrics: track.HasLyrics,
lyrics: track.Lyrics,
contentType: response.headers.get('Content-Type') || undefined,
isDirectPlay: response.headers.has('Content-Length'),
bitRate: baseTrackOptions.audioBitRate,
};
}
@@ -84,5 +76,15 @@ const trackParams = {
*/
export async function retrieveAllTracks() {
return fetchApi<{ Items: AlbumTrack[] }>(({ user_id }) => `/Users/${user_id}/Items?${trackParams}`)
.then((d) => retrieveAndInjectLyricsToTracks(d.Items));
.then((d) => d.Items);
}
export async function retrieveTrackCodecMetadata(trackId: string): Promise<CodecMetadata> {
const url = generateTrackUrl(trackId);
const response = await fetch(url, { method: 'HEAD' });
return {
contentType: response.headers.get('Content-Type') || undefined,
isDirectPlay: response.headers.has('Content-Length'),
};
}