feat: Allow scrobbling using alternative song titles (#3093)

This commit is contained in:
Yumeo
2025-03-15 18:42:58 +01:00
committed by GitHub
parent 2d86d26701
commit bcdd24d74b
6 changed files with 38 additions and 5 deletions

View File

@ -671,7 +671,8 @@
"listenbrainz": {
"token": "Enter ListenBrainz user token"
},
"scrobble-other-media": "Scrobble other media"
"scrobble-other-media": "Scrobble other media",
"scrobble-alternative-title": "Use alternative titles"
},
"name": "Scrobbler",
"prompt": {

View File

@ -12,6 +12,12 @@ export interface ScrobblerPluginConfig {
* @default true
*/
scrobbleOtherMedia: boolean;
/**
* Use alternative titles for scrobbling (Useful for non-roman song titles)
*
* @default false
*/
alternativeTitles: boolean;
scrobblers: {
lastfm: {
/**
@ -71,6 +77,7 @@ export interface ScrobblerPluginConfig {
export const defaultConfig: ScrobblerPluginConfig = {
enabled: false,
scrobbleOtherMedia: true,
alternativeTitles: false,
scrobblers: {
lastfm: {
enabled: false,

View File

@ -96,6 +96,15 @@ export const onMenu = async ({
setConfig(config);
},
},
{
label: t('plugins.scrobbler.menu.scrobble-alternative-title'),
type: 'checkbox',
checked: Boolean(config.alternativeTitles),
click(item) {
config.alternativeTitles = item.checked;
setConfig(config);
},
},
{
label: 'Last.fm',
submenu: [

View File

@ -127,8 +127,13 @@ export class LastFmScrobbler extends ScrobblerBase {
await this.createSession(config, setConfig);
}
const title =
config.alternativeTitles && songInfo.alternativeTitle !== undefined
? songInfo.alternativeTitle
: songInfo.title;
const postData: LastFmSongData = {
track: songInfo.title,
track: title,
duration: songInfo.songDuration,
artist: songInfo.artist,
...(songInfo.album ? { album: songInfo.album } : undefined), // Will be undefined if current song is a video

View File

@ -48,7 +48,7 @@ export class ListenbrainzScrobbler extends ScrobblerBase {
return;
}
const body = createRequestBody('playing_now', songInfo);
const body = createRequestBody('playing_now', songInfo, config);
submitListen(body, config);
}
@ -64,7 +64,7 @@ export class ListenbrainzScrobbler extends ScrobblerBase {
return;
}
const body = createRequestBody('single', songInfo);
const body = createRequestBody('single', songInfo, config);
body.payload[0].listened_at = Math.trunc(Date.now() / 1000);
submitListen(body, config);
@ -74,10 +74,16 @@ export class ListenbrainzScrobbler extends ScrobblerBase {
function createRequestBody(
listenType: string,
songInfo: SongInfo,
config: ScrobblerPluginConfig,
): ListenbrainzRequestBody {
const title =
config.alternativeTitles && songInfo.alternativeTitle !== undefined
? songInfo.alternativeTitle
: songInfo.title;
const trackMetadata = {
artist_name: songInfo.artist,
track_name: songInfo.title,
track_name: title,
release_name: songInfo.album ?? undefined,
additional_info: {
media_player: 'YouTube Music Desktop App',

View File

@ -28,6 +28,7 @@ export enum MediaType {
export interface SongInfo {
title: string;
alternativeTitle?: string;
artist: string;
views: number;
uploadDate?: string;
@ -68,6 +69,7 @@ const handleData = async (
// Fill songInfo with empty values
const songInfo: SongInfo = {
title: '',
alternativeTitle: '',
artist: '',
views: 0,
uploadDate: '',
@ -91,6 +93,9 @@ const handleData = async (
new URL(microformat.urlCanonical).searchParams.get('list') ?? '';
// Used for options.resumeOnStart
config.set('url', microformat.urlCanonical);
songInfo.alternativeTitle = microformat.linkAlternates.find(
(link) => link.title,
)?.title;
}
const { videoDetails } = data;