feat(downloads): add metadata to videos
This commit is contained in:
parent
5d0d375242
commit
f2b8cdc812
2 changed files with 55 additions and 51 deletions
100
js/api.js
100
js/api.js
|
|
@ -15,7 +15,7 @@ import { APICache } from './cache.js';
|
||||||
import { DashDownloader } from './dash-downloader.ts';
|
import { DashDownloader } from './dash-downloader.ts';
|
||||||
import { HlsDownloader } from './hls-downloader.js';
|
import { HlsDownloader } from './hls-downloader.js';
|
||||||
import { MP3EncodingError } from './mp3-encoder.js';
|
import { MP3EncodingError } from './mp3-encoder.js';
|
||||||
import { loadFfmpeg, FfmpegError } from './ffmpeg.js';
|
import { loadFfmpeg, FfmpegError, ffmpeg } from './ffmpeg.js';
|
||||||
import { triggerDownload, applyAudioPostProcessing } from './download-utils.ts';
|
import { triggerDownload, applyAudioPostProcessing } from './download-utils.ts';
|
||||||
import { isCustomFormat } from './ffmpegFormats.ts';
|
import { isCustomFormat } from './ffmpegFormats.ts';
|
||||||
import { DownloadProgress } from './progressEvents.js';
|
import { DownloadProgress } from './progressEvents.js';
|
||||||
|
|
@ -1504,59 +1504,63 @@ export class LosslessAPI {
|
||||||
|
|
||||||
if (!isVideo) {
|
if (!isVideo) {
|
||||||
blob = await applyAudioPostProcessing(blob, quality, onProgress, options.signal);
|
blob = await applyAudioPostProcessing(blob, quality, onProgress, options.signal);
|
||||||
|
}
|
||||||
|
|
||||||
// Add metadata if track information is provided
|
// Add metadata if track information is provided
|
||||||
if (track) {
|
if (track) {
|
||||||
onProgress?.({
|
onProgress?.({
|
||||||
stage: 'processing',
|
stage: 'processing',
|
||||||
message: 'Adding metadata...',
|
message: 'Adding metadata...',
|
||||||
});
|
});
|
||||||
|
|
||||||
const enrichedTrack = { ...track };
|
const enrichedTrack = { ...track };
|
||||||
if (lookup.info) {
|
if (lookup.info) {
|
||||||
enrichedTrack.replayGain = {
|
enrichedTrack.replayGain = {
|
||||||
trackReplayGain: lookup.info.trackReplayGain,
|
trackReplayGain: lookup.info.trackReplayGain,
|
||||||
trackPeakAmplitude: lookup.info.trackPeakAmplitude,
|
trackPeakAmplitude: lookup.info.trackPeakAmplitude,
|
||||||
albumReplayGain: lookup.info.albumReplayGain,
|
albumReplayGain: lookup.info.albumReplayGain,
|
||||||
albumPeakAmplitude: lookup.info.albumPeakAmplitude,
|
albumPeakAmplitude: lookup.info.albumPeakAmplitude,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (track.album?.id && (track.album?.totalDiscs == null || track.album?.numberOfTracksOnDisc == null)) {
|
||||||
track.album?.id &&
|
|
||||||
(track.album?.totalDiscs == null || track.album?.numberOfTracksOnDisc == null)
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
const albumData = await this.getAlbum(track.album.id);
|
|
||||||
if (albumData.tracks?.length > 0) {
|
|
||||||
const discTrackCounts = new Map();
|
|
||||||
let maxDiscNumber = 0;
|
|
||||||
for (const t of albumData.tracks) {
|
|
||||||
const dn = getTrackDiscNumber(t);
|
|
||||||
discTrackCounts.set(dn, (discTrackCounts.get(dn) || 0) + 1);
|
|
||||||
if (dn > maxDiscNumber) maxDiscNumber = dn;
|
|
||||||
}
|
|
||||||
const totalDiscs = maxDiscNumber || 1;
|
|
||||||
const discNumber = getTrackDiscNumber(track);
|
|
||||||
enrichedTrack.album = {
|
|
||||||
...(enrichedTrack.album || {}),
|
|
||||||
totalDiscs: track.album?.totalDiscs ?? totalDiscs,
|
|
||||||
numberOfTracksOnDisc:
|
|
||||||
track.album?.numberOfTracksOnDisc ?? discTrackCounts.get(discNumber),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('Failed to fetch album for disc info:', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onProgress?.(new DownloadProgress('Adding metadata'));
|
|
||||||
try {
|
try {
|
||||||
blob = await addMetadataToAudio(blob, enrichedTrack, this, quality, prefetchPromises);
|
const albumData = await this.getAlbum(track.album.id);
|
||||||
} catch (err) {
|
if (albumData.tracks?.length > 0) {
|
||||||
console.error(err);
|
const discTrackCounts = new Map();
|
||||||
|
let maxDiscNumber = 0;
|
||||||
|
for (const t of albumData.tracks) {
|
||||||
|
const dn = getTrackDiscNumber(t);
|
||||||
|
discTrackCounts.set(dn, (discTrackCounts.get(dn) || 0) + 1);
|
||||||
|
if (dn > maxDiscNumber) maxDiscNumber = dn;
|
||||||
|
}
|
||||||
|
const totalDiscs = maxDiscNumber || 1;
|
||||||
|
const discNumber = getTrackDiscNumber(track);
|
||||||
|
enrichedTrack.album = {
|
||||||
|
...(enrichedTrack.album || {}),
|
||||||
|
totalDiscs: track.album?.totalDiscs ?? totalDiscs,
|
||||||
|
numberOfTracksOnDisc:
|
||||||
|
track.album?.numberOfTracksOnDisc ?? discTrackCounts.get(discNumber),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Failed to fetch album for disc info:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onProgress?.(new DownloadProgress('Adding metadata'));
|
||||||
|
try {
|
||||||
|
if (isVideo) {
|
||||||
|
blob = new File(
|
||||||
|
[await ffmpeg(blob, ['-c', 'copy'], 'output.mp4', 'video/mp4', onProgress, options.signal)],
|
||||||
|
'output.mp4',
|
||||||
|
{ type: 'video/mp4' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
blob = await addMetadataToAudio(blob, enrichedTrack, this, quality, prefetchPromises);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.triggerDownload ?? true) {
|
if (options.triggerDownload ?? true) {
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,12 @@ export async function addMetadataToAudio(audioBlob, track, api, _quality, prefet
|
||||||
try {
|
try {
|
||||||
data.title = getTrackTitle(track);
|
data.title = getTrackTitle(track);
|
||||||
data.artist = getFullArtistString(track);
|
data.artist = getFullArtistString(track);
|
||||||
data.albumTitle = track.album.title;
|
data.albumTitle = track.album?.title;
|
||||||
data.albumArtist = track.album?.artist?.name || track.artist?.name;
|
data.albumArtist = track.album?.artist?.name || track.artist?.name;
|
||||||
data.trackNumber = track.trackNumber;
|
data.trackNumber = track.trackNumber;
|
||||||
data.discNumber = track.volumeNumber ?? track.discNumber;
|
data.discNumber = track.volumeNumber ?? track.discNumber;
|
||||||
data.totalTracks = track.album.numberOfTracksOnDisc ?? track.album.numberOfTracks;
|
data.totalTracks = track.album?.numberOfTracksOnDisc ?? track.album?.numberOfTracks;
|
||||||
data.totalDiscs = track.album.totalDiscs;
|
data.totalDiscs = track.album?.totalDiscs;
|
||||||
data.copyright = track.copyright;
|
data.copyright = track.copyright;
|
||||||
data.isrc = track.isrc;
|
data.isrc = track.isrc;
|
||||||
data.explicit = Boolean(track.explicit);
|
data.explicit = Boolean(track.explicit);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue