Search in sources :

Example 1 with YouTubeVideo

use of net.robinfriedli.aiode.audio.youtube.YouTubeVideo in project aiode by robinfriedli.

the class Playlist method getTracks.

/**
 * Returns the items in this playlist as objects supported by the {@link PlayableFactory} class. Note that getting the
 * Spotify track for a Song requires this method to be invoked with client credentials
 */
public List<Object> getTracks(SpotifyApi spotifyApi) {
    List<PlaylistItem> playlistItems = getItemsSorted();
    SpotifyTrackBulkLoadingService service = new SpotifyTrackBulkLoadingService(spotifyApi);
    Map<Object, Integer> itemsWithIndex = new HashMap<>();
    for (int i = 0; i < playlistItems.size(); i++) {
        PlaylistItem item = playlistItems.get(i);
        if (item instanceof Song) {
            String id = ((Song) item).getId();
            int finalI = i;
            service.add(createItem(id, TRACK), track -> itemsWithIndex.put(track, finalI));
        } else if (item instanceof Episode) {
            String id = ((Episode) item).getId();
            int finalI = i;
            service.add(createItem(id, EPISODE), track -> itemsWithIndex.put(track, finalI));
        } else if (item instanceof Video) {
            Video video = (Video) item;
            YouTubeVideo youtubeVideo = video.asYouTubeVideo();
            itemsWithIndex.put(youtubeVideo, i);
            String spotifyId = video.getRedirectedSpotifyId();
            if (!Strings.isNullOrEmpty(spotifyId)) {
                SpotifyItemKind kindEntity = video.getRedirectedSpotifyKind();
                SpotifyTrackKind kind = kindEntity != null ? kindEntity.asEnum() : TRACK;
                service.add(createItem(spotifyId, kind), youtubeVideo::setRedirectedSpotifyTrack);
            }
        } else if (item instanceof UrlTrack) {
            itemsWithIndex.put(item, i);
        }
    }
    service.perform();
    return itemsWithIndex.keySet().stream().sorted(Comparator.comparing(itemsWithIndex::get)).collect(Collectors.toList());
}
Also used : Size(javax.validation.constraints.Size) PlayableFactory(net.robinfriedli.aiode.audio.PlayableFactory) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) HashMap(java.util.HashMap) User(net.dv8tion.jda.api.entities.User) Strings(com.google.common.base.Strings) Table(javax.persistence.Table) Lists(com.google.common.collect.Lists) Guild(net.dv8tion.jda.api.entities.Guild) Map(java.util.Map) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) Id(javax.persistence.Id) Entity(javax.persistence.Entity) Collection(java.util.Collection) OneToMany(javax.persistence.OneToMany) Set(java.util.Set) Collectors(java.util.stream.Collectors) SpotifyTrackKind(net.robinfriedli.aiode.audio.spotify.SpotifyTrackKind) SpotifyTrackBulkLoadingService(net.robinfriedli.aiode.audio.spotify.SpotifyTrackBulkLoadingService) Serializable(java.io.Serializable) Objects(java.util.Objects) SpotifyApi(se.michaelthelin.spotify.SpotifyApi) Column(javax.persistence.Column) GenerationType(javax.persistence.GenerationType) List(java.util.List) Stream(java.util.stream.Stream) GeneratedValue(javax.persistence.GeneratedValue) SpringPropertiesConfig(net.robinfriedli.aiode.boot.SpringPropertiesConfig) Comparator(java.util.Comparator) Sets(com.google.api.client.util.Sets) HashMap(java.util.HashMap) SpotifyTrackBulkLoadingService(net.robinfriedli.aiode.audio.spotify.SpotifyTrackBulkLoadingService) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) SpotifyTrackKind(net.robinfriedli.aiode.audio.spotify.SpotifyTrackKind) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo)

Example 2 with YouTubeVideo

use of net.robinfriedli.aiode.audio.youtube.YouTubeVideo 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 3 with YouTubeVideo

use of net.robinfriedli.aiode.audio.youtube.YouTubeVideo in project aiode by robinfriedli.

the class SpotifyRedirectService method redirectTrack.

public void redirectTrack(HollowYouTubeVideo youTubeVideo) throws IOException {
    SpotifyTrack spotifyTrack = youTubeVideo.getRedirectedSpotifyTrack();
    if (spotifyTrack == null) {
        throw new IllegalArgumentException(youTubeVideo.toString() + " is not a placeholder for a redirected Spotify Track");
    }
    // early exit to avoid duplicate loading of Playables that have been loaded prioritised by invoking Playable#fetchNow
    if (youTubeVideo.isDone()) {
        return;
    }
    youTubeVideo.markLoading();
    String spotifyTrackId = spotifyTrack.getId();
    Optional<SpotifyRedirectIndex> persistedSpotifyRedirectIndex;
    if (!Strings.isNullOrEmpty(spotifyTrackId)) {
        persistedSpotifyRedirectIndex = queryExistingIndex(session, spotifyTrackId);
    } else {
        persistedSpotifyRedirectIndex = Optional.empty();
    }
    if (persistedSpotifyRedirectIndex.isPresent()) {
        SpotifyRedirectIndex spotifyRedirectIndex = persistedSpotifyRedirectIndex.get();
        YouTubeVideo video = youTubeService.getVideoForId(spotifyRedirectIndex.getYouTubeId());
        if (video != null) {
            try {
                youTubeVideo.setId(video.getVideoId());
                youTubeVideo.setDuration(video.getDuration());
            } catch (UnavailableResourceException e) {
                // never happens for YouTubeVideoImpl instances
                throw new RuntimeException(e);
            }
            youTubeVideo.setTitle(spotifyTrack.getDisplay());
            runUpdateTask(spotifyTrackId, (index, session) -> index.setLastUsed(LocalDate.now()));
            return;
        } else {
            runUpdateTask(spotifyTrackId, (index, session) -> session.delete(index));
        }
    }
    youTubeService.redirectSpotify(youTubeVideo);
    if (!youTubeVideo.isCanceled() && !Strings.isNullOrEmpty(spotifyTrack.getId())) {
        SINGE_THREAD_EXECUTOR_SERVICE.execute(() -> StaticSessionProvider.consumeSession(otherThreadSession -> {
            try {
                String videoId = youTubeVideo.getVideoId();
                SpotifyRedirectIndex spotifyRedirectIndex = new SpotifyRedirectIndex(spotifyTrack.getId(), videoId, spotifyTrack.getKind(), otherThreadSession);
                // check again if the index was not created by other thread
                if (queryExistingIndex(otherThreadSession, spotifyTrackId).isEmpty()) {
                    invoker.invoke(() -> otherThreadSession.persist(spotifyRedirectIndex));
                }
            } catch (UnavailableResourceException e) {
                logger.warn("Tried creating a SpotifyRedirectIndex for an unavailable Track");
            } catch (Exception e) {
                logger.error("Exception while creating SpotifyRedirectIndex", e);
            }
        }));
    }
}
Also used : Logger(org.slf4j.Logger) UnavailableResourceException(net.robinfriedli.aiode.exceptions.UnavailableResourceException) LoggerFactory(org.slf4j.LoggerFactory) Session(org.hibernate.Session) IOException(java.io.IOException) LoggingThreadFactory(net.robinfriedli.aiode.concurrent.LoggingThreadFactory) SpotifyRedirectIndex(net.robinfriedli.aiode.entities.SpotifyRedirectIndex) SpotifyRedirectIndexModificationLock(net.robinfriedli.aiode.entities.SpotifyRedirectIndexModificationLock) HibernateInvoker(net.robinfriedli.aiode.function.HibernateInvoker) Executors(java.util.concurrent.Executors) Aiode(net.robinfriedli.aiode.Aiode) Strings(com.google.common.base.Strings) HollowYouTubeVideo(net.robinfriedli.aiode.audio.youtube.HollowYouTubeVideo) LocalDate(java.time.LocalDate) BiConsumer(java.util.function.BiConsumer) Optional(java.util.Optional) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) StaticSessionProvider(net.robinfriedli.aiode.persist.StaticSessionProvider) ShutdownableExecutorService(net.robinfriedli.aiode.boot.ShutdownableExecutorService) ExecutorService(java.util.concurrent.ExecutorService) YouTubeService(net.robinfriedli.aiode.audio.youtube.YouTubeService) SpotifyRedirectIndex(net.robinfriedli.aiode.entities.SpotifyRedirectIndex) UnavailableResourceException(net.robinfriedli.aiode.exceptions.UnavailableResourceException) HollowYouTubeVideo(net.robinfriedli.aiode.audio.youtube.HollowYouTubeVideo) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) UnavailableResourceException(net.robinfriedli.aiode.exceptions.UnavailableResourceException) IOException(java.io.IOException)

