use of se.michaelthelin.spotify.model_objects.specification.ShowSimplified in project aiode by robinfriedli.
the class Episode method initShow.
private void initShow(se.michaelthelin.spotify.model_objects.specification.Episode episode) {
ShowSimplified show = episode.getShow();
if (show != null) {
showId = show.getId();
showName = show.getName();
}
}
use of se.michaelthelin.spotify.model_objects.specification.ShowSimplified in project aiode by robinfriedli.
the class AbstractPlayableLoadingCommand method loadSpotifyShow.
private void loadSpotifyShow(AudioManager audioManager) throws Exception {
int limit = getArgumentValueWithTypeOrElse("select", Integer.class, 20);
Callable<List<ShowSimplified>> albumLoadCallable = () -> getSpotifyService().searchShow(getCommandInput(), argumentSet("own"), limit);
List<ShowSimplified> shows;
if (argumentSet("own")) {
shows = runWithLogin(albumLoadCallable);
} else {
shows = runWithCredentials(albumLoadCallable);
}
if (shows.size() == 1) {
ShowSimplified show = shows.get(0);
List<Episode> episodes = runWithCredentials(() -> getSpotifyService().getShowEpisodes(show.getId()));
PlayableFactory playableFactory = audioManager.createPlayableFactory(getSpotifyService(), trackLoadingExecutor);
List<Playable> playables = playableFactory.createPlayables(shouldRedirectSpotify(), episodes);
handleResults(playables);
loadedShow = show;
} else if (shows.isEmpty()) {
throw new NoSpotifyResultsFoundException(String.format("No shows found for '%s'", getCommandInput()));
} else {
askQuestion(shows, ShowSimplified::getName, ShowSimplified::getPublisher);
}
}
use of se.michaelthelin.spotify.model_objects.specification.ShowSimplified 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 se.michaelthelin.spotify.model_objects.specification.ShowSimplified in project aiode by robinfriedli.
the class SpotifyTrack method getDisplay.
public String getDisplay() {
String name = getName();
String artistString = exhaustiveMatch(track -> StringList.create(track.getArtists(), ArtistSimplified::getName).toSeparatedString(", "), episode -> {
ShowSimplified show = episode.getShow();
if (show != null) {
return show.getName();
}
return null;
});
if (!Strings.isNullOrEmpty(artistString)) {
return String.format("%s by %s", name, artistString);
} else {
return name;
}
}
use of se.michaelthelin.spotify.model_objects.specification.ShowSimplified in project aiode by robinfriedli.
the class YouTubeService method redirectSpotify.
/**
* Workaround as Spotify does not allow full playback of tracks via third party APIs using the web api for licencing
* reasons. Gets the metadata and searches the corresponding YouTube video. The only way to stream from Spotify
* directly is by using the $preview argument with the {@link PlayCommand} or {@link QueueCommand} which plays the
* provided mp3 preview.
* <p>
* However Spotify MIGHT release an SDK supporting full playback of songs across all devices, not just browsers in
* which case this method and the corresponding block in {@link PlayableFactory#createPlayable(boolean, Object)} should
* be removed.
* For reference, see <a href="https://github.com/spotify/web-api/issues/57">Web playback of Full Tracks - Github</a>
* <p>
* This method searches 5 youtube videos using the Spotify track name + artist and then uses a combination of
* levenshtein distance, whether or not the channel title matches the artist, the view count and the index in the
* youtube response to determine the best match.
* <p>
* If the current YouTube API quota usage is beneath the threshold then this action
* will use the YouTube API, costing {@link #QUOTA_COST_SEARCH} + {@link #QUOTA_COST_LIST} (this also applies
* when searching with lavaplayer) quota. Else this uses lavaplayer to load the video metadata by scraping the HTML
* page returned by YouTube.
*
* @param youTubeVideo the hollow youtube that has already been added to the queue and awaits to receive values
*/
public void redirectSpotify(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");
}
StringList artists = spotifyTrack.exhaustiveMatch(track -> StringList.create(track.getArtists(), ArtistSimplified::getName), episode -> {
ShowSimplified show = episode.getShow();
if (show != null) {
return StringList.of(show.getName());
}
return StringList.create();
});
String searchTerm = spotifyTrack.getName() + " " + artists.toSeparatedString(" ");
List<String> videoIds;
if (currentQuota.get() < quotaThreshold) {
YouTube.Search.List search = youTube.search().list(List.of("id", "snippet"));
search.setKey(apiKey);
search.setQ(searchTerm);
// set topic to filter results to music video
search.setTopicId("/m/04rlf");
search.setType(List.of("video"));
search.setFields("items(snippet/title,id/videoId)");
search.setMaxResults((long) REDIRECT_SEARCH_AMOUNT);
List<SearchResult> items = doWithQuota(QUOTA_COST_SEARCH, () -> search.execute().getItems());
if (items.isEmpty()) {
youTubeVideo.cancel();
return;
}
videoIds = items.stream().map(item -> item.getId().getVideoId()).collect(Collectors.toList());
} else {
AudioTrackLoader audioTrackLoader = new AudioTrackLoader(Aiode.get().getAudioManager().getPlayerManager());
AudioItem audioItem;
try {
audioItem = audioTrackLoader.loadByIdentifier("ytsearch:" + searchTerm);
} catch (FriendlyException e) {
youTubeVideo.cancel();
return;
}
if (!(audioItem instanceof AudioPlaylist)) {
youTubeVideo.cancel();
return;
}
AudioPlaylist resultList = (AudioPlaylist) audioItem;
List<AudioTrack> tracks = resultList.getTracks();
if (tracks.isEmpty()) {
youTubeVideo.cancel();
return;
}
List<AudioTrack> audioTracks = tracks.subList(0, Math.min(tracks.size(), REDIRECT_SEARCH_AMOUNT));
videoIds = audioTracks.stream().map(AudioTrack::getIdentifier).collect(Collectors.toList());
}
List<Video> videos = getAllVideos(videoIds);
if (videos.isEmpty()) {
youTubeVideo.cancel();
return;
}
Video video = getBestMatch(videos, spotifyTrack, artists);
String videoId = video.getId();
long durationMillis = getDurationMillis(videoId);
String artistString = artists.toSeparatedString(", ");
String title = spotifyTrack.getName() + " by " + artistString;
youTubeVideo.setTitle(title);
youTubeVideo.setId(videoId);
youTubeVideo.setDuration(durationMillis);
}
Aggregations