Skip to content

Commit

Permalink
Send scrobble events at 66% listen time instead of when the track ends
Browse files Browse the repository at this point in the history
  • Loading branch information
Pixaurora committed Nov 6, 2024
1 parent 12cb680 commit a58a34e
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package net.pixaurora.kit_tunes.api.event;

import java.util.Optional;

import net.pixaurora.kit_tunes.api.music.ListeningProgress;
import net.pixaurora.kit_tunes.api.music.Track;
import net.pixaurora.kit_tunes.api.resource.ResourcePath;

public interface TrackMiddleEvent {
public Optional<Track> track();

public ResourcePath searchPath();

public ListeningProgress progress();
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package net.pixaurora.kit_tunes.api.listener;

import net.pixaurora.kit_tunes.api.event.TrackEndEvent;
import net.pixaurora.kit_tunes.api.event.TrackMiddleEvent;
import net.pixaurora.kit_tunes.api.event.TrackStartEvent;

public interface MusicEventListener {
public default void onTrackStart(TrackStartEvent event) {
}

public default void onTrackMiddleReached(TrackMiddleEvent event) {
}

public default void onTrackEnd(TrackEndEvent event) {
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.pixaurora.kitten_heart.impl;

import java.nio.file.Path;
import java.time.Duration;

import org.quiltmc.loader.api.ModContainer;
import org.quiltmc.loader.api.ModMetadata;
Expand All @@ -15,6 +16,8 @@ public abstract class Constants {
public static final Path SCROBBLER_CACHE_PATH = CACHE_PATH.resolve("scrobblers.json");
public static final Path LISTEN_HISTORY_PATH = CACHE_PATH.resolve("history.json");

public static final Duration MINIMUM_TIME_TO_SCROBBLE = Duration.ofMinutes(1);

static {
ModContainer mod = QuiltLoader.getModContainer(MOD_ID).get(); // Should never be null, since we're running from
// in this mod.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ public static void tick() {

MAIN_THREAD_TASKS.clear();
}

synchronized (PLAYING_TRACKS) {
for (PlayingSong song : PLAYING_TRACKS.values()) {
if (song.sentMiddleEvent()) {
continue;
}

if (song.canSendMiddleEvent()) {
processEvent(listener -> listener
.onTrackMiddleReached(new TrackEventImpl(song.path(), song.track(), song.progress())));
}
}
}
}

public static void addMainThreadTask(Runnable task) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import java.util.Optional;

import net.pixaurora.kit_tunes.api.event.TrackEndEvent;
import net.pixaurora.kit_tunes.api.event.TrackMiddleEvent;
import net.pixaurora.kit_tunes.api.event.TrackStartEvent;
import net.pixaurora.kit_tunes.api.music.ListeningProgress;
import net.pixaurora.kit_tunes.api.music.Track;
import net.pixaurora.kit_tunes.api.resource.ResourcePath;

public class TrackEventImpl implements TrackStartEvent, TrackEndEvent {
public class TrackEventImpl implements TrackStartEvent, TrackMiddleEvent, TrackEndEvent {
private final ResourcePath path;
private final Optional<Track> track;
private final ListeningProgress progress;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package net.pixaurora.kitten_heart.impl.listener;

import java.io.IOException;
import java.time.Duration;

import net.pixaurora.kit_tunes.api.event.TrackEndEvent;
import net.pixaurora.kit_tunes.api.event.TrackMiddleEvent;
import net.pixaurora.kit_tunes.api.event.TrackStartEvent;
import net.pixaurora.kit_tunes.api.listener.MusicEventListener;
import net.pixaurora.kit_tunes.api.music.ListeningProgress;
Expand All @@ -28,35 +28,30 @@ public void onTrackStart(TrackStartEvent event) {
}

@Override
public void onTrackEnd(TrackEndEvent event) {
public void onTrackMiddleReached(TrackMiddleEvent event) {
if (!event.track().isPresent()) {
return;
}

Track track = event.track().get();
ListeningProgress progress = event.progress();
ListenRecord record = new ListenRecord(event.track().get(), event.progress());

ListenRecord record = new ListenRecord(track, progress);
KitTunes.SCROBBLER_CACHE
.execute(scrobblers -> scrobblers.completeScrobbling(KitTunes.CLIENT, record));
}

Duration requiredLength = track.duration().dividedBy(2);
boolean longEnoughToScrobble = progress.amountPlayed().compareTo(requiredLength) > 0;

if (longEnoughToScrobble) {
KitTunes.SCROBBLER_CACHE
.execute(scrobblers -> scrobblers.completeScrobbling(KitTunes.CLIENT, record));
} else {
float amountPlayed = (float) progress.amountPlayed().toMillis() / 1000;
float amountRequired = (float) requiredLength.toMillis() / 1000;
KitTunes.LOGGER.info("Skipping scrobbling " + track.name() + " because it only played for " +
amountPlayed + " out of " + amountRequired + " seconds!");
@Override
public void onTrackEnd(TrackEndEvent event) {
if (!event.track().isPresent()) {
return;
}

ListenRecord record = new ListenRecord(event.track().get(), event.progress());

KitTunes.LISTEN_HISTORY.execute(history -> history.record(record));
try {
KitTunes.LISTEN_HISTORY.save();
} catch (IOException e) {
KitTunes.LOGGER.error("Failed to save listen history while scrobbling!", e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.pixaurora.kit_tunes.api.music.ListeningProgress;
import net.pixaurora.kit_tunes.api.music.Track;
import net.pixaurora.kit_tunes.api.resource.ResourcePath;
import net.pixaurora.kitten_heart.impl.Constants;
import net.pixaurora.kitten_heart.impl.music.control.MusicControls;
import net.pixaurora.kitten_heart.impl.ui.widget.progress.ProgressProvider;

Expand All @@ -16,11 +17,16 @@ public class PlayingSong implements ProgressProvider {
private final ListeningProgress progress;
private final MusicControls controls;

private boolean hasSentMiddleEvent;
private final long middleEventMillis;

public PlayingSong(ResourcePath path, Optional<Track> track, ListeningProgress progress, MusicControls controls) {
this.path = path;
this.track = track;
this.progress = progress;
this.controls = controls;
this.middleEventMillis = track.map(Track::duration).map(duration -> duration.toMillis() * 6 / 10)
.orElse(Constants.MINIMUM_TIME_TO_SCROBBLE.toMillis());
}

public ResourcePath path() {
Expand All @@ -39,6 +45,19 @@ public MusicControls controls() {
return this.controls;
}

public boolean sentMiddleEvent() {
return this.hasSentMiddleEvent;
}

public boolean canSendMiddleEvent() {
if (this.middleEventMillis < this.progress.amountPlayed().toMillis()) {
this.hasSentMiddleEvent = true;
return true;
} else {
return false;
}
}

@Override
public double percentComplete() {
return (double) this.playedDuration().toMillis() / this.totalDuration().toMillis();
Expand Down

0 comments on commit a58a34e

Please sign in to comment.