Auto flow is back online !

This commit is contained in:
Sebastien 2020-04-12 18:23:06 +02:00
parent da6756c829
commit 010627a9b6
5 changed files with 177 additions and 157 deletions

View File

@ -54,8 +54,7 @@ public class MusicWebAPIController {
if (guild == null) { if (guild == null) {
logger.warn("Request whit no guild!"); logger.warn("Request whit no guild!");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST); return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
} } else {
else{
logger.trace("currentMusicInfo for " + guild.getName()); logger.trace("currentMusicInfo for " + guild.getName());
} }
@ -63,14 +62,12 @@ public class MusicWebAPIController {
if (guild.getAudioManager().isConnected()) { if (guild.getAudioManager().isConnected()) {
AudioPlayer player = AudioM.getInstance(guild).getGuildMusicManager().player; AudioPlayer player = AudioM.getInstance(guild).getGuildMusicManager().player;
AudioTrack currentTrack = player.getPlayingTrack(); AudioTrack currentTrack = player.getPlayingTrack();
if(currentTrack == null) if (currentTrack == null) {
{
return new ResponseEntity<>(new CurrentMusicData(null, 0, "STOP", false, AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()), HttpStatus.OK); return new ResponseEntity<>(new CurrentMusicData(null, 0, "STOP", false, AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()), HttpStatus.OK);
} }
UserAudioTrackData uat = new UserAudioTrackData(AudioM.getInstance(guild).getGuildMusicManager().scheduler.getCurrentPlayingTrack()); UserAudioTrackData uat = new UserAudioTrackData(AudioM.getInstance(guild).getGuildMusicManager().scheduler.getCurrentPlayingTrack());
return new ResponseEntity<>(new CurrentMusicData(uat, currentTrack.getPosition(), currentTrack.getState().toString(), player.isPaused(), AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()), HttpStatus.OK); return new ResponseEntity<>(new CurrentMusicData(uat, currentTrack.getPosition(), currentTrack.getState().toString(), player.isPaused(), AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()), HttpStatus.OK);
}else } else {
{
return new ResponseEntity<>(new CurrentMusicData(null, 0, "DISCONNECTED", false, false), HttpStatus.OK); return new ResponseEntity<>(new CurrentMusicData(null, 0, "DISCONNECTED", false, false), HttpStatus.OK);
} }
} }
@ -81,8 +78,7 @@ public class MusicWebAPIController {
if (guild == null) { if (guild == null) {
logger.warn("Request whit no guild!"); logger.warn("Request whit no guild!");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST); return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
} } else {
else{
logger.trace("getPlaylist for " + guild.getName()); logger.trace("getPlaylist for " + guild.getName());
} }
@ -92,8 +88,6 @@ public class MusicWebAPIController {
} }
@RequestMapping("/getAllInfo") @RequestMapping("/getAllInfo")
public ResponseEntity<AllMusicInfoData> getAllInfo(@RequestParam(value = "guild") String guildId, @CookieValue("token") String token) { public ResponseEntity<AllMusicInfoData> getAllInfo(@RequestParam(value = "guild") String guildId, @CookieValue("token") String token) {
if (token != null) { if (token != null) {
@ -113,17 +107,14 @@ public class MusicWebAPIController {
if (guild.getAudioManager().isConnected()) { if (guild.getAudioManager().isConnected()) {
AudioPlayer player = AudioM.getInstance(guild).getGuildMusicManager().player; AudioPlayer player = AudioM.getInstance(guild).getGuildMusicManager().player;
AudioTrack currentTrack = player.getPlayingTrack(); AudioTrack currentTrack = player.getPlayingTrack();
if(currentTrack == null) if (currentTrack == null) {
{
musicData = new CurrentMusicData(null, 0, "STOP", false, AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()); musicData = new CurrentMusicData(null, 0, "STOP", false, AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow());
} } else {
else{
UserAudioTrackData uat = new UserAudioTrackData(AudioM.getInstance(guild).getGuildMusicManager().scheduler.getCurrentPlayingTrack()); UserAudioTrackData uat = new UserAudioTrackData(AudioM.getInstance(guild).getGuildMusicManager().scheduler.getCurrentPlayingTrack());
musicData = new CurrentMusicData(uat, currentTrack.getPosition(), currentTrack.getState().toString(), player.isPaused(), AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()); musicData = new CurrentMusicData(uat, currentTrack.getPosition(), currentTrack.getState().toString(), player.isPaused(), AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow());
} }
}else } else {
{
musicData = new CurrentMusicData(null, 0, "DISCONNECTED", false, false); musicData = new CurrentMusicData(null, 0, "DISCONNECTED", false, false);
} }
return new ResponseEntity<>(new AllMusicInfoData(musicData, list), HttpStatus.OK); return new ResponseEntity<>(new AllMusicInfoData(musicData, list), HttpStatus.OK);
@ -135,8 +126,7 @@ public class MusicWebAPIController {
} }
} } else {
else{
logger.warn("All Info without token!"); logger.warn("All Info without token!");
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
@ -156,15 +146,14 @@ public class MusicWebAPIController {
try { try {
UserEntity user = userUtils.getUserWithApiToken(userRepository, token); UserEntity user = userUtils.getUserWithApiToken(userRepository, token);
logger.info("Receive command " + data.command + " from " + request.getRemoteAddr() + " USER: " + user.getName() + " GUILD: " + guild.getName()); logger.info("[" + guild.getName() + "] Receive command" + data.command + " from" + request.getRemoteAddr() + " USER:" + user.getName() + " GUILD:" + guild.getName());
if (ApiCommandLoader.apiCommands.containsKey(data.command)) { if (ApiCommandLoader.apiCommands.containsKey(data.command)) {
UserStatsUtils.getINSTANCE().addApiCount(user, guildId); UserStatsUtils.getINSTANCE().addApiCount(user, guildId);
return ApiCommandLoader.apiCommands.get(data.command).action(data, MainBot.jda.getUserById(user.getJdaId()), guild); return ApiCommandLoader.apiCommands.get(data.command).action(data, MainBot.jda.getUserById(user.getJdaId()), guild);
} } else
else
return new ResponseEntity<>(new CommandResponseData(data.command, "Unknown Command", "command"), HttpStatus.BAD_REQUEST); return new ResponseEntity<>(new CommandResponseData(data.command, "Unknown Command", "command"), HttpStatus.BAD_REQUEST);
} catch (UnknownTokenException e) { } catch (UnknownTokenException e) {
@ -173,14 +162,12 @@ public class MusicWebAPIController {
} }
} } else {
else{
logger.warn("Command without token! ip: " + request.getRemoteAddr()); logger.warn("Command without token! ip: " + request.getRemoteAddr());
return new ResponseEntity<>(new CommandResponseData(data.command, "Missing token!\nPlease Re-connect.", "token"), HttpStatus.UNAUTHORIZED); return new ResponseEntity<>(new CommandResponseData(data.command, "Missing token!\nPlease Re-connect.", "token"), HttpStatus.UNAUTHORIZED);
} }
} } else
else
logger.info("Null"); logger.info("Null");
return new ResponseEntity<>(new CommandResponseData(null, null), HttpStatus.NO_CONTENT); return new ResponseEntity<>(new CommandResponseData(null, null), HttpStatus.NO_CONTENT);
} }
@ -191,8 +178,7 @@ public class MusicWebAPIController {
if (guild == null) { if (guild == null) {
logger.warn("Request whit no guild!"); logger.warn("Request whit no guild!");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST); return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
} } else {
else{
logger.trace("getPlaylist for " + guild.getName()); logger.trace("getPlaylist for " + guild.getName());
} }
List<ChanelData> temp = new ArrayList<>(); List<ChanelData> temp = new ArrayList<>();

