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);
});
}
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;
}
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);
}
}));
}
}
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);
}
});
}
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));
}
}
Aggregations