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