Search in sources :

Example 1 with HollowYouTubeVideo

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

the class AddCommand method addPlayables.

private void addPlayables(Playlist playlist, List<Playable> playables) {
    if ((getTask() != null && getTask().isTerminated()) || Thread.currentThread().isInterrupted()) {
        return;
    }
    Session session = getContext().getSession();
    List<PlaylistItem> items = Lists.newArrayList();
    invoke(() -> {
        playables.forEach(playable -> {
            if (playable instanceof HollowYouTubeVideo && ((HollowYouTubeVideo) playable).isCanceled()) {
                return;
            }
            items.add(playable.export(playlist, getContext().getUser(), session));
        });
        addToList(playlist, items);
    });
}
Also used : HollowYouTubeVideo(net.robinfriedli.aiode.audio.youtube.HollowYouTubeVideo) PlaylistItem(net.robinfriedli.aiode.entities.PlaylistItem) Session(org.hibernate.Session)

Example 2 with HollowYouTubeVideo

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

the class PlayableFactory method createPlayables.

/**
 * Creates Playables for a Collection of Objects; YouTube videos or Spotify Tracks.
 *
 * @param redirectSpotify if true the matching YouTube video is loaded to play the full track using
 *                        {@link YouTubeService#redirectSpotify(HollowYouTubeVideo)}, else a {@link PlayableTrackWrapper} is created to play the
 *                        preview mp3 provided by Spotify
 * @param items           the objects to create a Playable for
 * @return the created Playables
 */
public List<Playable> createPlayables(boolean redirectSpotify, Collection<?> items) {
    List<Playable> playables = Lists.newArrayList();
    List<HollowYouTubeVideo> tracksToRedirect = Lists.newArrayList();
    List<YouTubePlaylist> youTubePlaylistsToLoad = Lists.newArrayList();
    try {
        for (Object item : items) {
            if (item instanceof Playable) {
                playables.add((Playable) item);
            } else if (item instanceof Track) {
                handleTrack(SpotifyTrack.wrap((Track) item), redirectSpotify, tracksToRedirect, playables);
            } else if (item instanceof Episode) {
                handleTrack(SpotifyTrack.wrap((Episode) item), redirectSpotify, tracksToRedirect, playables);
            } else if (item instanceof SpotifyTrack) {
                handleTrack((SpotifyTrack) item, redirectSpotify, tracksToRedirect, playables);
            } else if (item instanceof UrlTrack) {
                playables.add(((UrlTrack) item).asPlayable());
            } else if (item instanceof YouTubePlaylist) {
                YouTubePlaylist youTubePlaylist = ((YouTubePlaylist) item);
                playables.addAll(youTubePlaylist.getVideos());
                youTubePlaylistsToLoad.add(youTubePlaylist);
            } else if (item instanceof PlaylistSimplified) {
                List<SpotifyTrack> t = SpotifyInvoker.create(spotifyService.getSpotifyApi()).invoke(() -> spotifyService.getPlaylistTracks((PlaylistSimplified) item));
                for (SpotifyTrack track : t) {
                    handleTrack(track, redirectSpotify, tracksToRedirect, playables);
                }
            } else if (item instanceof AlbumSimplified) {
                List<Track> t = invoker.invoke(() -> spotifyService.getAlbumTracks((AlbumSimplified) item));
                for (Track track : t) {
                    handleTrack(SpotifyTrack.wrapIfNotNull(track), redirectSpotify, tracksToRedirect, playables);
                }
            } else if (item instanceof AudioTrack) {
                playables.add(new UrlPlayable((AudioTrack) item));
            } else if (item instanceof AudioPlaylist) {
                List<Playable> convertedPlayables = ((AudioPlaylist) item).getTracks().stream().map(UrlPlayable::new).collect(Collectors.toList());
                playables.addAll(convertedPlayables);
            } else if (item != null) {
                throw new UnsupportedOperationException("Unsupported playable " + item.getClass());
            }
        }
    } catch (Exception e) {
        throw new RuntimeException("Exception while creating Playables", e);
    }
    if (!tracksToRedirect.isEmpty() || !youTubePlaylistsToLoad.isEmpty()) {
        trackLoadingExecutor.execute(new SpotifyTrackRedirectionRunnable(tracksToRedirect, youTubeService).andThen(new YouTubePlaylistPopulationRunnable(youTubePlaylistsToLoad, youTubeService)));
    }
    return playables;
}
Also used : NoResultsFoundException(net.robinfriedli.aiode.exceptions.NoResultsFoundException) NotFoundException(se.michaelthelin.spotify.exceptions.detailed.NotFoundException) InvalidCommandException(net.robinfriedli.aiode.exceptions.InvalidCommandException) ParseException(org.apache.hc.core5.http.ParseException) SpotifyWebApiException(se.michaelthelin.spotify.exceptions.SpotifyWebApiException) IOException(java.io.IOException) Episode(se.michaelthelin.spotify.model_objects.specification.Episode) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) UrlTrack(net.robinfriedli.aiode.entities.UrlTrack) YouTubePlaylist(net.robinfriedli.aiode.audio.youtube.YouTubePlaylist) HollowYouTubeVideo(net.robinfriedli.aiode.audio.youtube.HollowYouTubeVideo) AlbumSimplified(se.michaelthelin.spotify.model_objects.specification.AlbumSimplified) StringList(net.robinfriedli.stringlist.StringList) List(java.util.List) AudioTrack(com.sedmelluq.discord.lavaplayer.track.AudioTrack) SpotifyTrackRedirectionRunnable(net.robinfriedli.aiode.audio.exec.SpotifyTrackRedirectionRunnable) SpotifyTrack(net.robinfriedli.aiode.audio.spotify.SpotifyTrack) Track(se.michaelthelin.spotify.model_objects.specification.Track) AudioTrack(com.sedmelluq.discord.lavaplayer.track.AudioTrack) UrlTrack(net.robinfriedli.aiode.entities.UrlTrack) YouTubePlaylistPopulationRunnable(net.robinfriedli.aiode.audio.exec.YouTubePlaylistPopulationRunnable) PlaylistSimplified(se.michaelthelin.spotify.model_objects.specification.PlaylistSimplified) AudioPlaylist(com.sedmelluq.discord.lavaplayer.track.AudioPlaylist)

