Search in sources :

Example 1 with SpotifyTrack

use of net.robinfriedli.aiode.audio.spotify.SpotifyTrack in project aiode by robinfriedli.

the class Playlist method asTrackList.

/**
 * returns all Songs as Spotify tracks including all videos that are redirected Spotify tracks i.e. the attribute
 * redirectedSpotifyId is set. Mind that this method has to be invoked with client credentials
 */
public List<SpotifyTrack> asTrackList(SpotifyApi spotifyApi) {
    SpotifyTrackBulkLoadingService service = new SpotifyTrackBulkLoadingService(spotifyApi);
    List<SpotifyTrack> tracks = Lists.newArrayList();
    for (PlaylistItem item : getItemsSorted()) {
        if (item instanceof Song) {
            String id = ((Song) item).getId();
            service.add(createItem(id, TRACK), tracks::add);
        } else if (item instanceof Episode) {
            String id = ((Episode) item).getId();
            service.add(createItem(id, EPISODE), tracks::add);
        } else if (item instanceof Video && ((Video) item).getRedirectedSpotifyId() != null) {
            Video video = (Video) item;
            String redirectedSpotifyId = video.getRedirectedSpotifyId();
            SpotifyItemKind kindEntity = video.getRedirectedSpotifyKind();
            SpotifyTrackKind kind = kindEntity != null ? kindEntity.asEnum() : TRACK;
            service.add(createItem(redirectedSpotifyId, kind), tracks::add);
        }
    }
    service.perform();
    return tracks;
}
Also used : SpotifyTrackBulkLoadingService(net.robinfriedli.aiode.audio.spotify.SpotifyTrackBulkLoadingService) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) SpotifyTrackKind(net.robinfriedli.aiode.audio.spotify.SpotifyTrackKind)

Example 2 with SpotifyTrack

use of net.robinfriedli.aiode.audio.spotify.SpotifyTrack in project aiode by robinfriedli.

the class ChartsCommand method getTrackForRecord.

private Playable getTrackForRecord(Object[] record, Session session) throws Exception {
    long sourceEntityPk = (Long) record[0];
    PlaybackHistorySource sourceEntity = session.load(PlaybackHistorySource.class, sourceEntityPk);
    Playable.Source source = sourceEntity.asEnum();
    String id = (String) record[1];
    Long spotifyItemKindPk = (Long) record[3];
    SpotifyItemKind spotifyItemKind = spotifyItemKindPk != null ? session.load(SpotifyItemKind.class, spotifyItemKindPk) : null;
    switch(source) {
        case SPOTIFY:
            return runWithCredentials(() -> {
                if (spotifyItemKind == null) {
                    throw new IllegalStateException("spotifyItemKind cannot be null for PlaybackHistory entries of source SPOTIFY");
                }
                SpotifyTrackKind kind = spotifyItemKind.asEnum();
                SpotifyService spotifyService = getSpotifyService();
                SpotifyTrack track = kind.loadSingleItem(spotifyService, id);
                if (track == null) {
                    return null;
                }
                return new PlayableTrackWrapper(track);
            });
        case YOUTUBE:
            YouTubeService youTubeService = Aiode.get().getAudioManager().getYouTubeService();
            try {
                return youTubeService.getVideoForId(id);
            } catch (FriendlyException e) {
                return null;
            }
        case URL:
            return playableFactory.createPlayable(id, getContext().getSpotifyApi(), false);
    }
    throw new UnsupportedOperationException("Unsupported source " + sourceEntity);
}
Also used : SpotifyItemKind(net.robinfriedli.aiode.entities.SpotifyItemKind) SpotifyService(net.robinfriedli.aiode.audio.spotify.SpotifyService) YouTubeService(net.robinfriedli.aiode.audio.youtube.YouTubeService) FriendlyException(com.sedmelluq.discord.lavaplayer.tools.FriendlyException) PlayableTrackWrapper(net.robinfriedli.aiode.audio.spotify.PlayableTrackWrapper) Playable(net.robinfriedli.aiode.audio.Playable) SpotifyTrackKind(net.robinfriedli.aiode.audio.spotify.SpotifyTrackKind) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) PlaybackHistorySource(net.robinfriedli.aiode.entities.PlaybackHistorySource)

Example 3 with SpotifyTrack

use of net.robinfriedli.aiode.audio.spotify.SpotifyTrack in project aiode by robinfriedli.

the class UploadCommand method doRun.