Example 4 with YouTubeVideo

use of net.robinfriedli.aiode.audio.youtube.YouTubeVideo in project aiode by robinfriedli.

the class AbstractPlayableLoadingCommand method loadYouTubeVideo.

private void loadYouTubeVideo(AudioManager audioManager) throws IOException {
    YouTubeService youTubeService = audioManager.getYouTubeService();
    if (argumentSet("select")) {
        int limit = getArgumentValueWithTypeOrElse("select", Integer.class, 10);
        List<YouTubeVideo> youTubeVideos = youTubeService.searchSeveralVideos(limit, getCommandInput());
        if (youTubeVideos.size() == 1) {
            Playable playable = youTubeVideos.get(0);
            handleResults(Lists.newArrayList(playable));
            loadedTrack = playable;
        } else if (youTubeVideos.isEmpty()) {
            throw new NoResultsFoundException(String.format("No YouTube video found for '%s'", getCommandInput()));
        } else {
            askQuestion(youTubeVideos, youTubeVideo -> {
                try {
                    return youTubeVideo.getDisplay();
                } catch (UnavailableResourceException e) {
                    // Unreachable since only HollowYouTubeVideos might get interrupted
                    throw new RuntimeException(e);
                }
            });
        }
    } else {
        YouTubeVideo youTubeVideo = youTubeService.searchVideo(getCommandInput());
        handleResults(Lists.newArrayList(youTubeVideo));
        loadedTrack = youTubeVideo;
    }
}
Also used : StringList(net.robinfriedli.stringlist.StringList) NoResultsFoundException(net.robinfriedli.aiode.exceptions.NoResultsFoundException) PlayableFactory(net.robinfriedli.aiode.audio.PlayableFactory) UrlPlayable(net.robinfriedli.aiode.audio.UrlPlayable) YouTubePlaylist(net.robinfriedli.aiode.audio.youtube.YouTubePlaylist) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) Playable(net.robinfriedli.aiode.audio.Playable) Episode(se.michaelthelin.spotify.model_objects.specification.Episode) Callable(java.util.concurrent.Callable) AudioPlaylist(com.sedmelluq.discord.lavaplayer.track.AudioPlaylist) Lists(com.google.common.collect.Lists) Playlist(net.robinfriedli.aiode.entities.Playlist) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) SearchEngine(net.robinfriedli.aiode.util.SearchEngine) Track(se.michaelthelin.spotify.model_objects.specification.Track) CommandContribution(net.robinfriedli.aiode.entities.xml.CommandContribution) SpotifyUri(net.robinfriedli.aiode.audio.spotify.SpotifyUri) UnavailableResourceException(net.robinfriedli.aiode.exceptions.UnavailableResourceException) ArtistSimplified(se.michaelthelin.spotify.model_objects.specification.ArtistSimplified) CommandManager(net.robinfriedli.aiode.command.CommandManager) AudioPlayback(net.robinfriedli.aiode.audio.AudioPlayback) IOException(java.io.IOException) AudioManager(net.robinfriedli.aiode.audio.AudioManager) NoSpotifyResultsFoundException(net.robinfriedli.aiode.exceptions.NoSpotifyResultsFoundException) AudioItem(com.sedmelluq.discord.lavaplayer.track.AudioItem) UrlValidator(org.apache.commons.validator.routines.UrlValidator) Aiode(net.robinfriedli.aiode.Aiode) ShowSimplified(se.michaelthelin.spotify.model_objects.specification.ShowSimplified) List(java.util.List) AudioTrackLoader(net.robinfriedli.aiode.audio.AudioTrackLoader) SpotifyTrackResultHandler(net.robinfriedli.aiode.audio.spotify.SpotifyTrackResultHandler) SpotifyService(net.robinfriedli.aiode.audio.spotify.SpotifyService) CommandContext(net.robinfriedli.aiode.command.CommandContext) PlaylistSimplified(se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified) AlbumSimplified(se.michaelthelin.spotify.model_objects.specification.AlbumSimplified) AudioTrack(com.sedmelluq.discord.lavaplayer.track.AudioTrack) TrackLoadingExecutor(net.robinfriedli.aiode.audio.exec.TrackLoadingExecutor) YouTubeService(net.robinfriedli.aiode.audio.youtube.YouTubeService) NoResultsFoundException(net.robinfriedli.aiode.exceptions.NoResultsFoundException) UrlPlayable(net.robinfriedli.aiode.audio.UrlPlayable) Playable(net.robinfriedli.aiode.audio.Playable) UnavailableResourceException(net.robinfriedli.aiode.exceptions.UnavailableResourceException) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) YouTubeService(net.robinfriedli.aiode.audio.youtube.YouTubeService)