View File

@ -61,7 +61,6 @@ public class AudioM {
} }
private AudioM(Guild guild) { private AudioM(Guild guild) {
this.playerManager = new DefaultAudioPlayerManager(); this.playerManager = new DefaultAudioPlayerManager();
AudioSourceManagers.registerRemoteSources(playerManager); AudioSourceManagers.registerRemoteSources(playerManager);
@ -71,6 +70,7 @@ public class AudioM {
/** /**
* Load audio track from url, connect to chanel if not connected * Load audio track from url, connect to chanel if not connected
*
* @param event * @param event
* @param voiceChannel Voice channel to connect if no connected * @param voiceChannel Voice channel to connect if no connected
* @param trackUrl Audio track url * @param trackUrl Audio track url
@ -84,7 +84,7 @@ public class AudioM {
playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() { playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() {
@Override @Override
public void trackLoaded(AudioTrack track) { public void trackLoaded(AudioTrack track) {
logger.info("Single Track detected!"); logger.info("[" + guild + "] Single Track detected!");
UserAudioTrack uat = new UserAudioTrack(event.getAuthor(), track); UserAudioTrack uat = new UserAudioTrack(event.getAuthor(), track);
event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Add " + track.getInfo().title + " to playlist")).queue(); event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Add " + track.getInfo().title + " to playlist")).queue();
@ -93,7 +93,7 @@ public class AudioM {
@Override @Override
public void playlistLoaded(AudioPlaylist playlist) { public void playlistLoaded(AudioPlaylist playlist) {
logger.info("Playlist detected! Limit: "+playlistLimit); logger.info("[" + guild + "] Playlist detected! Limit: " + playlistLimit);
AudioTrack firstTrack = playlist.getSelectedTrack(); AudioTrack firstTrack = playlist.getSelectedTrack();
event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Add " + firstTrack.getInfo().title + " and 30 first videos to playlist !")).queue(); event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicOk("Add " + firstTrack.getInfo().title + " and 30 first videos to playlist !")).queue();
@ -102,19 +102,18 @@ public class AudioM {
playListLoader(playlist, playlistLimit, event.getAuthor(), onHead); playListLoader(playlist, playlistLimit, event.getAuthor(), onHead);
} }
@Override @Override
public void noMatches() { public void noMatches() {
logger.warn("Cant find media!"); logger.warn("[" + guild + "] Cant find media!");
event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicError("Video not found !")).queue(); event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicError("Video not found !")).queue();
} }
@Override @Override
public void loadFailed(FriendlyException exception) { public void loadFailed(FriendlyException exception) {
logger.error("Can't load media!"); logger.error("[" + guild + "] Can't load media!");
logger.error(exception.getMessage()); logger.error(exception.getMessage());
event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicError("Playback error !")).queue(); event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicError("Playback error !")).queue();
} }
@ -125,7 +124,7 @@ public class AudioM {
playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() { playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() {
@Override @Override
public void trackLoaded(AudioTrack track) { public void trackLoaded(AudioTrack track) {
logger.info("Auto add " + track.getInfo().title +" to playlist."); logger.info("[" + guild + "] Auto add " + track.getInfo().title + " to playlist.");
UserAudioTrack userAudioTrack = new UserAudioTrack(MainBot.jda.getSelfUser(), track); UserAudioTrack userAudioTrack = new UserAudioTrack(MainBot.jda.getSelfUser(), track);
play(guild, playedChanel, musicManager, userAudioTrack, true); play(guild, playedChanel, musicManager, userAudioTrack, true);
} }
@ -133,19 +132,19 @@ public class AudioM {
@Override @Override
public void playlistLoaded(AudioPlaylist playlist) { public void playlistLoaded(AudioPlaylist playlist) {
AudioTrack track = playlist.getTracks().get(0); AudioTrack track = playlist.getTracks().get(0);
logger.info("Auto add " + track.getInfo().title +" to playlist."); logger.info("[" + guild + "] Auto add " + track.getInfo().title + " to playlist.");
UserAudioTrack userAudioTrack = new UserAudioTrack(MainBot.jda.getSelfUser(), track); UserAudioTrack userAudioTrack = new UserAudioTrack(MainBot.jda.getSelfUser(), track);
play(guild, playedChanel, musicManager, userAudioTrack, true); play(guild, playedChanel, musicManager, userAudioTrack, true);
} }
@Override @Override
public void noMatches() { public void noMatches() {
logger.warn("Track not found: "+trackUrl); logger.warn("[" + guild + "] Track not found: " + trackUrl);
} }
@Override @Override
public void loadFailed(FriendlyException exception) { public void loadFailed(FriendlyException exception) {
logger.error("Cant load media!"); logger.error("[" + guild + "] Cant load media!");
logger.error(exception.getMessage()); logger.error(exception.getMessage());
} }
}); });
@ -154,6 +153,7 @@ public class AudioM {
/** /**
* Load playlist to playlist * Load playlist to playlist
*
* @param playlist Loaded playlist * @param playlist Loaded playlist
* @param playlistLimit Playlist limit * @param playlistLimit Playlist limit
* @param user User who have submitted the playlist * @param user User who have submitted the playlist
@ -187,6 +187,7 @@ public class AudioM {
/** /**
* Add single track to playlist, auto-connect if not connected to vocal chanel * Add single track to playlist, auto-connect if not connected to vocal chanel
*
* @param guild guild * @param guild guild
* @param channel Chanel for auto-connect * @param channel Chanel for auto-connect
* @param musicManager Guild music manager * @param musicManager Guild music manager
@ -204,6 +205,7 @@ public class AudioM {
/** /**
* Skip current track * Skip current track
*
* @param event * @param event
*/ */
public void skipTrack(MessageReceivedEvent event) { public void skipTrack(MessageReceivedEvent event) {
@ -214,6 +216,7 @@ public class AudioM {
/** /**
* Pause current track * Pause current track
*
* @param event * @param event
*/ */
public void pause(MessageReceivedEvent event) { public void pause(MessageReceivedEvent event) {
@ -227,6 +230,7 @@ public class AudioM {
/** /**
* Resume paused track * Resume paused track
*
* @param event * @param event
*/ */
public void resume(MessageReceivedEvent event) { public void resume(MessageReceivedEvent event) {
@ -238,6 +242,7 @@ public class AudioM {
/** /**
* Print current played track info * Print current played track info
*
* @param event * @param event
*/ */
public void info(MessageReceivedEvent event) { public void info(MessageReceivedEvent event) {
@ -256,6 +261,7 @@ public class AudioM {
/** /**
* Print current playlist content * Print current playlist content
*
* @param event * @param event
*/ */
public void list(MessageReceivedEvent event) { public void list(MessageReceivedEvent event) {
@ -264,9 +270,7 @@ public class AudioM {
StringBuilder resp = new StringBuilder(); StringBuilder resp = new StringBuilder();
if (list.size() == 0) { if (list.size() == 0) {
resp.append("Oh my god!\nThe playlist is empty ! \n:astonished: "); resp.append("Oh my god!\nThe playlist is empty ! \n:astonished: ");
} } else {
else
{
for (UserAudioTrackData trackInfo : list) { for (UserAudioTrackData trackInfo : list) {
resp.append("- "); resp.append("- ");
resp.append(trackInfo.getAudioTrackInfo().title); resp.append(trackInfo.getAudioTrackInfo().title);
@ -278,6 +282,7 @@ public class AudioM {
/** /**
* Called by //add, only if already connected * Called by //add, only if already connected
*
* @param event * @param event
* @param url Audio track url * @param url Audio track url
* @param playListLimit Limit of playlist * @param playListLimit Limit of playlist
@ -286,15 +291,14 @@ public class AudioM {
public void add(MessageReceivedEvent event, String url, int playListLimit, boolean onHead) { public void add(MessageReceivedEvent event, String url, int playListLimit, boolean onHead) {
if (playedChanel != null) { if (playedChanel != null) {
loadAndPlay(event, playedChanel, url, playListLimit, onHead); loadAndPlay(event, playedChanel, url, playListLimit, onHead);
} } else {
else
{
event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicError("Not connected to vocal chanel !")).queue(); event.getTextChannel().sendMessage(EmbedMessageUtils.getMusicError("Not connected to vocal chanel !")).queue();
} }
} }
/** /**
* Stop current playing track and flush playlist * Stop current playing track and flush playlist
*
* @param event * @param event
*/ */
public void stop(MessageReceivedEvent event) { public void stop(MessageReceivedEvent event) {

View File

@ -8,6 +8,8 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo;
import net.Broken.MainBot; import net.Broken.MainBot;
import net.Broken.RestApi.Data.UserAudioTrackData; import net.Broken.RestApi.Data.UserAudioTrackData;
import net.Broken.audio.Youtube.RelatedIdNotFound;
import net.Broken.audio.Youtube.YoutubeSearchRework;
import net.Broken.audio.Youtube.YoutubeTools; import net.Broken.audio.Youtube.YoutubeTools;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@ -53,15 +55,14 @@ public class TrackScheduler extends AudioEventAdapter {
// something is playing, it returns false and does nothing. In that case the player was already playing so this // something is playing, it returns false and does nothing. In that case the player was already playing so this
// track goes to the queue instead. // track goes to the queue instead.
if (track.getSubmittedUser() != MainBot.jda.getSelfUser()) { if (track.getSubmittedUser() != MainBot.jda.getSelfUser()) {
logger.debug("Flush history"); logger.debug("[" + guild + "] Flush history");
history = new ArrayList<>(); history = new ArrayList<>();
} }
history.add(track.getAudioTrack().getIdentifier()); history.add(track.getAudioTrack().getIdentifier());
if (!player.startTrack(track.getAudioTrack(), true)) { if (!player.startTrack(track.getAudioTrack(), true)) {
queue.offer(track); queue.offer(track);
} } else {
else{
currentPlayingTrack = track; currentPlayingTrack = track;
} }
if (track.getSubmittedUser() != MainBot.jda.getSelfUser()) { if (track.getSubmittedUser() != MainBot.jda.getSelfUser()) {
@ -73,6 +74,7 @@ public class TrackScheduler extends AudioEventAdapter {
/** /**
* Add track on top of playlist * Add track on top of playlist
*
* @param track * @param track
*/ */
public void addNext(UserAudioTrack track) { public void addNext(UserAudioTrack track) {
@ -87,16 +89,14 @@ public class TrackScheduler extends AudioEventAdapter {
history.add(track.getAudioTrack().getIdentifier()); history.add(track.getAudioTrack().getIdentifier());
if (!player.startTrack(track.getAudioTrack(), true)) { if (!player.startTrack(track.getAudioTrack(), true)) {
queue.addFirst(track); queue.addFirst(track);
} } else {
else{
currentPlayingTrack = track; currentPlayingTrack = track;
} }
if (track.getSubmittedUser() != MainBot.jda.getSelfUser()) { if (track.getSubmittedUser() != MainBot.jda.getSelfUser()) {
needAutoPlay(); needAutoPlay();
} } else
else logger.debug("[" + guild + "] Bot add, ignore autoFlow");
logger.debug("Bot add, ignore autoFlow");
} }
public void pause() { public void pause() {
@ -142,16 +142,16 @@ public class TrackScheduler extends AudioEventAdapter {
for (UserAudioTrack track : queue) { for (UserAudioTrack track : queue) {
if (track.getAudioTrack().getInfo().uri.equals(uri)) { if (track.getAudioTrack().getInfo().uri.equals(uri)) {
if (!queue.remove(track)) { if (!queue.remove(track)) {
logger.error("Delete failure!"); logger.error("[" + guild + "] Delete failure!");
return false; return false;
} else { } else {
logger.info("Delete succeful"); logger.info("[" + guild + "] Delete successful");
needAutoPlay(); needAutoPlay();
return true; return true;
} }
} }
} }
logger.info("Delete failure! Not found."); logger.info("[" + guild + "] Delete failure! Not found.");
return false; return false;
} }
@ -174,27 +174,34 @@ public class TrackScheduler extends AudioEventAdapter {
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
// Only start the next track if the end reason is suitable for it (FINISHED or LOAD_FAILED) // Only start the next track if the end reason is suitable for it (FINISHED or LOAD_FAILED)
if (endReason.mayStartNext) { if (endReason.mayStartNext) {
logger.debug("End of track, start next."); logger.debug("[" + guild + "] End of track, start next.");
nextTrack(); nextTrack();
} }
} }
private void needAutoPlay() { private void needAutoPlay() {
if ((queue.size() < 1) && autoFlow && currentPlayingTrack != null) { if ((queue.size() < 1) && autoFlow && currentPlayingTrack != null) {
logger.debug("Auto add needed!"); logger.debug("[" + guild.getName() + "] Auto add needed!");
AudioM audioM = AudioM.getInstance(guild); AudioM audioM = AudioM.getInstance(guild);
YoutubeSearchRework youtubeSearchRework = YoutubeSearchRework.getInstance();
try {
String id = youtubeSearchRework.getRelatedVideo(currentPlayingTrack.getAudioTrack().getInfo().identifier);
logger.debug("[" + guild.getName() + "] Related id: " + id);
audioM.loadAndPlayAuto(id);
} catch (IOException | RelatedIdNotFound ex) {
logger.debug("[" + guild.getName() + "] Can't find related id, try API...");
YoutubeTools youtubeTools = YoutubeTools.getInstance(); YoutubeTools youtubeTools = YoutubeTools.getInstance();
try { try {
String id = youtubeTools.getRelatedVideo(currentPlayingTrack.getAudioTrack().getInfo().identifier, history); String id = youtubeTools.getRelatedVideo(currentPlayingTrack.getAudioTrack().getInfo().identifier, history);
logger.debug("Related id: "+id); logger.debug("[" + guild.getName() + "] Related id: " + id);
audioM.loadAndPlayAuto(id); audioM.loadAndPlayAuto(id);
} catch (GoogleJsonResponseException e) { } catch (GoogleJsonResponseException e) {
logger.error("There was a service error: " + e.getDetails().getCode() + " : " + e.getDetails().getMessage()); logger.error("[" + guild.getName() + "] There was a service error: " + e.getDetails().getCode() + " : " + e.getDetails().getMessage());
} catch (IOException t) { } catch (IOException t) {
logger.catching(t); logger.catching(t);
} }
}
} }
} }

View File

@ -0,0 +1,4 @@
package net.Broken.audio.Youtube;
public class RelatedIdNotFound extends Exception {
}

View File

@ -104,4 +104,23 @@ public class YoutubeSearchRework {
} }
return results; return results;
} }
public String getRelatedVideo(String sourceVideoId) throws IOException, RelatedIdNotFound {
sourceVideoId = URLEncoder.encode(sourceVideoId, StandardCharsets.UTF_8.toString());
String url = "https://www.youtube.com/watch?v=" + sourceVideoId;
Document doc = getYoutubeSearchDocument(url);
return extractRelatedVideoId(doc);
}
private String extractRelatedVideoId(Document doc) throws RelatedIdNotFound {
Elements elements = doc.select(".autoplay-bar .content-link");
if(elements.size() == 0){
throw new RelatedIdNotFound();
}
Element elem = elements.get(0);
String url = elem.attributes().get("href");
return url.replace("/watch?v=", "");
}
} }