/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.schabi.newpipe.extractor.services.xh.extractors; import com.grack.nanojson.JsonArray; import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonParser; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.StreamExtractor; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; // Parse import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.schabi.newpipe.extractor.localization.Localization; import static org.schabi.newpipe.extractor.services.xh.XhService.HOST; import org.schabi.newpipe.extractor.services.xh.extractors.items.XhVideo; import org.schabi.newpipe.extractor.stream.DeliveryMethod; public class XhStreamExtractor extends StreamExtractor { // baseurl String baseUrl; // Object XhVideo video; public XhStreamExtractor(StreamingService service, LinkHandler linkHandler) { super(service, linkHandler); } @Override public String getThumbnailUrl() throws ParsingException { return this.video.getThumbURL(); } @Override public String getUploaderUrl() throws ParsingException { return ""; } @Override public String getUploaderName() throws ParsingException { return this.video.getAuthorName(); } @Override public List getAudioStreams() throws IOException, ExtractionException { // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. return Collections.emptyList(); } @Override public List getVideoStreams() throws IOException, ExtractionException { // video was not parsed / no video streams if (video.getSources().isEmpty()) { return Collections.emptyList(); } // new list final List listStreams = new ArrayList<>(); // iterate hashmap for key values for (Map.Entry source: video.getSources().entrySet()) { System.out.println(source.getKey()); System.out.println(source.getValue()); MediaFormat format = MediaFormat.MPEG_4; if (source.getValue().endsWith(".webm")) { format = MediaFormat.WEBM; } DeliveryMethod deliver = DeliveryMethod.PROGRESSIVE_HTTP; if (source.getValue().endsWith(".m3u8")) { deliver = DeliveryMethod.HLS; } // add source to list listStreams.add( new VideoStream.Builder() .setId(String.valueOf(video.getId()) + "-" + source.getKey()) .setContent(source.getValue(), true) .setIsVideoOnly(false) .setDeliveryMethod(deliver) .setMediaFormat(format) .setResolution(source.getKey()) .build() ); } // return sources return listStreams; } @Override public List getVideoOnlyStreams() throws IOException, ExtractionException { return Collections.emptyList(); } @Override public StreamType getStreamType() throws ParsingException { return StreamType.VIDEO_STREAM; } @Override public void onFetchPage(Downloader downloader) throws IOException, ExtractionException { // get baseurl using predefined method getBaseUrl() // perform regex to replace the url host String url = getLinkHandler().getUrl(); url = url.replaceAll("http?s\\:\\/\\/(xhamster?.+)\\/videos\\/", "https://" + HOST + "/videos/"); this.baseUrl = url; final String html_ = downloader.get(url).responseBody(); // parse video info try { Document html = Jsoup.parse(html_); // Parse Content final Element e = html.getElementById("initials-script"); final String content = e.html(); String info_cdn = content.substring(0, content.length() - 1).replace("window.initials=", ""); // Use NanoJSON to convert to VideoItem JsonObject json = JsonParser.object().from(info_cdn); final JsonObject videoModel = json.getObject("videoModel"); // Video Info final int id = videoModel.getInt("id"); final String title = videoModel.getString("title"); final String description = videoModel.getString("description"); final String thumbURL = videoModel.getString("thumbURL"); final int duration = videoModel.getInt("created"); final String pageURL = videoModel.getString("pageURL"); final int created = videoModel.getInt("created"); // Author final String authorName = videoModel.getObject("author").getString("name"); final int authorID = videoModel.getObject("author").getInt("id"); final String authorThumb = videoModel.getObject("author").getString("thumbURL"); final String authorPageURL = videoModel.getObject("author").getString("pageURL"); HashMap streams = new HashMap<>(); // iterate urls JsonArray mp4 = json.getObject("xplayerSettings").getObject("sources").getObject("standard").getArray("mp4"); if (!mp4.isEmpty()) { // headers Map> headers = new HashMap<>(); headers.put("Referer", Arrays.asList(baseUrl)); for (int i=0; i < mp4.size(); i++) { JsonObject j = mp4.getObject(i); String key = j.getString("quality"); String value = j.getString("url"); int responseCode = downloader.head(value, headers).responseCode(); System.out.println(responseCode); streams.put(key, value); } } // set the video object this.video = new XhVideo(id, title, description, duration, created, pageURL, thumbURL, authorID, authorName, authorThumb, authorPageURL, streams); } catch (Exception e) { throw new ExtractionException(e.getMessage(), e); } } @Override public String getName() throws ParsingException { return video.getTitle(); } }