@Override
public void doRun() throws Exception {
    SpotifyApi spotifyApi = getContext().getSpotifyApi();
    Playlist playlist = SearchEngine.searchLocalList(getContext().getSession(), getCommandInput());
    if (playlist == null) {
        throw new InvalidCommandException(String.format("No local list found for '%s'", getCommandInput()));
    }
    runWithLogin(() -> {
        List<SpotifyTrack> tracks = playlist.asTrackList(spotifyApi);
        String name = playlist.getName();
        if (tracks.isEmpty()) {
            throw new InvalidCommandException("Playlist " + name + " has no Spotify tracks.");
        }
        String userId = spotifyApi.getCurrentUsersProfile().build().execute().getId();
        se.michaelthelin.spotify.model_objects.specification.Playlist spotifyPlaylist = spotifyApi.createPlaylist(userId, name).build().execute();
        uploadedPlaylistName = spotifyPlaylist.getName();
        String playlistId = spotifyPlaylist.getId();
        List<String> trackUris = tracks.stream().map(SpotifyTrack::getUri).collect(Collectors.toList());
        List<List<String>> sequences = Lists.partition(trackUris, 90);
        for (List<String> sequence : sequences) {
            spotifyApi.addItemsToPlaylist(playlistId, sequence.toArray(new String[0])).build().execute();
        }
        return null;
    });
}
Also used : Playlist(net.robinfriedli.aiode.entities.Playlist) InvalidCommandException(net.robinfriedli.aiode.exceptions.InvalidCommandException) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) SpotifyApi(se.michaelthelin.spotify.SpotifyApi) List(java.util.List)

Example 4 with SpotifyTrack

use of net.robinfriedli.aiode.audio.spotify.SpotifyTrack in project aiode by robinfriedli.

the class QueueCommand method getPlayablesForOption.

private List<Playable> getPlayablesForOption(Object chosenOption, PlayableFactory playableFactory) throws Exception {
    if (chosenOption instanceof Track || chosenOption instanceof YouTubeVideo || chosenOption instanceof Episode) {
        Playable track = playableFactory.createPlayable(shouldRedirectSpotify(), chosenOption);
        loadedTrack = track;
        return Collections.singletonList(track);
    } else if (chosenOption instanceof PlaylistSimplified) {
        PlaylistSimplified playlist = (PlaylistSimplified) chosenOption;
        List<SpotifyTrack> tracks = runWithCredentials(() -> getSpotifyService().getPlaylistTracks(playlist));
        List<Playable> playables = playableFactory.createPlayables(shouldRedirectSpotify(), tracks);
        loadedSpotifyPlaylist = playlist;
        return playables;
    } else if (chosenOption instanceof YouTubePlaylist) {
        YouTubePlaylist youTubePlaylist = (YouTubePlaylist) chosenOption;
        List<Playable> playables = playableFactory.createPlayables(youTubePlaylist);
        loadedYouTubePlaylist = youTubePlaylist;
        return playables;
    } else if (chosenOption instanceof AlbumSimplified) {
        AlbumSimplified album = (AlbumSimplified) chosenOption;
        List<Track> tracks = runWithCredentials(() -> getSpotifyService().getAlbumTracks(album.getId()));
        List<Playable> playables = playableFactory.createPlayables(shouldRedirectSpotify(), tracks);
        loadedAlbum = album;
        return playables;
    } else if (chosenOption instanceof AudioTrack) {
        Playable playable = playableFactory.createPlayable(shouldRedirectSpotify(), chosenOption);
        loadedAudioTrack = (AudioTrack) chosenOption;
        return Collections.singletonList(playable);
    } else if (chosenOption instanceof AudioPlaylist) {
        List<Playable> playables = playableFactory.createPlayables(shouldRedirectSpotify(), chosenOption);
        loadedAudioPlaylist = (AudioPlaylist) chosenOption;
        return playables;
    } else if (chosenOption instanceof ShowSimplified) {
        ShowSimplified show = (ShowSimplified) chosenOption;
        List<Episode> episodes = runWithCredentials(() -> getSpotifyService().getShowEpisodes(show.getId()));
        List<Playable> playables = playableFactory.createPlayables(shouldRedirectSpotify(), episodes);
        loadedShow = show;
        return playables;
    }
    throw new UnsupportedOperationException("Unsupported chosen option type: " + chosenOption.getClass());
}
Also used : ShowSimplified(se.michaelthelin.spotify.model_objects.specification.ShowSimplified) Episode(se.michaelthelin.spotify.model_objects.specification.Episode) Playable(net.robinfriedli.aiode.audio.Playable) YouTubePlaylist(net.robinfriedli.aiode.audio.youtube.YouTubePlaylist) AlbumSimplified(se.michaelthelin.spotify.model_objects.specification.AlbumSimplified) List(java.util.List) AudioTrack(com.sedmelluq.discord.lavaplayer.track.AudioTrack) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) Track(se.michaelthelin.spotify.model_objects.specification.Track) AudioTrack(com.sedmelluq.discord.lavaplayer.track.AudioTrack) PlaylistSimplified(se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified) AudioPlaylist(com.sedmelluq.discord.lavaplayer.track.AudioPlaylist)