Example 3 with HollowYouTubeVideo

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

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

the class ExportCommand method doRun.

@Override
public void doRun() {
    Session session = getContext().getSession();
    Guild guild = getContext().getGuild();
    AudioQueue queue = Aiode.get().getAudioManager().getQueue(guild);
    if (queue.isEmpty()) {
        throw new InvalidCommandException("Queue is empty");
    }
    Playlist existingPlaylist = SearchEngine.searchLocalList(session, getCommandInput());
    if (existingPlaylist != null) {
        throw new InvalidCommandException("Playlist " + getCommandInput() + " already exists");
    }
    List<Playable> tracks = queue.getTracks();
    User createUser = getContext().getUser();
    Playlist playlist = new Playlist(getCommandInput(), createUser, guild);
    invoke(() -> {
        session.persist(playlist);
        for (Playable track : tracks) {
            if (track instanceof HollowYouTubeVideo) {
                HollowYouTubeVideo video = (HollowYouTubeVideo) track;
                video.awaitCompletion();
                if (video.isCanceled()) {
                    continue;
                }
            }
            PlaylistItem export = track.export(playlist, getContext().getUser(), session);
            export.add();
            session.persist(export);
        }
    });
}
Also used : Playlist(net.robinfriedli.aiode.entities.Playlist) User(net.dv8tion.jda.api.entities.User) InvalidCommandException(net.robinfriedli.aiode.exceptions.InvalidCommandException) Playable(net.robinfriedli.aiode.audio.Playable) HollowYouTubeVideo(net.robinfriedli.aiode.audio.youtube.HollowYouTubeVideo) Guild(net.dv8tion.jda.api.entities.Guild) AudioQueue(net.robinfriedli.aiode.audio.AudioQueue) PlaylistItem(net.robinfriedli.aiode.entities.PlaylistItem) Session(org.hibernate.Session)

Example 5 with HollowYouTubeVideo

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

the class PlayableFactory method handleTrack.

private void handleTrack(SpotifyTrack track, boolean redirectSpotify, List<HollowYouTubeVideo> tracksToRedirect, List<Playable> playables) {
    if (track == null) {
        return;
    }
    if (redirectSpotify) {
        HollowYouTubeVideo youTubeVideo = new HollowYouTubeVideo(youTubeService, track);
        tracksToRedirect.add(youTubeVideo);
        playables.add(youTubeVideo);
    } else {
        playables.add(new PlayableTrackWrapper(track));
    }
}
Also used : PlayableTrackWrapper(net.robinfriedli.aiode.audio.spotify.PlayableTrackWrapper) HollowYouTubeVideo(net.robinfriedli.aiode.audio.youtube.HollowYouTubeVideo)

Aggregations

HollowYouTubeVideo (net.robinfriedli.aiode.audio.youtube.HollowYouTubeVideo)5 Session (org.hibernate.Session)3 IOException (java.io.IOException)2 PlaylistItem (net.robinfriedli.aiode.entities.PlaylistItem)2 InvalidCommandException (net.robinfriedli.aiode.exceptions.InvalidCommandException)2 Strings (com.google.common.base.Strings)1 AudioPlaylist (com.sedmelluq.discord.lavaplayer.track.AudioPlaylist)1 AudioTrack (com.sedmelluq.discord.lavaplayer.track.AudioTrack)1 LocalDate (java.time.LocalDate)1 List (java.util.List)1 Optional (java.util.Optional)1 ExecutorService (java.util.concurrent.ExecutorService)1 Executors (java.util.concurrent.Executors)1 BiConsumer (java.util.function.BiConsumer)1 Guild (net.dv8tion.jda.api.entities.Guild)1 User (net.dv8tion.jda.api.entities.User)1 Aiode (net.robinfriedli.aiode.Aiode)1 AudioQueue (net.robinfriedli.aiode.audio.AudioQueue)1 Playable (net.robinfriedli.aiode.audio.Playable)1 SpotifyTrackRedirectionRunnable (net.robinfriedli.aiode.audio.exec.SpotifyTrackRedirectionRunnable)1