Example 5 with YouTubeVideo

use of net.robinfriedli.aiode.audio.youtube.YouTubeVideo in project aiode by robinfriedli.

the class SearchCommand method withUserResponse.

@Override
public void withUserResponse(Object chosenOption) throws Exception {
    if (chosenOption instanceof Collection) {
        throw new InvalidCommandException("Cannot select more than one result");
    }
    if (chosenOption instanceof PlaylistSimplified) {
        PlaylistSimplified playlist = (PlaylistSimplified) chosenOption;
        List<SpotifyTrack> tracks = runWithCredentials(() -> getSpotifyService().getPlaylistTracks(playlist));
        listTracks(tracks, playlist.getName(), playlist.getOwner().getDisplayName(), null, "playlist/" + playlist.getId());
    } else if (chosenOption instanceof YouTubePlaylist) {
        listYouTubePlaylist((YouTubePlaylist) chosenOption);
    } else if (chosenOption instanceof YouTubeVideo) {
        listYouTubeVideo((YouTubeVideo) chosenOption);
    } else if (chosenOption instanceof AlbumSimplified) {
        AlbumSimplified album = (AlbumSimplified) chosenOption;
        List<SpotifyTrack> tracks = runWithCredentials(() -> getSpotifyService().getAlbumTracks(album.getId())).stream().filter(Objects::nonNull).map(SpotifyTrack::wrap).collect(Collectors.toList());
        listTracks(tracks, album.getName(), null, StringList.create(album.getArtists(), ArtistSimplified::getName).toSeparatedString(", "), "album/" + album.getId());
    } else if (chosenOption instanceof ShowSimplified) {
        ShowSimplified show = (ShowSimplified) chosenOption;
        List<SpotifyTrack> tracks = runWithCredentials(() -> getSpotifyService().getShowEpisodes(show.getId())).stream().filter(Objects::nonNull).map(SpotifyTrack::wrap).collect(Collectors.toList());
        listTracks(tracks, show.getName(), show.getPublisher(), null, "show/" + show.getId());
    }
}
Also used : ShowSimplified(se.michaelthelin.spotify.model_objects.specification.ShowSimplified) InvalidCommandException(net.robinfriedli.aiode.exceptions.InvalidCommandException) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) YouTubePlaylist(net.robinfriedli.aiode.audio.youtube.YouTubePlaylist) Objects(java.util.Objects) Collection(java.util.Collection) AlbumSimplified(se.michaelthelin.spotify.model_objects.specification.AlbumSimplified) StringList(net.robinfriedli.stringlist.StringList) List(java.util.List) YouTubeVideo(net.robinfriedli.aiode.audio.youtube.YouTubeVideo) PlaylistSimplified(se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified)

Aggregations

YouTubeVideo (net.robinfriedli.aiode.audio.youtube.YouTubeVideo)7 List (java.util.List)5 SpotifyTrack (net.robinfriedli.aiode.audio.spotify.SpotifyTrack)5 YouTubePlaylist (net.robinfriedli.aiode.audio.youtube.YouTubePlaylist)5 IOException (java.io.IOException)3 Collection (java.util.Collection)3 Objects (java.util.Objects)3 Aiode (net.robinfriedli.aiode.Aiode)3 InvalidCommandException (net.robinfriedli.aiode.exceptions.InvalidCommandException)3 StringList (net.robinfriedli.stringlist.StringList)3 AlbumSimplified (se.michaelthelin.spotify.model_objects.specification.AlbumSimplified)3 PlaylistSimplified (se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified)3 ShowSimplified (se.michaelthelin.spotify.model_objects.specification.ShowSimplified)3 Strings (com.google.common.base.Strings)2 Lists (com.google.common.collect.Lists)2 AudioPlaylist (com.sedmelluq.discord.lavaplayer.track.AudioPlaylist)2 AudioTrack (com.sedmelluq.discord.lavaplayer.track.AudioTrack)2 Callable (java.util.concurrent.Callable)2 Collectors (java.util.stream.Collectors)2 User (net.dv8tion.jda.api.entities.User)2