Example 5 with SpotifyTrack

use of net.robinfriedli.aiode.audio.spotify.SpotifyTrack in project aiode by robinfriedli.

the class YouTubeService method getBestMatch.

private Video getBestMatch(List<Video> videos, SpotifyTrack spotifyTrack, StringList artists) {
    Video video;
    int size = videos.size();
    if (size == 1) {
        video = videos.get(0);
    } else {
        Map<Integer, Video> videosByScore = new HashMap<>();
        Map<Video, Integer> editDistanceMap = new HashMap<>();
        long[] viewCounts = new long[size];
        for (int i = 0; i < size; i++) {
            Video v = videos.get(i);
            viewCounts[i] = getViewCount(v);
            editDistanceMap.put(v, getBestEditDistance(spotifyTrack, v));
        }
        int index = 0;
        for (Video v : videos) {
            int artistMatchScore = 0;
            if (artists.stream().anyMatch(a -> {
                String artist = a.toLowerCase();
                String artistNoSpace = artist.replaceAll(" ", "");
                VideoSnippet snippet = v.getSnippet();
                if (snippet == null) {
                    return false;
                }
                String channelTitle = snippet.getChannelTitle();
                if (channelTitle == null) {
                    return false;
                }
                String channel = channelTitle.toLowerCase();
                String channelNoSpace = channel.replace(" ", "");
                return channel.contains(artist) || artist.contains(channel) || channelNoSpace.contains(artistNoSpace) || artistNoSpace.contains(channelNoSpace);
            })) {
                artistMatchScore = ARTIST_MATCH_SCORE_MULTIPLIER * size;
            }
            long viewCount = getViewCount(v);
            int editDistance = editDistanceMap.get(v);
            long viewRank = Arrays.stream(viewCounts).filter(c -> viewCount < c).count();
            long editDistanceRank = editDistanceMap.values().stream().filter(d -> d < editDistance).count();
            int viewScore = VIEW_SCORE_MULTIPLIER * (int) (size - viewRank);
            int editDistanceScore = EDIT_DISTANCE_SCORE_MULTIPLIER * (int) (size - editDistanceRank);
            int indexScore = INDEX_SCORE_MULTIPLIER * (size - index);
            int totalScore = artistMatchScore + viewScore + editDistanceScore + indexScore;
            videosByScore.putIfAbsent(totalScore, v);
            ++index;
        }
        @SuppressWarnings("OptionalGetWithoutIsPresent") int bestScore = videosByScore.keySet().stream().mapToInt(k -> k).max().getAsInt();
        video = videosByScore.get(bestScore);
    }
    return video;
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BigInteger(java.math.BigInteger) Arrays(java.util.Arrays) StringList(net.robinfriedli.stringlist.StringList) LoggerFactory(org.slf4j.LoggerFactory) VideoListResponse(com.google.api.services.youtube.model.VideoListResponse) SearchResult(com.google.api.services.youtube.model.SearchResult) CurrentYouTubeQuotaUsage(net.robinfriedli.aiode.entities.CurrentYouTubeQuotaUsage) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Map(java.util.Map) BigInteger(java.math.BigInteger) AudioTrackInfo(com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo) FriendlyException(com.sedmelluq.discord.lavaplayer.tools.FriendlyException) UnavailableResourceException(net.robinfriedli.aiode.exceptions.UnavailableResourceException) VideoContentDetails(com.google.api.services.youtube.model.VideoContentDetails) LevenshteinDistance(org.apache.commons.text.similarity.LevenshteinDistance) LoggingThreadFactory(net.robinfriedli.aiode.concurrent.LoggingThreadFactory) Playlist(com.google.api.services.youtube.model.Playlist) Collectors(java.util.stream.Collectors) Executors(java.util.concurrent.Executors) Objects(java.util.Objects) List(java.util.List) AbstractShutdownable(net.robinfriedli.aiode.boot.AbstractShutdownable) StaticSessionProvider(net.robinfriedli.aiode.persist.StaticSessionProvider) VideoSnippet(com.google.api.services.youtube.model.VideoSnippet) CommandRuntimeException(net.robinfriedli.aiode.exceptions.CommandRuntimeException) HibernateComponent(net.robinfriedli.aiode.boot.configurations.HibernateComponent) IntStream(java.util.stream.IntStream) NoResultsFoundException(net.robinfriedli.aiode.exceptions.NoResultsFoundException) PlayableFactory(net.robinfriedli.aiode.audio.PlayableFactory) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) Session(org.hibernate.Session) DependsOn(org.springframework.context.annotation.DependsOn) HashMap(java.util.HashMap) Callable(java.util.concurrent.Callable) AudioPlaylist(com.sedmelluq.discord.lavaplayer.track.AudioPlaylist) Value(org.springframework.beans.factory.annotation.Value) Strings(com.google.common.base.Strings) Lists(com.google.common.collect.Lists) QueueCommand(net.robinfriedli.aiode.command.commands.playback.QueueCommand) PlaylistItem(com.google.api.services.youtube.model.PlaylistItem) Video(com.google.api.services.youtube.model.Video) ExecutorService(java.util.concurrent.ExecutorService) Nullable(javax.annotation.Nullable) PlayCommand(net.robinfriedli.aiode.command.commands.playback.PlayCommand) Logger(org.slf4j.Logger) ArtistSimplified(se.michaelthelin.spotify.model_objects.specification.ArtistSimplified) IOException(java.io.IOException) YouTube(com.google.api.services.youtube.YouTube) HibernateInvoker(net.robinfriedli.aiode.function.HibernateInvoker) VideoStatistics(com.google.api.services.youtube.model.VideoStatistics) AudioItem(com.sedmelluq.discord.lavaplayer.track.AudioItem) Aiode(net.robinfriedli.aiode.Aiode) PlaylistItemListResponse(com.google.api.services.youtube.model.PlaylistItemListResponse) ShowSimplified(se.michaelthelin.spotify.model_objects.specification.ShowSimplified) Component(org.springframework.stereotype.Component) ChronoUnit(java.time.temporal.ChronoUnit) AudioTrackLoader(net.robinfriedli.aiode.audio.AudioTrackLoader) EagerFetchQueue(net.robinfriedli.aiode.concurrent.EagerFetchQueue) AudioTrack(com.sedmelluq.discord.lavaplayer.track.AudioTrack) LockModeType(javax.persistence.LockModeType) VideoSnippet(com.google.api.services.youtube.model.VideoSnippet) HashMap(java.util.HashMap) Video(com.google.api.services.youtube.model.Video)

