/** * @param httpInterface HTTP interface to use for performing any necessary request. * @param videoId ID of the video. * @param mustExist If <code>true</code>, throws an exception instead of returning <code>null</code> if the track does * not exist. * @return JSON information about the track if it exists. <code>null</code> if it does not and mustExist is * <code>false</code>. * @throws IOException On network error. */ public JsonBrowser getTrackInfoFromMainPage(HttpInterface httpInterface, String videoId, boolean mustExist) throws IOException { try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(getWatchUrl(videoId)))) { int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != 200) { throw new IOException("Invalid status code for video page response: " + statusCode); } String html = IOUtils.toString(response.getEntity().getContent(), Charset.forName(CHARSET)); String configJson = DataFormatTools.extractBetween(html, "ytplayer.config = ", ";ytplayer.load"); if (configJson != null) { return JsonBrowser.parse(configJson); } } if (determineFailureReason(httpInterface, videoId, mustExist)) { return null; } // In case main page does not give player configuration, but info page indicates an OK result, it is probably an // age-restricted video for which the complete track info can be combined from the embed page and the info page. return getTrackInfoFromEmbedPage(httpInterface, videoId); }
/** * @param videoId Video ID. Used as {@link AudioTrackInfo#identifier}. * @param title See {@link AudioTrackInfo#title}. * @param uploader Name of the uploader. Used as {@link AudioTrackInfo#author}. * @param isStream See {@link AudioTrackInfo#isStream}. * @param duration See {@link AudioTrackInfo#length}. * @return An audio track instance. */ public YoutubeAudioTrack buildTrackObject(String videoId, String title, String uploader, boolean isStream, long duration) { return new YoutubeAudioTrack(new AudioTrackInfo(title, uploader, duration, videoId, isStream, getWatchUrl(videoId)), this); }