Aggregations

SpotifyTrack (net.robinfriedli.aiode.audio.spotify.SpotifyTrack)13 List (java.util.List)10 StringList (net.robinfriedli.stringlist.StringList)9 ShowSimplified (se.michaelthelin.spotify.model_objects.specification.ShowSimplified)8 YouTubePlaylist (net.robinfriedli.aiode.audio.youtube.YouTubePlaylist)7 YouTubeVideo (net.robinfriedli.aiode.audio.youtube.YouTubeVideo)7 InvalidCommandException (net.robinfriedli.aiode.exceptions.InvalidCommandException)7 AlbumSimplified (se.michaelthelin.spotify.model_objects.specification.AlbumSimplified)7 PlaylistSimplified (se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified)7 IOException (java.io.IOException)6 NoResultsFoundException (net.robinfriedli.aiode.exceptions.NoResultsFoundException)6 Episode (se.michaelthelin.spotify.model_objects.specification.Episode)6 Track (se.michaelthelin.spotify.model_objects.specification.Track)6 AudioPlaylist (com.sedmelluq.discord.lavaplayer.track.AudioPlaylist)5 AudioTrack (com.sedmelluq.discord.lavaplayer.track.AudioTrack)5 Objects (java.util.Objects)5 Collectors (java.util.stream.Collectors)5 YouTubeService (net.robinfriedli.aiode.audio.youtube.YouTubeService)5 Collection (java.util.Collection)4 NoSpotifyResultsFoundException (net.robinfriedli.aiode.exceptions.NoSpotifyResultsFoundException)4