getQualityUrls();
9 | public abstract String getHost();
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/popup_hide.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/popup_show.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 8dp
6 | 176dp
7 | 16dp
8 | 2dp
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/roundedbutton.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/animelist.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/test/java/com/stuffbox/webscraper/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/models/Quality.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.models;
2 |
3 | public class Quality {
4 | private String quality;
5 | private String qualityUrl;
6 |
7 | public Quality(String quality, String qualityUrl) {
8 | this.quality = quality;
9 | this.qualityUrl = qualityUrl;
10 | }
11 |
12 | public String getQuality() {
13 | return quality;
14 | }
15 |
16 | public String getQualityUrl() {
17 | return qualityUrl;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFEE58
4 | #C9BC1F
5 | #FF4081
6 | #FFEE58
7 |
8 | #979797
9 | #FFFFFF
10 | #000
11 | #021aee
12 | #fff
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values/drawables.xml:
--------------------------------------------------------------------------------
1 |
2 | - @android:drawable/ic_menu_camera
3 | - @android:drawable/ic_menu_gallery
4 | - @android:drawable/ic_menu_slideshow
5 | - @android:drawable/ic_menu_manage
6 | - @android:drawable/ic_menu_share
7 | - @android:drawable/ic_menu_send
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | WebScraper
3 | Main2Activity
4 | Open navigation drawer
5 | Close navigation drawer
6 | Android Studio
7 | android.studio@android.com
8 | Navigation header
9 | Settings
10 | Plot Summary :
11 |
12 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 | **Is your feature request related to a problem? Please describe.**
8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9 |
10 | **Describe the solution you'd like**
11 | A clear and concise description of what you want to happen.
12 |
13 | **Describe alternatives you've considered**
14 | A clear and concise description of any alternative solutions or features you've considered.
15 |
16 | **Additional context**
17 | Add any other context or screenshots about the feature request here.
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/downloadqualitybutton.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/webviewer.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/bottommenu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/animefinder.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/stuffbox/webscraper/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper;
2 |
3 | import android.content.Context;
4 | import androidx.test.InstrumentationRegistry;
5 | import androidx.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.stuffbox.webscraper", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | **Describe the bug**
8 | A clear and concise description of what the bug is.
9 |
10 | **To Reproduce**
11 | Steps to reproduce the behavior:
12 | 1. Go to '...'
13 | 2. Click on '....'
14 | 3. Scroll down to '....'
15 | 4. See error
16 |
17 | **Expected behavior**
18 | A clear and concise description of what you expected to happen.
19 |
20 | **Screenshots**
21 | If applicable, add screenshots to help explain your problem.
22 |
23 | **Desktop (please complete the following information):**
24 | - OS: [e.g. iOS]
25 | - Browser [e.g. chrome, safari]
26 | - Version [e.g. 22]
27 |
28 | **Smartphone (please complete the following information):**
29 | - Device: [e.g. iPhone6]
30 | - OS: [e.g. iOS8.1]
31 | - Browser [e.g. stock browser, safari]
32 | - Version [e.g. 22]
33 |
34 | **Additional context**
35 | Add any other context about the problem here.
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | AnimeWatcher
2 |
3 | A simple app to watch anime without any ads .
4 | It uses Jsoup to extract information from gogoanime website.
5 |
6 |
7 |
8 |
9 |
10 | Features
11 | Picture in Picture mode
12 |
13 | Search Anime
14 |
15 | Check recent anime you have watched
16 |
17 | Anime List
18 | Contains 6142 Anime
19 |
20 |
21 |
22 |
23 | Library used
24 | Exoplayer- To show videos
25 |
26 | Jsoup- for webscraping
27 | Picasso - for displaying images and caching
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/database/AnimeDao.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.database;
2 |
3 | import androidx.room.Dao;
4 | import androidx.room.Delete;
5 | import androidx.room.Insert;
6 | import androidx.room.Query;
7 | import androidx.room.Update;
8 |
9 | import com.stuffbox.webscraper.models.Anime;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 | @Dao
14 | public interface AnimeDao {
15 | @Query("Select * from anime order by id DESC")
16 | List getAnimeList();
17 | @Insert
18 | void insertAnime(Anime anime);
19 | @Update
20 | void updateAnime(Anime anime);
21 | @Delete
22 | void deleteAnime(Anime anime);
23 | @Query("DELETE FROM anime WHERE episodeNo = :episodeNo and name= :name")
24 | void deleteAnimeByNameAndEpisodeNo(String name,String episodeNo);
25 | @Query("SELECT * FROM anime where name = :name and episodeNo= :episodeNo")
26 | Anime getAnimeByNameAndEpisodeNo(String name,String episodeNo);
27 | }
28 |
--------------------------------------------------------------------------------
/generateanimelist.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import json
3 | from bs4 import *
4 | baseurl ="https://gogoanime.pe/"
5 | jsonlist=[]
6 | for i in range(1,3):
7 | stringi=str(i)
8 | currenturl=baseurl+"anime-list.html?page="+stringi
9 | page=requests.get(currenturl)
10 | soup=BeautifulSoup(page.content,'html.parser')
11 | lis=soup.find('ul',class_='listing').find_all('li')
12 | for li in lis:
13 | x=BeautifulSoup(li.get('title'),'html.parser')
14 | imagelink=x.find('img').get('src')
15 | animelink=baseurl+li.find('a').get('href')
16 | title=x.find_all('div')[1].find('a').text
17 | #print(title)
18 | #print(animelink)
19 | anime={
20 | "anime" : {
21 | "Anime name" : title,
22 | "link" : animelink,
23 | "imagelink" : imagelink
24 | }
25 | }
26 | jsonlist.append(anime)
27 | with open('animelist.json', 'w') as json_file:
28 | json.dump(jsonlist, json_file)
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/adapterforanimelist.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
21 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/pip_play.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
19 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/video_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
22 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 | android.useAndroidX=true
14 | android.enableJetifier=true
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 | #android.useAndroidX=false
20 | # Jetifier will convert support libraries of all your dependencies to AndroidX automatically,
21 | # if you don't set it true then your project will have both support
22 | #android.enableJetifier=false
--------------------------------------------------------------------------------
/app/src/main/res/drawable/pip_pause.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
19 |
20 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/InputFilterMinMax.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper;
2 |
3 | import android.text.InputFilter;
4 | import android.text.Spanned;
5 |
6 | public class InputFilterMinMax implements InputFilter {
7 |
8 | private int min, max;
9 |
10 | public InputFilterMinMax(int min, int max) {
11 | this.min = min;
12 | this.max = max;
13 | }
14 |
15 | public InputFilterMinMax(String min, String max) {
16 | this.min = Integer.parseInt(min);
17 | this.max = Integer.parseInt(max);
18 | }
19 |
20 | @Override
21 | public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
22 | try {
23 | int input = Integer.parseInt(dest.toString() + source.toString());
24 | if (isInRange(min, max, input))
25 | return null;
26 | } catch (Exception nfe) { }
27 | return "";
28 | }
29 |
30 | private boolean isInRange(int a, int b, int c) {
31 | return b > a ? c >= a && c <= b : c >= b && c <= a;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/animelistrecyclerview.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
19 |
20 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/videoviewer.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
19 |
20 |
21 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/adapterforepisode.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
22 |
23 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/database/AnimeDatabase.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.database;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 |
6 | import androidx.room.Database;
7 | import androidx.room.Room;
8 | import androidx.room.RoomDatabase;
9 |
10 | import com.stuffbox.webscraper.models.Anime;
11 |
12 | @Database(entities = Anime.class,version =1,exportSchema = false)
13 | public abstract class AnimeDatabase extends RoomDatabase {
14 | private static final String LOG_TAG = AnimeDatabase.class.getSimpleName();
15 | private static final Object LOCK = new Object();
16 | private static final String DATABASE_NAME = "anime_db";
17 | private static AnimeDatabase sInstance;
18 |
19 | public static AnimeDatabase getInstance(Context context) {
20 | if (sInstance == null) {
21 | synchronized (LOCK) {
22 | Log.d(LOG_TAG, "Creating new database instance");
23 | sInstance = Room.databaseBuilder(context.getApplicationContext(),
24 | AnimeDatabase.class, DATABASE_NAME)
25 | .allowMainThreadQueries()
26 | .fallbackToDestructiveMigration()
27 | .build();
28 | }
29 | }
30 | Log.d(LOG_TAG, "Getting the database instance");
31 | return sInstance;
32 | }
33 |
34 | public abstract AnimeDao animeDao();
35 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/dublayout.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
20 |
21 |
22 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/downloadsheet.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
13 |
14 |
22 |
27 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/adapters/ViewPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.adapters;
2 |
3 |
4 | import androidx.annotation.NonNull;
5 | import androidx.fragment.app.Fragment;
6 | import androidx.fragment.app.FragmentManager;
7 | import androidx.fragment.app.FragmentPagerAdapter;
8 |
9 |
10 | import com.stuffbox.webscraper.constants.Constants;
11 | import com.stuffbox.webscraper.fragments.AnimeFragment;
12 | import com.stuffbox.webscraper.fragments.RecentFragment;
13 |
14 | public class ViewPagerAdapter extends FragmentPagerAdapter {
15 | public ViewPagerAdapter(FragmentManager fm)
16 | {
17 | super(fm);
18 | }
19 | @NonNull
20 | @Override
21 | public Fragment getItem(int position) {
22 | Fragment fragment=null;
23 | if(position==0)
24 | {
25 | fragment= AnimeFragment.newInstance(Constants.url+"ajax/page-recent-release?page=1&type=2");
26 |
27 |
28 | }
29 | else if(position==1)
30 | fragment=AnimeFragment.newInstance(Constants.url);
31 | else
32 | {
33 | fragment=new RecentFragment();
34 | }
35 | return fragment;
36 | }
37 | @Override
38 | public int getCount() {
39 | return 3;
40 | }
41 | @Override
42 | public CharSequence getPageTitle(int position) {
43 | String title = null;
44 | if (position == 1)
45 | {
46 | title = "SUB";
47 | }
48 | else if (position == 0)
49 | {
50 | title = "DUB";
51 | }
52 | else if(position==2)
53 | {
54 | title= "RECENT";
55 | }
56 |
57 |
58 | return title;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
10 |
14 |
15 |
20 |
24 |
32 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/row_data.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
19 |
20 |
29 |
30 |
37 |
38 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/database/AnimeExecutors.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.database;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | import androidx.annotation.NonNull;
7 |
8 | import java.util.concurrent.Executor;
9 | import java.util.concurrent.Executors;
10 |
11 | public class AnimeExecutors {
12 |
13 | // For Singleton instantiation
14 | private static final Object LOCK = new Object();
15 | private static AnimeExecutors sInstance;
16 | private final Executor diskIO;
17 | private final Executor mainThread;
18 | private final Executor networkIO;
19 |
20 | private AnimeExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
21 | this.diskIO = diskIO;
22 | this.networkIO = networkIO;
23 | this.mainThread = mainThread;
24 | }
25 |
26 | public static AnimeExecutors getInstance() {
27 | if (sInstance == null) {
28 | synchronized (LOCK) {
29 | sInstance = new AnimeExecutors(Executors.newSingleThreadExecutor(),
30 | Executors.newFixedThreadPool(3),
31 | new MainThreadExecutor());
32 | }
33 | }
34 | return sInstance;
35 | }
36 |
37 | public Executor diskIO() {
38 | return diskIO;
39 | }
40 |
41 | public Executor mainThread() {
42 | return mainThread;
43 | }
44 |
45 | public Executor networkIO() {
46 | return networkIO;
47 | }
48 |
49 | private static class MainThreadExecutor implements Executor {
50 | private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
51 |
52 | @Override
53 | public void execute(@NonNull Runnable command) {
54 | mainThreadHandler.post(command);
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/scrapers/XStreamScraper.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.scrapers;
2 |
3 | import android.util.Log;
4 |
5 | import com.stuffbox.webscraper.models.Quality;
6 |
7 | import org.json.JSONArray;
8 | import org.json.JSONObject;
9 | import org.jsoup.Jsoup;
10 | import org.jsoup.nodes.Document;
11 |
12 | import java.io.IOException;
13 | import java.util.ArrayList;
14 |
15 | public class XStreamScraper extends Scraper {
16 |
17 | private final Document gogoAnimePageDocument;
18 |
19 | public XStreamScraper(Document gogoAnimePageDocument) {
20 | this.gogoAnimePageDocument = gogoAnimePageDocument;
21 | }
22 | @Override
23 | public ArrayList getQualityUrls() {
24 | String xstreamLink = gogoAnimePageDocument.getElementsByClass("xstreamcdn").get(0).getElementsByTag("a").get(0).attr("data-video");
25 | Log.i("apiurl",xstreamLink);
26 | String id = xstreamLink.substring(xstreamLink.lastIndexOf("/")+1);
27 | String apiUrl = "https://fcdn.stream/api/source/"+id;
28 | Log.i("apiUrl","soja :"+ apiUrl);
29 | ArrayList qualities = new ArrayList<>();
30 |
31 | try {
32 | Document apiDocument = Jsoup.connect(apiUrl).ignoreContentType(true).post();
33 | JSONObject jsonObject = new JSONObject(apiDocument.text());
34 | JSONArray datas = jsonObject.getJSONArray("data");
35 | for(int i =0;i
2 |
3 |
4 |
5 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | lintOptions{
5 | checkReleaseBuilds false
6 | abortOnError false
7 | }
8 | compileSdkVersion 28
9 | defaultConfig {
10 | applicationId "com.stuffbox.webscraper"
11 | minSdkVersion 23
12 | targetSdkVersion 28
13 | versionCode 1
14 | versionName "6"
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | compileOptions {
24 | targetCompatibility JavaVersion.VERSION_1_8
25 | }
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | testImplementation 'junit:junit:4.12'
31 | implementation 'org.jsoup:jsoup:1.12.1'
32 | implementation 'androidx.appcompat:appcompat:1.1.0'
33 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
34 | testImplementation 'junit:junit:4.12'
35 | implementation 'com.squareup.picasso:picasso:2.71828'
36 | androidTestImplementation 'androidx.test:runner:1.2.0'
37 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
38 | implementation 'com.google.android.material:material:1.2.0-alpha05'
39 | implementation 'androidx.cardview:cardview:1.0.0'
40 | implementation 'com.google.android.exoplayer:exoplayer:2.10.8'
41 | implementation 'androidx.recyclerview:recyclerview:1.1.0'
42 | def room_version = "2.2.5"
43 |
44 | // Java language implementation
45 | implementation "androidx.room:room-runtime:$room_version"
46 | annotationProcessor "android.arch.persistence.room:compiler:$room_version"
47 |
48 | implementation 'androidx.cardview:cardview:1.0.0'
49 | implementation 'commons-io:commons-io:2.6'
50 | androidTestImplementation 'androidx.test:runner:1.2.0'
51 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
52 | implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
53 | annotationProcessor 'androidx.room:room-compiler:2.2.5'
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/models/Anime.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.models;
2 |
3 | import androidx.room.ColumnInfo;
4 | import androidx.room.Entity;
5 | import androidx.room.Ignore;
6 | import androidx.room.PrimaryKey;
7 |
8 | @Entity(tableName = "anime")
9 | public class Anime {
10 | @PrimaryKey(autoGenerate = true)
11 | public int id ;
12 | @ColumnInfo(name = "name")
13 | String name;
14 | @ColumnInfo(name = "link")
15 | String link;
16 | @ColumnInfo(name = "episodeNo")
17 | String episodeNo;
18 | @ColumnInfo(name = "imageLink")
19 | String imageLink;
20 | @ColumnInfo(name = "time")
21 |
22 | String time;
23 | @Ignore
24 | public Anime(String name, String link, String imageLink) {
25 | this.id = id;
26 | this.name = name;
27 | this.link = link;
28 | this.imageLink = imageLink;
29 | episodeNo="";
30 | this.time = "0";
31 |
32 | }
33 |
34 | public Anime(int id ,String name, String link, String episodeno, String imageLink,String time) {
35 | this.id = id;
36 | this.name = name;
37 | this.link = link;
38 | this.episodeNo = episodeno;
39 | this.imageLink = imageLink;
40 | this.time =time;
41 | }
42 | @Ignore
43 | public Anime(String name, String link, String episodeno, String imageLink,String time) {
44 | this.name = name;
45 | this.link = link;
46 | this.episodeNo = episodeno;
47 | this.imageLink = imageLink;
48 | this.time =time;
49 | }
50 |
51 | public String getTime() {
52 | return time;
53 | }
54 |
55 | public void setTime(String time) {
56 | this.time = time;
57 | }
58 |
59 | public Anime()
60 | {
61 |
62 | }
63 |
64 | public String getEpisodeNo() {
65 | return episodeNo;
66 | }
67 |
68 | public void setEpisodeNo(String episodeNo) {
69 | this.episodeNo = episodeNo;
70 | }
71 |
72 | public String getName() {
73 | return name;
74 | }
75 |
76 | public void setName(String name) {
77 | this.name = name;
78 | }
79 |
80 | public String getLink() {
81 | return link;
82 | }
83 |
84 | public void setLink(String link) {
85 | this.link = link;
86 | }
87 |
88 | public String getImageLink() {
89 | return imageLink;
90 | }
91 |
92 | public void setImageLink(String imageLink) {
93 | this.imageLink = imageLink;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
20 |
21 |
22 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
44 |
46 |
52 |
55 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/scrapers/NewScraper.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.scrapers;
2 |
3 | import android.util.Log;
4 |
5 | import com.stuffbox.webscraper.models.Quality;
6 |
7 |
8 | import org.json.JSONArray;
9 | import org.json.JSONObject;
10 | import org.jsoup.Jsoup;
11 | import org.jsoup.nodes.Document;
12 | import org.jsoup.nodes.Element;
13 |
14 | import java.util.ArrayList;
15 | import java.util.regex.Matcher;
16 | import java.util.regex.Pattern;
17 |
18 | public class NewScraper extends Scraper{
19 | private Document gogoAnimePageDocument ;
20 |
21 | public NewScraper(Document gogoAnimePageDocument) {
22 | this.gogoAnimePageDocument = gogoAnimePageDocument;
23 | }
24 |
25 | @Override
26 | public ArrayList getQualityUrls() {
27 | Log.i("newScraperRunning","running");
28 | String vidStreamUrl = gogoAnimePageDocument.getElementsByClass("play-video").get(0).getElementsByTag("iframe").get(0).absUrl("src");
29 | Log.i("vidsteramurl is",vidStreamUrl);
30 | ArrayList qualities = new ArrayList<>();
31 |
32 | vidStreamUrl = vidStreamUrl.replaceAll("streaming.php","loadserver.php");
33 | try {
34 | Document page = Jsoup.connect(vidStreamUrl).ignoreContentType(true).get();
35 | // JSONObject jsonObject = new JSONObject(page.text());
36 | for(Element element: page.getElementsByTag("script")) {
37 | if(element.outerHtml().contains("playerInstance.setup"))
38 | {
39 | Pattern pattern = Pattern.compile("\\[\\.*.*");
40 | Matcher matcher = pattern.matcher(element.outerHtml());
41 | if (matcher.find())
42 | {
43 | Log.i("matched text is",element.outerHtml().substring(matcher.start(),matcher.end()));
44 | String text = element.outerHtml().substring(matcher.start(),matcher.end()).replace("file","'file'").replace("label","'label'");
45 | JSONArray array = new JSONArray(text);
46 | String url = array.getJSONObject(0).getString("file");
47 | String label = array.getJSONObject(0).getString("label");
48 | qualities.add(new Quality(label,url));
49 | }
50 | }
51 | }
52 | return qualities;
53 |
54 | } catch (Exception e) {
55 | e.printStackTrace();
56 | }
57 | System.out.println(vidStreamUrl);
58 | return new ArrayList();
59 |
60 | }
61 |
62 | @Override
63 | public String getHost() {
64 | return "Exoplayer";
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/fragments/RecentFragment.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.fragments;
2 |
3 | import android.content.Context;
4 | import android.database.Cursor;
5 | import android.database.sqlite.SQLiteDatabase;
6 | import android.os.Bundle;
7 | import android.util.Log;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 | import java.util.Objects;
15 |
16 | import androidx.annotation.NonNull;
17 | import androidx.annotation.Nullable;
18 | import androidx.appcompat.widget.Toolbar;
19 | import androidx.fragment.app.Fragment;
20 | import androidx.recyclerview.widget.LinearLayoutManager;
21 | import androidx.recyclerview.widget.RecyclerView;
22 |
23 | import com.stuffbox.webscraper.R;
24 | import com.stuffbox.webscraper.adapters.AnimeDataAdapter;
25 | import com.stuffbox.webscraper.database.AnimeDatabase;
26 | import com.stuffbox.webscraper.models.Anime;
27 |
28 | public class RecentFragment extends Fragment {
29 | private ArrayList mAnimeList = new ArrayList<>();
30 | private RecyclerView recyclerView;
31 |
32 | @Nullable
33 | @Override
34 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
35 | View view=inflater.inflate(R.layout.animefinder,container,false);
36 | recyclerView = view.findViewById(R.id.recyclerview);
37 | return view;
38 | }
39 | @Override
40 | public void onResume() {
41 | getAnimeList();
42 | super.onResume();
43 | }
44 | private void getAnimeList(){
45 | mAnimeList.clear();
46 | // SQLiteDatabase recent=Objects.requireNonNull(getContext()).openOrCreateDatabase("recent",Context.MODE_PRIVATE,null);
47 | // Cursor resultSet = recent.rawQuery("Select * from anime",null);
48 | // resultSet.moveToLast();
49 | // for(int i=resultSet.getCount()-1;i>=0;i--) {
50 | // Anime anime =new Anime();
51 | //
52 | // anime.setName(resultSet.getString(0));
53 | // anime.setEpisodeNo(resultSet.getString(1));
54 | // anime.setLink(resultSet.getString(2));
55 | // anime.setImageLink(resultSet.getString(3));
56 | // Log.d("imagelinkis","soja "+ anime.getImageLink());
57 | //
58 | // mAnimeList.add(anime);
59 | //
60 | // resultSet.move(-1);
61 | // }
62 | AnimeDatabase animeDatabase = AnimeDatabase.getInstance(getContext());
63 | List animeList = animeDatabase.animeDao().getAnimeList();
64 | AnimeDataAdapter mDataAdapter = new AnimeDataAdapter(getContext(), animeList);
65 | RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getContext());
66 | recyclerView.setHasFixedSize(true);
67 | recyclerView.setDrawingCacheEnabled(true);
68 | recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
69 | recyclerView.setItemViewCacheSize(20);
70 | recyclerView.setLayoutManager(mLayoutManager);
71 | recyclerView.setAdapter(mDataAdapter);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/adapters/SearchAdapter.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.adapters;
2 |
3 |
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ImageView;
11 | import android.widget.TextView;
12 | import com.squareup.picasso.Picasso;
13 | import com.stuffbox.webscraper.R;
14 | import com.stuffbox.webscraper.activities.selectEpisode;
15 | import com.stuffbox.webscraper.models.Anime;
16 |
17 | import java.util.ArrayList;
18 | import androidx.annotation.NonNull;
19 | import androidx.cardview.widget.CardView;
20 | import androidx.recyclerview.widget.RecyclerView;
21 |
22 | public class SearchAdapter extends RecyclerView.Adapter {
23 |
24 | private ArrayList mAnimeList = new ArrayList<>();
25 |
26 |
27 | private Context context;
28 | private Activity activity;
29 | public SearchAdapter(Context context, ArrayList AnimeList,Activity activity) {
30 | this.mAnimeList = AnimeList;
31 | this.context=context;
32 | this.activity=activity;
33 | }
34 | public SearchAdapter()
35 | {
36 |
37 | }
38 |
39 | class MyViewHolder extends RecyclerView.ViewHolder {
40 | private CardView cardView;
41 |
42 | private TextView title, episodeno;
43 | private ImageView imageofanime;
44 |
45 | MyViewHolder(View view) {
46 | super(view);
47 | title = view.findViewById(R.id.animename);
48 | episodeno = view.findViewById(R.id.episodeno);
49 | imageofanime= view.findViewById(R.id.img);
50 | cardView= view.findViewById(R.id.cardview);
51 | }
52 | }
53 |
54 | @NonNull
55 | @Override
56 | public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
57 | View itemView = LayoutInflater.from(parent.getContext())
58 | .inflate(R.layout.row_data, parent, false);
59 |
60 | return new MyViewHolder(itemView);
61 | }
62 |
63 | @Override
64 | public void onBindViewHolder(final MyViewHolder holder, final int position) {
65 | holder.title.setText(mAnimeList.get(position).getName());
66 | holder.episodeno.setText(mAnimeList.get(position).getEpisodeNo());
67 | holder.cardView.setOnClickListener(new View.OnClickListener() {
68 | @Override
69 | public void onClick(View v) {
70 | Intent intent=new Intent(context, selectEpisode.class);
71 | intent.putExtra("link",mAnimeList.get(position).getLink());
72 | intent.putExtra("animename",mAnimeList.get(position).getName());
73 | intent.putExtra("imageurl",mAnimeList.get(position).getImageLink());
74 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
75 | context.getApplicationContext().startActivity(intent);
76 | activity.overridePendingTransition(R.anim.anime_slide_in_top,R.anim.anime_slide_out_top);
77 | }
78 | });
79 | Picasso.get().load(mAnimeList.get(position).getImageLink()).into(holder.imageofanime);
80 | }
81 |
82 | @Override
83 | public int getItemCount() {
84 | return mAnimeList.size();
85 | }
86 |
87 | }
88 |
89 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at balvindersi2@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/adapters/QualityAdapter.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.adapters;
2 |
3 | import android.app.DownloadManager;
4 | import android.app.Notification;
5 | import android.content.BroadcastReceiver;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.content.IntentFilter;
9 | import android.net.Uri;
10 | import android.os.Environment;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.widget.BaseAdapter;
15 | import android.widget.Button;
16 | import android.widget.Toast;
17 |
18 | import androidx.core.app.NotificationCompat;
19 |
20 | import com.stuffbox.webscraper.R;
21 |
22 | import java.util.ArrayList;
23 |
24 | public class QualityAdapter extends BaseAdapter {
25 | Context context;
26 | ArrayList quality,links;
27 | int position;
28 | long downloadID;
29 | String animename,episodeno;
30 | LayoutInflater inflater;
31 | public QualityAdapter(Context context, ArrayList quality, ArrayList links,String animename,String episodeno) {
32 | this.context = context;
33 | this.quality = quality;
34 | this.links = links;
35 | this.animename=animename;
36 | this.episodeno=episodeno;
37 | inflater=(LayoutInflater.from(context));
38 | }
39 | @Override
40 | public int getCount()
41 | {
42 | return quality.size();
43 | }
44 | @Override
45 | public Object getItem(int i) {
46 | return null;
47 | }
48 |
49 | @Override
50 | public long getItemId(int i) {
51 | return 0;
52 | }
53 |
54 | @Override
55 | public View getView(int i, View view, ViewGroup viewGroup) {
56 | view = inflater.inflate(R.layout.downloadqualitybutton, null);
57 | Button button = view.findViewById(R.id.buttondownload);
58 | button.setText(quality.get(i));
59 | position=i;
60 | button.setOnClickListener(new View.OnClickListener() {
61 | @Override
62 | public void onClick(View v) {
63 | String url=links.get(position);
64 | /* DownloadManager.Request request=new DownloadManager.Request(Uri.parse(url));
65 | String description=animename+" Episode "+episodeno;
66 | request.setDescription(description);
67 | request.setTitle("Downloading");
68 | request.allowScanningByMediaScanner();
69 | request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
70 | request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, animename+" Episode" +episodeno+".mp4");
71 | DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
72 | downloadID = manager.enqueue(request);
73 | context.registerReceiver(onDownloadComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
74 | */
75 | // Notification notification=new NotificationCompat.Builder(context.getResources(),0);
76 |
77 | }
78 | });
79 | return view;
80 | }
81 | private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
82 | @Override
83 | public void onReceive(Context context, Intent intent) {
84 | //Fetching the download id received with the broadcast
85 | long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
86 | //Checking if the received broadcast is for our enqueued download by matching download id
87 | if (downloadID == id) {
88 | Toast.makeText(context, "Download Completed", Toast.LENGTH_SHORT).show();
89 | }
90 | }
91 | };
92 |
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/tempcode.txt:
--------------------------------------------------------------------------------
1 | /* try {
2 | l = "https:" + x;
3 | // Log.i("Checkingsomethingsomething",l);
4 | org.jsoup.nodes.Document vid = Jsoup.connect(l).get();
5 | Log.i("videf", String.valueOf(vid));
6 | Elements elements = vid.select("script").eq(5);
7 | Elements xxa = vid.select("script");
8 | Log.i("bhaichaljanaa", String.valueOf(xxa.size()));
9 | Log.i("check", String.valueOf(elements));
10 | String urlRegex = "((https?|ftp|gopher|telnet|file):((//)|(\\\\))+[\\w\\d:#@%/;$()~_?\\+-=\\\\\\.&]*)";
11 | Pattern pattern = Pattern.compile(urlRegex, Pattern.CASE_INSENSITIVE);
12 | Matcher urlMatcher = pattern.matcher(String.valueOf(elements));
13 | ArrayList containedUrls = new ArrayList();
14 | while (urlMatcher.find()) {
15 | containedUrls.add(String.valueOf(elements).substring(urlMatcher.start(0),
16 | urlMatcher.end(0)));
17 | }
18 | if (containedUrls.size() == 0) {
19 | Elements x = vid.select("script").eq(3);
20 | String a = "((https?|ftp|gopher|telnet|file):((//)|(\\\\))+[\\w\\d:#@%/;$()~_?\\+-=\\\\\\.&]*)";
21 | Pattern z = Pattern.compile(a, Pattern.CASE_INSENSITIVE);
22 | Matcher y = z.matcher(String.valueOf(x));
23 | ArrayList b = new ArrayList();
24 | while (y.find()) {
25 | containedUrls.add(String.valueOf(x).substring(y.start(0),
26 | y.end(0)));
27 | }
28 | }
29 | //Log.i("loghoja",String.valueOf(containedUrls.size()));
30 | for (int i = 0; i < containedUrls.size(); i++)
31 | Log.i("Checkblabla", containedUrls.get(i));
32 | //Log.i("Checkblabla",containedUrls.get(3));
33 | //if(containedUrls.size()==0)
34 | // Toast.makeText(context,"cannot play video",Toast.LENGTH_SHORT).show();
35 | if(containedUrls.size()==0)
36 | {
37 | Elements elements2=mBlogDocument.select("li[class=mp4]").select("a");
38 | //Log.i("printing size",String.valueOf(elements.size()));
39 | String value=elements2.attr("data-video");
40 | //int index=value.indexOf("embed");
41 | //Log.i("printingindex",String.valueOf(index));
42 | //StringBuffer str=new StringBuffer(value);
43 |
44 | //str.replace(index,index+5,"watch");
45 | // Log.i("printingx",str.toString());
46 |
47 | //Log.i("printing url",value);
48 | // org.jsoup.nodes.Document mp4link=Jsoup.connect(value).get();
49 | // Log.i("sizeofmp4link",String.valueOf(mp4link));
50 | // Elements elements1=mp4link.select("div[id=player]");
51 | // Log.i("printing url",elements1);
52 | l=value;
53 | }
54 | else{ org.jsoup.nodes.Document videostreamlink = Jsoup.connect(containedUrls.get(containedUrls.size() - 1)).get();
55 | if (String.valueOf(videostreamlink).contains("htttps://nl3.")) {
56 | Log.i("chalrhahaiye", "firbhinhichalrha");
57 | videostreamlink = Jsoup.connect(containedUrls.get(4)).get();
58 | }
59 | // qualityvalue=findViewById(R.id.qualityxy);
60 |
61 | Log.i("blablablabla", String.valueOf(videostreamlink));*/
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/adapters/AnimeListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.adapters;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.net.Uri;
7 |
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.ImageView;
12 | import android.widget.LinearLayout;
13 | import android.widget.TextView;
14 |
15 | import com.squareup.picasso.Picasso;
16 | import com.stuffbox.webscraper.activities.AnimeList;
17 | import com.stuffbox.webscraper.R;
18 | import com.stuffbox.webscraper.models.Anime;
19 | import com.stuffbox.webscraper.activities.selectEpisode;
20 |
21 | import java.util.ArrayList;
22 |
23 | import androidx.annotation.NonNull;
24 | import androidx.recyclerview.widget.RecyclerView;
25 |
26 | public class AnimeListAdapter extends RecyclerView.Adapter {
27 |
28 | private ArrayList mAnimeList = new ArrayList<>();
29 | private Context context;
30 | Activity activity;
31 | public AnimeListAdapter(Context context, ArrayList AnimeList ,Activity activity) {
32 | this.mAnimeList = AnimeList;
33 | this.context=context;
34 | this.activity=activity;
35 | }
36 |
37 | class MyViewHolder extends RecyclerView.ViewHolder {
38 | private LinearLayout layout;
39 |
40 | private TextView title;
41 | private ImageView imageView;
42 |
43 | MyViewHolder(View view) {
44 | super(view);
45 | title = view.findViewById(R.id.animen);
46 | layout=view.findViewById(R.id.layout);
47 | imageView=view.findViewById(R.id.animeimage);
48 | }
49 | }
50 |
51 | @NonNull
52 | @Override
53 | public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
54 | View itemView = LayoutInflater.from(parent.getContext())
55 | .inflate(R.layout.adapterforanimelist, parent, false);
56 |
57 | return new MyViewHolder(itemView);
58 | }
59 |
60 | @Override
61 | public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
62 | holder.title.setText(mAnimeList.get(position).getName());
63 | holder.layout.setOnClickListener(new View.OnClickListener() {
64 | @Override
65 | public void onClick(View v) {
66 | Intent intent=new Intent(context, selectEpisode.class);
67 | intent.putExtra("link",mAnimeList.get(position).getLink());
68 | intent.putExtra("animename",mAnimeList.get(position).getName());
69 | // intent.putExtra("imageurl","https://images.gogoanime.tv/cover/yuuyuuhakusho-specials.png");
70 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
71 | context.getApplicationContext().startActivity(intent);
72 | activity.overridePendingTransition(R.anim.anime_slide_in_top,R.anim.anime_slide_out_top);
73 | }
74 | });
75 | if(AnimeList.loadImages==1) { // load images only when searching
76 | holder.setIsRecyclable(false);
77 | holder.imageView.setImageDrawable(null);
78 | holder.imageView.setVisibility(View.VISIBLE);
79 | Picasso.get().load(mAnimeList.get(position).getImageLink()).into(holder.imageView);
80 | }
81 | else {
82 | holder.setIsRecyclable(true);
83 | holder.imageView.setVisibility(View.GONE);
84 | }
85 | }
86 | @Override
87 | public int getItemCount() {
88 | return mAnimeList.size();
89 | }
90 | public void setFilter(ArrayList animeList)
91 | {
92 | mAnimeList=new ArrayList<>();
93 | mAnimeList.addAll(animeList);
94 |
95 | notifyDataSetChanged();
96 | }
97 | }
98 |
99 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
13 |
17 |
18 |
28 |
36 |
37 |
43 |
52 |
53 |
54 |
55 |
62 |
69 |
76 |
85 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/scrapers/Option1.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.scrapers;
2 |
3 |
4 |
5 |
6 | import android.util.Log;
7 |
8 | import com.stuffbox.webscraper.models.Quality;
9 |
10 | import org.jsoup.Jsoup;
11 | import org.jsoup.nodes.Document;
12 |
13 | import java.util.ArrayList;
14 | import java.util.regex.Matcher;
15 | import java.util.regex.Pattern;
16 | //working
17 | public class Option1 extends Scraper {
18 | Document gogoAnimePageDocument ;
19 | private static final Pattern urlPattern = Pattern.compile(
20 | "(?:^|[\\W])((ht|f)tp(s?):\\/\\/|www\\.)"
21 | + "(([\\w\\-]+\\.){1,}?([\\w\\-.~]+\\/?)*"
22 | + "[\\p{Alnum}.,%_=?\\-+()\\[\\]\\$~@!:/{};'])",
23 | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
24 | String m3u8Link;
25 |
26 | public Option1(Document gogoAnimePageDocument)
27 | {
28 | this.gogoAnimePageDocument = gogoAnimePageDocument;
29 | m3u8Link = "";
30 |
31 | }
32 | @Override
33 | public ArrayList getQualityUrls() {
34 | ArrayList qualities= new ArrayList<>();
35 |
36 | try
37 | {
38 | String vidStreamUrl = "https:" + gogoAnimePageDocument.getElementsByClass("play-video").get(0).getElementsByTag("iframe").get(0).attr("src");
39 | //String vidCdnUrl = vidStreamUrl.replace("streaming.php", "load.php");
40 |
41 | Document vidStreamPageDocument = Jsoup.connect(vidStreamUrl).get();
42 |
43 | String html = vidStreamPageDocument.outerHtml();
44 | Matcher matcher = urlPattern.matcher(html);
45 | while (matcher.find()) {
46 | int matchStart = matcher.start(1);
47 | int matchEnd = matcher.end();
48 | String link = html.substring(matchStart, matchEnd);
49 | if (link.contains("m3u8")) {
50 |
51 | m3u8Link = link.substring(0, link.indexOf("'"));
52 | Log.i("ScrapeUrl", m3u8Link);
53 |
54 | break;
55 |
56 | }
57 | }
58 | if(!m3u8Link.equals(""))
59 | {
60 |
61 | Document m3u8Page = Jsoup.connect(m3u8Link).ignoreContentType(true).get();
62 |
63 | String htmlToParse = m3u8Page.outerHtml();
64 | Log.i("html",htmlToParse);
65 | Pattern qualityPattern = Pattern.compile("[0-9]{3,4}x[0-9]{3,4}");
66 | Pattern m3u8LinkPattern = Pattern.compile("(drive//hls/(\\w)*/(\\w)*.m3u8)|(hls/(\\w)*/(\\w)*.m3u8)|(sub\\.\\d*\\.*\\d*\\.m3u8)|(dub\\.\\d*\\.*\\d*\\.m3u8)");
67 | Matcher qualityMatcher = qualityPattern.matcher(htmlToParse);
68 | Matcher m3u8LinkMatcher = m3u8LinkPattern.matcher(htmlToParse);
69 | int index = m3u8Link.lastIndexOf("/hls/");
70 |
71 | String baseUrl = m3u8Link.substring(0, index +"/hls/".length() );
72 | Log.i("baseUrl",baseUrl);
73 | while (qualityMatcher.find() && m3u8LinkMatcher.find()) {
74 | String quality = htmlToParse.substring(qualityMatcher.start(), qualityMatcher.end());
75 | String qualityUrl = baseUrl + htmlToParse.substring(m3u8LinkMatcher.start(), m3u8LinkMatcher.end());
76 | qualities.add(new Quality(quality,qualityUrl) );
77 |
78 | }
79 | Log.i("qualities length",""+qualities.size());
80 |
81 | }
82 |
83 | }
84 | catch (Exception e)
85 | {
86 | Log.i("maichala",e.getMessage());
87 |
88 | e.printStackTrace();
89 |
90 | }
91 | if(qualities.size()==0) {
92 |
93 | qualities.add(new Quality("Unknown", m3u8Link));
94 | Log.i("ScrapeUrl", m3u8Link);
95 | }
96 | return qualities;
97 | }
98 |
99 | @Override
100 | public String getHost() {
101 | return "";
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
25 |
28 |
33 |
46 |
47 |
48 |
55 |
58 |
68 |
69 |
70 |
71 |
80 |
81 |
82 |
83 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/adapters/AnimeDataAdapter.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.adapters;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 |
8 | import android.util.Log;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.ImageView;
13 | import android.widget.TextView;
14 |
15 |
16 | import com.squareup.picasso.Picasso;
17 | import com.stuffbox.webscraper.R;
18 | import com.stuffbox.webscraper.activities.WatchVideo;
19 | import com.stuffbox.webscraper.database.AnimeDatabase;
20 | import com.stuffbox.webscraper.models.Anime;
21 |
22 | import java.util.List;
23 |
24 | import androidx.annotation.NonNull;
25 | import androidx.cardview.widget.CardView;
26 | import androidx.recyclerview.widget.RecyclerView;
27 |
28 |
29 | public class AnimeDataAdapter extends RecyclerView.Adapter {
30 |
31 | private List mAnimeList;
32 |
33 | int size;
34 | private Context context;
35 |
36 | public AnimeDataAdapter(Context context, List AnimeList) {
37 | this.context = context;
38 | this.mAnimeList = AnimeList;
39 |
40 | }
41 |
42 | class MyViewHolder extends RecyclerView.ViewHolder {
43 | private CardView cardView;
44 | private TextView title, episodeno;
45 | private ImageView imageofanime;
46 |
47 | MyViewHolder(View view) {
48 | super(view);
49 | title = view.findViewById(R.id.animename);
50 | episodeno = view.findViewById(R.id.episodeno);
51 | imageofanime = view.findViewById(R.id.img);
52 | cardView = view.findViewById(R.id.cardview);
53 | }
54 | }
55 |
56 | @NonNull
57 | @Override
58 | public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
59 | View itemView = LayoutInflater.from(parent.getContext())
60 | .inflate(R.layout.row_data, parent, false);
61 |
62 | return new MyViewHolder(itemView);
63 | }
64 |
65 | @Override
66 | public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
67 | holder.title.setText(mAnimeList.get(position).getName());
68 | holder.episodeno.setText("Episode " + mAnimeList.get(position).getEpisodeNo());
69 | holder.cardView.setOnClickListener(new View.OnClickListener() {
70 | @Override
71 | public void onClick(View v) {
72 | Intent intent = new Intent(context, WatchVideo.class);
73 | intent.putExtra("link", mAnimeList.get(position).getLink());
74 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
75 | int ep = holder.episodeno.getText().toString().lastIndexOf(" ");
76 | size = 0;
77 | AnimeDatabase database = AnimeDatabase.getInstance(context);
78 |
79 | Anime temp = mAnimeList.get(position);
80 | Anime databaseAnime = database.animeDao().getAnimeByNameAndEpisodeNo(temp.getName(), temp.getEpisodeNo());
81 | Log.i("yotimername", temp.getName());
82 | Log.i("yotimerepisode", String.valueOf(temp.getEpisodeNo()));
83 |
84 | String time = "0";
85 | if (databaseAnime != null) {
86 | time = databaseAnime.getTime();
87 | }
88 | database.animeDao().deleteAnimeByNameAndEpisodeNo(temp.getName(), temp.getEpisodeNo());
89 | Anime anime = new Anime(temp.getName(), temp.getLink(), temp.getEpisodeNo(), temp.getImageLink(), time);
90 | database.animeDao().insertAnime(anime);
91 | intent.putExtra("animename", temp.getName());
92 | intent.putExtra("imagelink", temp.getImageLink());
93 | intent.putExtra("time", time);
94 |
95 | context.getApplicationContext().startActivity(intent);
96 | }
97 | });
98 |
99 | Picasso.get().load(mAnimeList.get(position).getImageLink()).into(holder.imageofanime);
100 | }
101 |
102 | @Override
103 | public int getItemCount() {
104 | return mAnimeList.size();
105 | }
106 |
107 | }
108 |
109 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/exoplayer.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
19 |
31 |
32 |
41 |
42 |
48 |
49 |
51 |
53 |
55 |
56 |
58 |
60 |
61 |
62 |
63 |
65 |
72 |
73 |
74 |
75 |
81 |
82 |
91 |
92 |
99 |
100 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/activities/AnimeList.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.activities;
2 |
3 | import android.os.Bundle;
4 |
5 | import androidx.core.view.MenuItemCompat;
6 | import android.view.Menu;
7 | import android.view.MenuItem;
8 | import android.view.View;
9 |
10 | import org.apache.commons.io.IOUtils;
11 | import org.json.JSONArray;
12 | import org.json.JSONObject;
13 |
14 |
15 | import java.io.InputStream;
16 | import java.util.ArrayList;
17 | import java.util.Objects;
18 |
19 | import androidx.appcompat.app.AppCompatActivity;
20 | import androidx.appcompat.widget.SearchView;
21 | import androidx.appcompat.widget.Toolbar;
22 | import androidx.recyclerview.widget.DefaultItemAnimator;
23 | import androidx.recyclerview.widget.LinearLayoutManager;
24 | import androidx.recyclerview.widget.RecyclerView;
25 |
26 | import com.stuffbox.webscraper.R;
27 | import com.stuffbox.webscraper.adapters.AnimeListAdapter;
28 | import com.stuffbox.webscraper.models.Anime;
29 |
30 | public class AnimeList extends AppCompatActivity implements SearchView.OnQueryTextListener {
31 | private ArrayList animeList= new ArrayList<>();
32 | AnimeListAdapter mDataAdapter;
33 | public static int loadImages=0; // only load Images when user is searching
34 | Toolbar toolbar;
35 | RecyclerView recyclerView;
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState)
38 | {
39 | super.onCreate(savedInstanceState);
40 | setContentView(R.layout.animelistrecyclerview);
41 | toolbar = findViewById(R.id.tool);
42 | setSupportActionBar(toolbar);
43 | Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
44 | getSupportActionBar().setDisplayShowHomeEnabled(true);
45 | toolbar.setNavigationOnClickListener(new View.OnClickListener() {
46 | @Override
47 | public void onClick(View v) {
48 | finish();
49 | overridePendingTransition(R.anim.anim_slide_in_right,R.anim.anim_slide_out_right);
50 | }
51 | });
52 | try
53 | {
54 | // Load json file
55 | InputStream is = getResources().openRawResource(R.raw.animelist);
56 | String s = IOUtils.toString(is);
57 | IOUtils.closeQuietly(is);
58 | JSONArray jsonArray=new JSONArray(s);
59 | for(int i=0;i newAnimeList=new ArrayList<>();
105 | for(int i=0;i
2 |
7 |
14 |
19 |
26 |
33 |
40 |
52 |
60 |
61 |
62 |
63 |
68 |
75 |
87 |
95 |
96 |
97 |
102 |
103 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/adapters/EpisodeAdapter.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.adapters;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.Button;
11 | import android.widget.LinearLayout;
12 | import android.widget.TextView;
13 |
14 | import java.util.ArrayList;
15 |
16 | import androidx.annotation.NonNull;
17 | import androidx.recyclerview.widget.RecyclerView;
18 |
19 | import com.stuffbox.webscraper.Downloader;
20 | import com.stuffbox.webscraper.R;
21 | import com.stuffbox.webscraper.activities.WatchVideo;
22 | import com.stuffbox.webscraper.database.AnimeDatabase;
23 | import com.stuffbox.webscraper.models.Anime;
24 |
25 |
26 | public class EpisodeAdapter extends RecyclerView.Adapter {
27 | private ArrayList mSiteLink;
28 | private ArrayList mEpisodeList;
29 | String animename;
30 | Activity activity;
31 | private Context context;
32 | private String imagelink;
33 |
34 | public EpisodeAdapter(Context context, ArrayList SiteList, ArrayList EpisodeList, String imagelink, String animename, Activity activity) {
35 | this.mSiteLink = SiteList;
36 | this.context = context;
37 | this.animename = animename;
38 | this.mEpisodeList = EpisodeList;
39 | this.imagelink = imagelink;
40 | this.activity = activity;
41 | }
42 |
43 | class MyViewHolder extends RecyclerView.ViewHolder {
44 |
45 | private TextView button;
46 | private Button download;
47 | private LinearLayout layout;
48 |
49 | MyViewHolder(View view) {
50 | super(view);
51 | layout = view.findViewById(R.id.linearlayouta);
52 | button = view.findViewById(R.id.notbutton);
53 | download = view.findViewById(R.id.downloadchoice);
54 | }
55 | }
56 |
57 | @NonNull
58 | @Override
59 | public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
60 | View itemView = LayoutInflater.from(parent.getContext())
61 | .inflate(R.layout.adapterforepisode, parent, false);
62 |
63 | return new MyViewHolder(itemView);
64 | }
65 |
66 | @SuppressLint("SetTextI18n")
67 | @Override
68 | public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
69 | holder.button.setText(animename + " Episode " + (position + 1));
70 | holder.layout.setOnClickListener(new View.OnClickListener() {
71 | @Override
72 | public void onClick(View view) {
73 | Intent intent = new Intent(context, WatchVideo.class);
74 | intent.putExtra("link", mSiteLink.get(position));
75 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
76 | AnimeDatabase database = AnimeDatabase.getInstance(context);
77 |
78 | Anime temp = new Anime(animename, mSiteLink.get(position), String.valueOf(position + 1),imagelink,"0");
79 | Anime databaseAnime = database.animeDao().getAnimeByNameAndEpisodeNo(temp.getName(), temp.getEpisodeNo());
80 |
81 | String time = "0";
82 | if (databaseAnime != null) {
83 | time = databaseAnime.getTime();
84 | }
85 | database.animeDao().deleteAnimeByNameAndEpisodeNo(temp.getName(), temp.getEpisodeNo());
86 | Anime anime = new Anime(temp.getName(), temp.getLink(), temp.getEpisodeNo(), temp.getImageLink(), time);
87 | database.animeDao().insertAnime(anime);
88 | intent.putExtra("animename", animename);
89 | intent.putExtra("imagelink", imagelink);
90 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
91 | intent.putExtra("noofepisodes", String.valueOf(mEpisodeList.size()));
92 | intent.putExtra("animenames", animename);
93 | intent.putExtra("selectepisodelink", mSiteLink.get(position));
94 | intent.putExtra("camefrom", "selectepisode");
95 | context.getApplicationContext().startActivity(intent);
96 | }
97 | });
98 | holder.download.setOnClickListener(new View.OnClickListener() {
99 | @Override
100 | public void onClick(View view) {
101 | new Downloader(mSiteLink.get(position), context, activity, animename, String.valueOf(position + 1)).execute();
102 |
103 | }
104 | });
105 | }
106 |
107 | @Override
108 | public int getItemCount() {
109 | return mEpisodeList.size();
110 | }
111 |
112 | }
113 |
114 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/newepisodelayout.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
14 |
19 |
20 |
25 |
31 |
39 |
40 |
46 |
47 |
52 |
61 |
62 |
69 |
70 |
71 |
72 |
84 |
85 |
96 |
103 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/scrapers/Option2.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.scrapers;
2 |
3 |
4 | import android.util.Log;
5 |
6 | import com.stuffbox.webscraper.models.Quality;
7 | import com.stuffbox.webscraper.scrapers.Scraper;
8 |
9 | import org.jsoup.Jsoup;
10 | import org.jsoup.nodes.Document;
11 |
12 | import java.io.IOException;
13 | import java.net.URL;
14 | import java.util.ArrayList;
15 | import java.util.HashMap;
16 | import java.util.List;
17 | import java.util.regex.Matcher;
18 | import java.util.regex.Pattern;
19 |
20 | public class Option2 extends Scraper {
21 | private static final Pattern urlPattern = Pattern.compile(
22 | "(?:^|[\\W])((ht|f)tp(s?):\\/\\/|www\\.)"
23 | + "(([\\w\\-]+\\.){1,}?([\\w\\-.~]+\\/?)*"
24 | + "[\\p{Alnum}.,%_=?\\-+()\\[\\]\\$~@!:/{};'])",
25 | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
26 | private static final Pattern vidCdnM3u8Pattern = Pattern.compile("((sub|dub)\\\\.[0-9]*\\\\.[0-9]*\\\\.m3u8)|(((sub)|(dub))\\.\\d*\\.\\d*\\.m3u8)");
27 | private static final Pattern vidCdnQualityPattern = Pattern.compile("[0-9]*p");
28 |
29 | public Option2(Document gogoAnimePageDocument) {
30 | this.gogoAnimePageDocument = gogoAnimePageDocument;
31 | }
32 |
33 | public String getHost() {
34 | return host;
35 | }
36 |
37 | private String host;
38 | private Document gogoAnimePageDocument;
39 | @Override
40 | public ArrayList getQualityUrls()
41 | {
42 |
43 | ArrayList qualities = new ArrayList<>();
44 | try {
45 | String vidStreamUrl = "https:" + gogoAnimePageDocument.getElementsByClass("play-video").get(0).getElementsByTag("iframe").get(0).attr("src");
46 | String vidCdnUrl = vidStreamUrl.replace("streaming.php", "streaming.php");
47 | Document vidCdnPageDocument = Jsoup.connect(vidCdnUrl).get();
48 | Log.i("vidcdn","vidcdn is "+vidCdnUrl);
49 |
50 | String htmlToParse = vidCdnPageDocument.outerHtml();
51 | // Log.i("m3u8html",htmlToParse);
52 | Matcher matcher = urlPattern.matcher(htmlToParse);
53 | String m3u8Link="";
54 | while (matcher.find()) {
55 | int matchStart = matcher.start();
56 | int matchEnd = matcher.end();
57 | String link = htmlToParse.substring(matchStart, matchEnd);
58 | if (link.contains("m3u8")) {
59 | m3u8Link = link.substring(1,link.length()-1);
60 | break;
61 | }
62 |
63 | }
64 |
65 | if(!m3u8Link.equals(""))
66 | {
67 | URL url = new URL(m3u8Link);
68 | Log.i("m3u8Url",m3u8Link);
69 |
70 | host = url.getHost();
71 | Log.i("myhost",host);
72 | String userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36";
73 | HashMap headers = new HashMap<>();
74 | headers.put("Accept", "*/*");
75 | headers.put("Accept-Encoding", "gzip,deflate,br");
76 | headers.put("Accept-Language", "en-IN,en;q=0.9,ur-IN;q=0.8,ur;q=0.7,en-GB;q=0.6,en-US;q=0.5");
77 | headers.put("Connection", "keep-alive");
78 | headers.put("Origin", "https://vidstreaming.io");
79 | headers.put("Referer", "https://vidstreaming.io");
80 | headers.put("Sec-Fetch-Mode", "cors");
81 | headers.put("Sec-Fetch-Site", "cross-site");
82 | headers.put("User-Agent", userAgent);
83 | headers.put("Host", host);
84 | String path = url.getFile().substring(0, url.getFile().lastIndexOf('/'));
85 | String base = url.getProtocol() + "://" + url.getHost() + path;
86 | Log.i("baseIs",base);
87 |
88 | Document m3u8PageDocument = Jsoup.connect(m3u8Link).ignoreContentType(true).userAgent(userAgent).headers(headers).get();
89 | System.out.println(m3u8PageDocument.outerHtml());
90 | htmlToParse = m3u8PageDocument.outerHtml();
91 | Matcher m3u8Matcher = vidCdnM3u8Pattern.matcher(htmlToParse);
92 | Matcher qualityMatcher = vidCdnQualityPattern.matcher(htmlToParse);
93 |
94 | while (qualityMatcher.find() && m3u8Matcher.find())
95 | {
96 | System.out.println(htmlToParse.substring(m3u8Matcher.start(),m3u8Matcher.end()));
97 | String qualityUrl = base+"/" + htmlToParse.substring(m3u8Matcher.start(),m3u8Matcher.end());
98 | Log.i("ScrapeUrl",qualityUrl);
99 | String quality = htmlToParse.substring(qualityMatcher.start(),qualityMatcher.end());
100 |
101 | qualities.add(new Quality(quality,qualityUrl));
102 | }
103 | if(qualities.size()==0) {
104 | qualities.add(new Quality("Unknown", m3u8Link));
105 | Log.i("ScrapeUrl",m3u8Link);
106 |
107 | }
108 | }
109 | } catch (Exception e) {
110 | Log.i("m3u8Url",e.getMessage());
111 |
112 | e.printStackTrace();
113 | }
114 | return qualities;
115 | }
116 |
117 | }
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/fragments/AnimeFragment.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.fragments;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.os.AsyncTask;
5 | import android.os.Bundle;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ProgressBar;
11 | import org.jsoup.Jsoup;
12 | import org.jsoup.select.Elements;
13 | import java.io.IOException;
14 | import java.util.ArrayList;
15 |
16 | import androidx.annotation.NonNull;
17 | import androidx.fragment.app.Fragment;
18 | import androidx.recyclerview.widget.LinearLayoutManager;
19 | import androidx.recyclerview.widget.RecyclerView;
20 | import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
21 |
22 | import com.stuffbox.webscraper.R;
23 | import com.stuffbox.webscraper.adapters.AnimeDataAdapter;
24 | import com.stuffbox.webscraper.models.Anime;
25 |
26 | public class AnimeFragment extends Fragment {
27 | private String url;
28 | private ArrayList AnimeList=new ArrayList<>();
29 |
30 | SwipeRefreshLayout swipeRefreshLayout;
31 | View view;
32 | int initial=1;
33 | public static AnimeFragment newInstance(String url)
34 | {
35 | Bundle bundle=new Bundle();
36 | bundle.putString("url",url);
37 | AnimeFragment dubFragment=new AnimeFragment();
38 | dubFragment.setArguments(bundle);
39 | return dubFragment;
40 | }
41 | private void readBundle(Bundle bundle)
42 | {
43 | if(bundle!=null)
44 | {
45 | url=bundle.getString("url");
46 |
47 | }
48 | }
49 |
50 |
51 |
52 | private ProgressBar progressBar;
53 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
54 | Bundle savedInstanceState) {
55 | view=inflater.inflate(R.layout.dublayout,container,false);
56 | swipeRefreshLayout=view.findViewById(R.id.swiperefresh);
57 |
58 | new Dub().execute();
59 | swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
60 | @Override
61 | public void onRefresh() {
62 | swipeRefreshLayout.setRefreshing(true);
63 | new Dub().execute();
64 | }
65 | });
66 | return view;
67 | }
68 |
69 | @SuppressLint("StaticFieldLeak")
70 | private class Dub extends AsyncTask {
71 | String desc;
72 |
73 | @Override
74 | protected void onPreExecute() {
75 | super.onPreExecute();
76 | readBundle(getArguments());
77 | if(initial==1) {
78 | progressBar = view.findViewById(R.id.progress);
79 | progressBar.setVisibility(View.VISIBLE);
80 | // swipeRefreshLayout.setRefreshing(true);
81 | }
82 | }
83 |
84 | @Override
85 | protected Void doInBackground(Void... params) {
86 | try {
87 | org.jsoup.nodes.Document searching;
88 | searching = Jsoup.connect(url).get();
89 | Elements li=searching.select("div[class=last_episodes loaddub]").select("ul[class=items]").select("li");
90 | int size = li.size();
91 | for (int i = 0; i < size; i++) {
92 | Anime anime = new Anime();
93 |
94 | Elements mElementAnimeName=searching.select("p[class=name]").select("a").eq(i);
95 | String mAnimenName= mElementAnimeName.text();
96 | if(mAnimenName.contains("[email protect ed]"))
97 | mAnimenName= mAnimenName.replace("[email protected]","IDOLM@STER");
98 | String mlink=searching.select("p[class=name]").select("a").eq(i).attr("abs:href");
99 | String imagelink=searching.select("div[class=img]").select("img").eq(i).attr("src");
100 | String episodeno=searching.select("p[class=episode]").eq(i).text();
101 | int index = episodeno.indexOf(" ");
102 | episodeno = episodeno.substring(index+1);
103 | anime.setName(mAnimenName);
104 | Log.i("imagelinkis",imagelink);
105 | anime.setLink(mlink);
106 | anime.setEpisodeNo(episodeno);
107 | anime.setImageLink(imagelink);
108 | AnimeList.add(anime);
109 | }
110 | } catch (IOException e) {
111 | e.printStackTrace();
112 | }
113 | return null;
114 | }
115 | @Override
116 | protected void onPostExecute(Void result) {
117 | RecyclerView mRecyclerView = view.findViewById(R.id.act_recyclerview);
118 | AnimeDataAdapter mDataAdapter = new AnimeDataAdapter(view.getContext(), AnimeList);
119 | RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(view.getContext());
120 | mRecyclerView.setHasFixedSize(true);
121 | mRecyclerView.setDrawingCacheEnabled(true);
122 | mRecyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
123 | mRecyclerView.setItemViewCacheSize(20);
124 | mRecyclerView.setLayoutManager(mLayoutManager);
125 | mRecyclerView.setAdapter(mDataAdapter);
126 | initial=0;
127 | progressBar.setVisibility(View.GONE);
128 | swipeRefreshLayout.setRefreshing(false);
129 | }
130 | }
131 | @Override
132 | public void onResume() {
133 | super.onResume();
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/activities/webvideo.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.activities;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.net.http.SslError;
6 | import android.os.Bundle;
7 | import android.util.Log;
8 | import android.view.KeyEvent;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.webkit.SslErrorHandler;
12 | import android.webkit.WebChromeClient;
13 | import android.webkit.WebSettings;
14 | import android.webkit.WebView;
15 | import android.webkit.WebViewClient;
16 | import android.widget.FrameLayout;
17 |
18 | import com.stuffbox.webscraper.R;
19 |
20 | public class webvideo extends Activity {
21 | private WebView webView;
22 | private FrameLayout customViewContainer;
23 | private WebChromeClient.CustomViewCallback customViewCallback;
24 | private View mCustomView;
25 | private myWebChromeClient mWebChromeClient;
26 | private myWebViewClient mWebViewClient;
27 | String url;
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.webviewer);
32 | webView = findViewById(R.id.ASZ);
33 | customViewContainer = findViewById(R.id.customViewContainer);
34 | mWebViewClient = new myWebViewClient();
35 | webView.setWebViewClient(mWebViewClient);
36 | mWebChromeClient = new myWebChromeClient();
37 | WebSettings settings = webView.getSettings();
38 | webView.setWebChromeClient(mWebChromeClient);
39 | settings.setJavaScriptEnabled(true);
40 | settings.setAppCacheEnabled(true);
41 | settings.setSaveFormData(true);
42 | try {
43 | url = getIntent().getStringExtra("videostreamlink");
44 | }catch (Exception e)
45 | {
46 | e.printStackTrace();
47 | }
48 |
49 | Log.i("checkingstring",url);
50 |
51 | webView.loadUrl(url);
52 |
53 | }
54 | public boolean inCustomView() {
55 | return (mCustomView != null);
56 | }
57 | public void hideCustomView() {
58 | mWebChromeClient.onHideCustomView();
59 | }
60 | @Override
61 | protected void onPause() {
62 | super.onPause();
63 | webView.onPause();
64 | }
65 |
66 | @Override
67 | protected void onResume() {
68 | super.onResume();
69 | webView.onResume();
70 | }
71 |
72 | @Override
73 | protected void onStop() {
74 | super.onStop();
75 | if (inCustomView()) {
76 | hideCustomView();
77 | }
78 | }
79 | @Override
80 | public boolean onKeyDown(int keyCode, KeyEvent event) {
81 | if (keyCode == KeyEvent.KEYCODE_BACK) {
82 |
83 | if (inCustomView()) {
84 | hideCustomView();
85 | return true;
86 | }
87 |
88 | if ((mCustomView == null) && webView.canGoBack()) {
89 | webView.goBack();
90 | return true;
91 | }
92 | }
93 | return super.onKeyDown(keyCode, event);
94 | }
95 |
96 | class myWebChromeClient extends WebChromeClient {
97 | private Bitmap mDefaultVideoPoster;
98 | private View mVideoProgressView;
99 |
100 |
101 | @Override
102 | public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
103 | onShowCustomView(view, callback);
104 | }
105 |
106 |
107 | @Override
108 | public void onShowCustomView(View view,CustomViewCallback callback) {
109 |
110 | if (mCustomView != null) {
111 | callback.onCustomViewHidden();
112 | return;
113 | }
114 | mCustomView = view;
115 | webView.setVisibility(View.GONE);
116 | customViewContainer.setVisibility(View.VISIBLE);
117 | customViewContainer.addView(view);
118 | customViewCallback = callback;
119 | }
120 |
121 | @Override
122 | public View getVideoLoadingProgressView() {
123 |
124 | if (mVideoProgressView == null) {
125 | LayoutInflater inflater = LayoutInflater.from(webvideo.this);
126 | mVideoProgressView = inflater.inflate(R.layout.video_progress, null);
127 | }
128 | return mVideoProgressView;
129 | }
130 |
131 | @Override
132 | public void onHideCustomView() {
133 | super.onHideCustomView();
134 | if (mCustomView == null)
135 | return;
136 |
137 | webView.setVisibility(View.VISIBLE);
138 | customViewContainer.setVisibility(View.GONE);
139 |
140 | mCustomView.setVisibility(View.GONE);
141 |
142 | customViewContainer.removeView(mCustomView);
143 | customViewCallback.onCustomViewHidden();
144 |
145 | mCustomView = null;
146 | }
147 | }
148 |
149 | class myWebViewClient extends WebViewClient {
150 | @Override
151 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
152 | return true; }
153 | @Override
154 | public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError er) {
155 | handler.proceed();
156 | }
157 |
158 | }
159 | @Override
160 | public void onWindowFocusChanged(boolean hasFocus) {
161 | super.onWindowFocusChanged(hasFocus);
162 | if (hasFocus) {
163 | hideSystemUI();
164 |
165 | }
166 | }
167 | private void hideSystemUI() {
168 | View decorView = getWindow().getDecorView();
169 | int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
170 | | View.SYSTEM_UI_FLAG_FULLSCREEN|View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
171 | decorView.setSystemUiVisibility(uiOptions);
172 | }
173 |
174 | }
175 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/Downloader.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.content.Context;
6 | import android.os.AsyncTask;
7 | import android.util.Log;
8 | import android.view.Gravity;
9 | import android.view.View;
10 | import android.widget.ListView;
11 | import android.widget.ProgressBar;
12 | import android.widget.RelativeLayout;
13 | import android.widget.Toast;
14 |
15 | import com.stuffbox.webscraper.adapters.QualityAdapter;
16 | import com.stuffbox.webscraper.constants.Constants;
17 |
18 | import org.jsoup.Jsoup;
19 | import org.jsoup.nodes.Document;
20 | import org.jsoup.select.Elements;
21 |
22 | import java.util.ArrayList;
23 |
24 | public class Downloader extends AsyncTask {
25 | private String baseurl;
26 | Context context;
27 | Dialog mBottomSheetDialog;
28 | ProgressBar bar;
29 | ArrayList links=new ArrayList<>();
30 | ArrayList quality=new ArrayList<>();
31 | Activity activity;
32 | String animename,episodeno;
33 | public Downloader(String baseurl, Context context, Activity activity,String animename,String episodeno) {
34 | this.baseurl=baseurl;
35 | this.context=context;
36 | this.activity=activity;
37 | this.animename=animename;
38 | this.episodeno=episodeno;
39 | }
40 | int flag=0; // flag=1 means no download links
41 | @Override
42 | protected void onPreExecute() {
43 | super.onPreExecute();
44 | mBottomSheetDialog=new Dialog(activity,R.style.MaterialDialogSheet);
45 | mBottomSheetDialog.setContentView(R.layout.downloadsheet);
46 | mBottomSheetDialog.setCancelable(true);
47 | mBottomSheetDialog.getWindow().setLayout(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
48 | mBottomSheetDialog.getWindow().setGravity(Gravity.BOTTOM);
49 | bar=mBottomSheetDialog.findViewById(R.id.loader);
50 | bar.setVisibility(View.VISIBLE);
51 | mBottomSheetDialog.show();
52 | }
53 |
54 | @Override
55 | protected Void doInBackground(Void... voids) {
56 | Document document;
57 | Log.i("downloadlinks",baseurl);
58 | try {
59 | if (baseurl.equals(Constants.url+"ansatsu-kyoushitsu-tv--episode-1")) //edge case
60 | document = Jsoup.connect(Constants.url+"ansatsu-kyoushitsu-episode-1").get();
61 | else
62 | document = Jsoup.connect(baseurl).get();
63 | String vidstreamlink=document.select("div[class=play-video]").select("iframe").attr("src");
64 | int indexofid=vidstreamlink.indexOf("id=");
65 | int indexofand=vidstreamlink.indexOf("&");
66 | String id=vidstreamlink.substring(indexofid,indexofand);
67 | String viddownload="https://vidstreaming.io/download?"+id;
68 | Log.i("downloadlinks",viddownload);
69 | document=Jsoup.connect(viddownload).get();
70 | Elements possibledownloadlinks=document.select("div[class=dowload]");
71 | //First check for direct downloadlinks
72 | int i=0;
73 | while (possibledownloadlinks.eq(i).select("a").attr("href").contains("google")) {
74 | links.add(possibledownloadlinks.eq(i).select("a").attr("href"));
75 | quality.add(possibledownloadlinks.eq(i).select("a").text());
76 | i++;
77 | }
78 | if(i==0) // No google links
79 | {
80 | //Try to get rapidvideo links;
81 | //Get rapidvideo index;
82 | for(i=0;i0)
96 | {
97 | Elements rapidvideolinks=video.eq(video.size()-1).select("a");
98 | if(rapidvideolinks.size()==0)
99 | flag=1;
100 | else
101 | {
102 | for(int j=0;j mEpisodeList = new ArrayList<>();
45 | private ArrayList mSiteLink = new ArrayList<>();
46 | EpisodeAdapter mDataAdapter;
47 | String imagelink;
48 | ImageView imageofanime;
49 | TextInputEditText editText;
50 | TextView plotsummary;
51 | LinearLayout linearLayout;
52 | String summary;
53 | AnimeDatabase animeDatabase;
54 |
55 | ProgressBar bar;
56 | RecyclerView mRecyclerView;
57 | String cameback = "false";
58 |
59 | @Override
60 | protected void onCreate(Bundle savedInstanceState) {
61 | super.onCreate(savedInstanceState);
62 | setContentView(R.layout.newepisodelayout);
63 | animenameforrecents = getIntent().getStringExtra("animename");
64 | Toolbar toolbar = findViewById(R.id.actiontool);
65 | linearLayout = findViewById(R.id.linear);
66 | plotsummary = findViewById(R.id.summary);
67 | imageofanime = findViewById(R.id.animeimage);
68 | setSupportActionBar(toolbar);
69 | Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
70 | getSupportActionBar().setDisplayShowHomeEnabled(true);
71 | getSupportActionBar().setTitle(animenameforrecents);
72 | animeDatabase = AnimeDatabase.getInstance(this);
73 | toolbar.setNavigationOnClickListener(new View.OnClickListener() {
74 | @Override
75 | public void onClick(View v) {
76 | finish();
77 | overridePendingTransition(R.anim.anim_slide_in_bottom, R.anim.anim_slide_out_bottom);
78 |
79 | }
80 | });
81 | link = getIntent().getStringExtra("link");
82 | if (getIntent().getStringExtra("cameback") != null)
83 | cameback = getIntent().getStringExtra("cameback");
84 | StringBuilder b = new StringBuilder();
85 | for (int i = 0; i < link.length(); i++) {
86 | if (link.charAt(i) == 'y') {
87 | if (link.charAt(i + 1) == '/') {
88 | for (int j = i + 2; j < link.length(); j++)
89 | b.append(link.charAt(j));
90 | break;
91 | }
92 | }
93 |
94 | }
95 | animename = b.toString();
96 | new SearchingEpisodes().execute();
97 | editText = findViewById(R.id.episodeno);
98 | Button button = findViewById(R.id.episodeselector);
99 | button.setOnClickListener(new View.OnClickListener() {
100 | @Override
101 | public void onClick(View view) {
102 | if (!editText.getText().toString().equals("")) {
103 | int episodeno = Integer.parseInt(String.valueOf(editText.getText()));
104 | Intent intent = new Intent(getApplicationContext(), WatchVideo.class);
105 | intent.putExtra("link", mSiteLink.get(episodeno - 1));
106 | intent.putExtra("noofepisodes", String.valueOf(mEpisodeList.size()));
107 | AnimeDatabase database = AnimeDatabase.getInstance(getApplicationContext());
108 | Anime temp = database.animeDao().getAnimeByNameAndEpisodeNo(animenameforrecents, String.valueOf(episodeno));
109 | String time = "0";
110 | if (temp != null)
111 | time = temp.getTime();
112 | database.animeDao().deleteAnimeByNameAndEpisodeNo(animenameforrecents, String.valueOf(episodeno));
113 | Anime anime = new Anime(animenameforrecents, mSiteLink.get(episodeno - 1),String.valueOf(episodeno), imagelink, time);
114 | database.animeDao().insertAnime(anime);
115 | intent.putExtra("imagelink", imagelink);
116 | intent.putExtra("animename", animenameforrecents);
117 | intent.putExtra("animenames", animenameforrecents);
118 | intent.putExtra("camefrom", "selectepisode");
119 | intent.putExtra("selectepisodelink", link);
120 | intent.putExtra("time", time);
121 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
122 | startActivity(intent);
123 | } else {
124 | editText.requestFocus();
125 | editText.setError("Enter episode no first");
126 | }
127 | }
128 | });
129 | }
130 |
131 | @SuppressLint("StaticFieldLeak")
132 | private class SearchingEpisodes extends AsyncTask {
133 | @Override
134 | protected void onPreExecute() {
135 | super.onPreExecute();
136 | linearLayout.setVisibility(View.GONE);
137 | mRecyclerView = findViewById(R.id.xyza);
138 | mRecyclerView.setVisibility(View.GONE);
139 | plotsummary.setVisibility(View.GONE);
140 | imageofanime.setVisibility(View.GONE);
141 | bar = findViewById(R.id.loading);
142 | bar.setVisibility(View.VISIBLE);
143 |
144 | }
145 |
146 | @Override
147 | protected Void doInBackground(Void... params) {
148 | try {
149 | org.jsoup.nodes.Document searching = Jsoup.connect(link).get();
150 | Elements li = searching.select("div[class=anime_video_body]").select("ul[id=episode_page]").select("li");
151 | imagelink = searching.select("div[class=anime_info_body_bg]").select("img").attr("src");
152 | summary = searching.select("div[class=anime_info_body_bg]").select("p[class=type]").eq(1).text();
153 | String a = String.valueOf(li.select("a").eq(li.size() - 1).html());
154 | int end;
155 | if (a.contains("-")) {
156 | int index = a.indexOf('-');
157 | end = Integer.parseInt(a.substring(index + 1));
158 | } else {
159 | end = Integer.parseInt(a);
160 | }
161 | Log.d("episodesare", String.valueOf(end));
162 | if (end != 0)
163 | for (int i = 1; i <= end; i++) {
164 | String c = Constants.url+"/watch/" + animename + "-episode-" + i;
165 | Log.i("cis",c);
166 | mEpisodeList.add(String.valueOf(i));
167 |
168 | mSiteLink.add(c);
169 | }
170 | else {
171 | String c = Constants.url+"/watch/" + animename + "-episode-" + 0;
172 | mEpisodeList.add(String.valueOf(0));
173 |
174 | mSiteLink.add(c);
175 | }
176 | } catch (Exception e) {
177 | e.printStackTrace();
178 | }
179 | return null;
180 | }
181 |
182 | @Override
183 | protected void onPostExecute(Void result) {
184 | mRecyclerView.setVisibility(View.VISIBLE);
185 | plotsummary.setVisibility(View.VISIBLE);
186 | imageofanime.setVisibility(View.VISIBLE);
187 | bar.setVisibility(View.GONE);
188 | linearLayout.setVisibility(View.VISIBLE);
189 | findViewById(R.id.view).setVisibility(View.VISIBLE);
190 | findViewById(R.id.text12).setVisibility(View.VISIBLE);
191 | mDataAdapter = new EpisodeAdapter(getApplicationContext(), mSiteLink, mEpisodeList, imagelink, animenameforrecents, selectEpisode.this);
192 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
193 | linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
194 | plotsummary.setText(summary);
195 | Picasso.get().load(imagelink).into(imageofanime);
196 |
197 |
198 | mRecyclerView.setHasFixedSize(true);
199 |
200 | mRecyclerView.setLayoutManager(linearLayoutManager);
201 | mRecyclerView.setAdapter(mDataAdapter);
202 | editText.setHint("Episode no between 1 to " + mEpisodeList.size());
203 | editText.setFilters(new InputFilter[]{
204 | new InputFilterMinMax(1, mEpisodeList.size())
205 | })
206 | ;
207 |
208 | editText.requestFocus();
209 | }
210 | }
211 |
212 | @Override
213 | public boolean onKeyDown(int keyCode, KeyEvent event) {
214 |
215 |
216 | if (keyCode == KeyEvent.KEYCODE_BACK) {
217 | if (!cameback.equals("false")) {
218 | Intent intent = new Intent(this, MainActivity.class);
219 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
220 | intent.putExtra("playtuturu", "play");
221 | startActivity(intent);
222 | }
223 |
224 | }
225 | super.onBackPressed();
226 | overridePendingTransition(R.anim.anim_slide_in_bottom, R.anim.anim_slide_out_bottom);
227 | return false;
228 | }
229 | }
230 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/activities/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.activities;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Intent;
5 | import android.content.SharedPreferences;
6 | import android.database.sqlite.SQLiteDatabase;
7 | import android.media.MediaPlayer;
8 | import android.net.ConnectivityManager;
9 | import android.net.NetworkInfo;
10 | import android.os.AsyncTask;
11 | import android.os.Bundle;
12 | import android.util.Log;
13 | import android.view.Menu;
14 | import android.view.MenuItem;
15 | import android.view.View;
16 | import android.widget.FrameLayout;
17 | import android.widget.LinearLayout;
18 | import android.widget.ProgressBar;
19 |
20 | import com.google.android.material.appbar.AppBarLayout;
21 | import com.google.android.material.bottomnavigation.BottomNavigationView;
22 | import com.google.android.material.tabs.TabLayout;
23 | import com.stuffbox.webscraper.R;
24 | import com.stuffbox.webscraper.adapters.SearchAdapter;
25 | import com.stuffbox.webscraper.adapters.ViewPagerAdapter;
26 | import com.stuffbox.webscraper.constants.Constants;
27 | import com.stuffbox.webscraper.database.AnimeDatabase;
28 | import com.stuffbox.webscraper.models.Anime;
29 |
30 | import org.jsoup.Jsoup;
31 | import org.jsoup.select.Elements;
32 |
33 | import java.util.ArrayList;
34 |
35 | import androidx.annotation.NonNull;
36 | import androidx.annotation.Nullable;
37 | import androidx.appcompat.app.AppCompatActivity;
38 | import androidx.appcompat.widget.SearchView;
39 | import androidx.appcompat.widget.Toolbar;
40 | import androidx.core.view.MenuItemCompat;
41 |
42 | import androidx.recyclerview.widget.LinearLayoutManager;
43 | import androidx.recyclerview.widget.RecyclerView;
44 | import androidx.viewpager.widget.ViewPager;
45 |
46 | public class MainActivity extends AppCompatActivity {
47 | Toolbar toolbar;
48 | LinearLayout noanime;
49 | String searchurl;
50 | AppBarLayout appBarLayout;
51 | private ArrayList mAnimeList = new ArrayList<>();
52 | MenuItem prevMenuItem;
53 | RecyclerView recyclerView;
54 |
55 | BottomNavigationView bottomNavigationView;
56 | ViewPager viewPager;
57 | SearchAdapter DataAdapter;
58 | SearchingAnime x = new SearchingAnime();
59 | ProgressBar progressBar;
60 | @Override
61 | protected void onCreate(@Nullable Bundle savedInstanceState) {
62 | super.onCreate(savedInstanceState);
63 | setContentView(R.layout.activity_main);
64 | SharedPreferences preferences=getSharedPreferences("settings",0);
65 | playTuturuSound(preferences);
66 | if(!haveNetworkConnection(getApplicationContext()))
67 | {
68 | LinearLayout linearLayout1=findViewById(R.id.notvisiblelinearlayout);
69 | linearLayout1.setVisibility(View.VISIBLE);
70 | viewPager=findViewById(R.id.viewPager);
71 | viewPager.setVisibility(View.GONE);
72 | bottomNavigationView=findViewById(R.id.bottom_navigation);
73 | bottomNavigationView.setVisibility(View.GONE);
74 | appBarLayout=findViewById(R.id.appbar);
75 | appBarLayout.setVisibility(View.GONE);
76 | }else{
77 |
78 | bottomNavigationView=findViewById(R.id.bottom_navigation);
79 | bottomNavigationView.setOnNavigationItemSelectedListener(
80 | new BottomNavigationView.OnNavigationItemSelectedListener() {
81 | @Override
82 | public boolean onNavigationItemSelected(@NonNull MenuItem item) {
83 | switch (item.getItemId()) {
84 | case R.id.DUB:
85 | viewPager.setCurrentItem(0);
86 | break;
87 | case R.id.SUB:
88 | viewPager.setCurrentItem(1);
89 | break;
90 | case R.id.recent:
91 | viewPager.setCurrentItem(2);
92 | break;
93 | }
94 | return false;
95 | }
96 | });
97 | toolbar = findViewById(R.id.tool);
98 | setSupportActionBar(toolbar);
99 |
100 | noanime=findViewById(R.id.noanime);
101 | ViewPagerAdapter viewPagerAdapter;
102 | viewPager = findViewById(R.id.viewPager);
103 | AnimeDatabase animeDatabase = AnimeDatabase.getInstance(this);
104 | progressBar=findViewById(R.id.progress2);
105 | viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
106 | viewPager.setOffscreenPageLimit(3);
107 | viewPager.setAdapter(viewPagerAdapter);
108 | viewPager.setCurrentItem(1);
109 | bottomNavigationView.getMenu().getItem(1).setChecked(true);
110 | viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
111 | @Override
112 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
113 |
114 | }
115 |
116 | @Override
117 | public void onPageSelected(int position) {
118 | if (prevMenuItem != null)
119 | prevMenuItem.setChecked(false);
120 | else
121 | bottomNavigationView.getMenu().getItem(0).setChecked(false);
122 |
123 | bottomNavigationView.getMenu().getItem(position).setChecked(true);
124 | prevMenuItem = bottomNavigationView.getMenu().getItem(position);
125 | }
126 |
127 | @Override
128 | public void onPageScrollStateChanged(int state) {
129 |
130 | }
131 | });
132 |
133 | }
134 | }
135 | @Override
136 | public boolean onCreateOptionsMenu(Menu menu) {
137 |
138 | getMenuInflater().inflate(R.menu.drawer, menu);
139 | MenuItem search = menu.findItem(R.id.action_search);
140 | MenuItem animelist = menu.findItem(R.id.animelist);
141 | animelist.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
142 | @Override
143 | public boolean onMenuItemClick(MenuItem menuItem) {
144 | Intent i = new Intent(getApplicationContext(), AnimeList.class);
145 | startActivity(i);
146 | overridePendingTransition(R.anim.anim_slide_in_left,R.anim.anim_slide_out_left);
147 | return false;
148 | }
149 | });
150 | MenuItem settings=menu.findItem(R.id.settings);
151 | settings.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
152 | @Override
153 | public boolean onMenuItemClick(MenuItem item) {
154 | Intent intent=new Intent(getApplicationContext(),Settings.class);
155 | startActivity(intent);
156 | return false;
157 | }
158 | });
159 | SearchView searchView = (SearchView) MenuItemCompat.getActionView(search);
160 | searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
161 | @Override
162 | public boolean onQueryTextSubmit(String query) {
163 | return false;
164 | }
165 |
166 | @Override
167 | public boolean onQueryTextChange(String newText) {
168 | newText = newText.toLowerCase();
169 | noanime.setVisibility(View.GONE);
170 |
171 | if (newText.length() >= 3) {
172 | RecyclerView recyclerView = findViewById(R.id.recyclerview2);
173 | recyclerView.setVisibility(View.VISIBLE);
174 | viewPager.setVisibility(View.GONE);
175 | bottomNavigationView.setVisibility(View.GONE);
176 | searchurl = Constants.url+"/search?keyword=" + newText;
177 | if (x.getStatus() == AsyncTask.Status.RUNNING)
178 | x.cancel(true);
179 | x = new SearchingAnime();
180 | x.execute();
181 |
182 | }
183 | else
184 | {
185 | if (x.getStatus() == AsyncTask.Status.RUNNING)
186 | x.cancel(true);
187 | RecyclerView recyclerView = findViewById(R.id.recyclerview2);
188 | recyclerView.setVisibility(View.GONE);
189 | progressBar=findViewById(R.id.progress2);
190 |
191 | viewPager.setVisibility(View.VISIBLE);
192 | bottomNavigationView.setVisibility(View.VISIBLE);
193 | progressBar.setVisibility(View.GONE);
194 | }
195 | return false;
196 | }
197 | });
198 | return true;
199 | }
200 |
201 | @SuppressLint("StaticFieldLeak")
202 | private class SearchingAnime extends AsyncTask {
203 | @Override
204 | protected void onPreExecute() {
205 | super.onPreExecute();
206 | recyclerView = findViewById(R.id.recyclerview2);
207 | recyclerView.setVisibility(View.GONE);
208 | progressBar.setVisibility(View.VISIBLE);
209 | }
210 |
211 | @Override
212 | protected Void doInBackground(Void... params) {
213 | try {
214 |
215 | org.jsoup.nodes.Document searching = Jsoup.connect(searchurl).get();
216 | DataAdapter = new SearchAdapter();
217 | DataAdapter.notifyItemRangeRemoved(0, mAnimeList.size());
218 | mAnimeList.clear();
219 |
220 | Elements li = searching.select("div[class=main_body]").select("div[class=last_episodes]").select("ul[class=items]").select("li");
221 | for (int i = 0; i < li.size(); i++) {
222 | Anime anime = new Anime();
223 | anime.setLink(li.select("div[class=img]").eq(i).select("a").attr("abs:href"));
224 | anime.setName(li.select("div[class=img]").eq(i).select("a").attr("title"));
225 | anime.setImageLink(li.select("div[class=img]").eq(i).select("img").attr("src"));
226 | mAnimeList.add(anime);
227 |
228 | }
229 | } catch (Exception e) {
230 | e.printStackTrace();
231 | }
232 | return null;
233 | }
234 |
235 | @Override
236 | protected void onPostExecute(Void result) {
237 | progressBar.setVisibility(View.GONE);
238 | if (mAnimeList.size() == 0)
239 | noanime.setVisibility(View.VISIBLE);
240 | else {
241 | recyclerView.setVisibility(View.VISIBLE);
242 |
243 | DataAdapter = new SearchAdapter(getApplicationContext(), mAnimeList,MainActivity.this);
244 | RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
245 | recyclerView.setHasFixedSize(true);
246 | recyclerView.setDrawingCacheEnabled(true);
247 | recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
248 | recyclerView.setItemViewCacheSize(30);
249 | recyclerView.setLayoutManager(mLayoutManager);
250 | recyclerView.setAdapter(DataAdapter);
251 | }
252 | }
253 | }
254 |
255 | @Override
256 | public void onBackPressed() {
257 | try {
258 | if (!(viewPager.getCurrentItem() == 1) && viewPager.getVisibility()==View.VISIBLE)
259 | viewPager.setCurrentItem(1);
260 | else
261 | super.onBackPressed();
262 | }
263 | catch (Exception e)
264 | {
265 | e.printStackTrace();
266 | super.onBackPressed();
267 | }
268 | }
269 | void playTuturuSound(SharedPreferences preferences)
270 | {
271 | if(!(preferences.contains("playtuturu")))
272 |
273 | { SharedPreferences.Editor editor = preferences.edit();
274 | editor.putInt("playtuturu",1);
275 | editor.apply();
276 | }
277 | if(preferences.getInt("playtuturu",0)==1)
278 | {
279 | final MediaPlayer mediaPlayer= MediaPlayer.create(this,R.raw.tuturu);
280 | mediaPlayer.start();
281 | mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
282 | @Override
283 | public void onCompletion(MediaPlayer mp) {
284 | mediaPlayer.release();
285 | }
286 |
287 | });
288 | }
289 | }
290 | boolean haveNetworkConnection(android.content.Context context) {
291 | boolean haveConnectedWifi = false;
292 | boolean haveConnectedMobile = false;
293 |
294 | ConnectivityManager cm = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
295 | NetworkInfo[] netInfo = cm.getAllNetworkInfo();
296 | for (NetworkInfo ni : netInfo) {
297 | if (ni.getTypeName().equalsIgnoreCase("WIFI"))
298 | if (ni.isConnected())
299 | haveConnectedWifi = true;
300 | if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
301 | if (ni.isConnected())
302 | haveConnectedMobile = true;
303 | }
304 | return haveConnectedWifi || haveConnectedMobile;
305 | }
306 | }
307 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stuffbox/webscraper/activities/WatchVideo.java:
--------------------------------------------------------------------------------
1 | package com.stuffbox.webscraper.activities;
2 |
3 | import android.app.ActivityManager;
4 | import android.app.AlertDialog;
5 | import android.app.PendingIntent;
6 | import android.app.PictureInPictureParams;
7 | import android.app.RemoteAction;
8 | import android.content.BroadcastReceiver;
9 | import android.content.Context;
10 | import android.content.DialogInterface;
11 | import android.content.Intent;
12 | import android.content.IntentFilter;
13 | import android.content.res.Configuration;
14 | import android.graphics.drawable.Icon;
15 | import android.net.Uri;
16 | import android.os.AsyncTask;
17 | import android.os.Bundle;
18 | import android.util.Log;
19 | import android.view.KeyEvent;
20 | import android.view.View;
21 | import android.widget.ImageButton;
22 | import android.widget.LinearLayout;
23 | import android.widget.ProgressBar;
24 | import android.widget.TextView;
25 | import android.widget.Toast;
26 |
27 | import androidx.annotation.DrawableRes;
28 | import androidx.annotation.NonNull;
29 | import androidx.annotation.Nullable;
30 | import androidx.appcompat.app.AppCompatActivity;
31 |
32 | import com.google.android.exoplayer2.ExoPlaybackException;
33 | import com.google.android.exoplayer2.ExoPlayer;
34 | import com.google.android.exoplayer2.ExoPlayerFactory;
35 | import com.google.android.exoplayer2.Player;
36 | import com.google.android.exoplayer2.SimpleExoPlayer;
37 | import com.google.android.exoplayer2.source.ExtractorMediaSource;
38 | import com.google.android.exoplayer2.source.MediaSource;
39 | import com.google.android.exoplayer2.source.hls.HlsMediaSource;
40 | import com.google.android.exoplayer2.ui.PlayerView;
41 | import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
42 | import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
43 | import com.google.android.exoplayer2.upstream.HttpDataSource;
44 | import com.google.android.exoplayer2.util.Util;
45 | import com.stuffbox.webscraper.R;
46 | import com.stuffbox.webscraper.database.AnimeDatabase;
47 | import com.stuffbox.webscraper.models.Anime;
48 | import com.stuffbox.webscraper.models.Quality;
49 | import com.stuffbox.webscraper.scrapers.NewScraper;
50 | import com.stuffbox.webscraper.scrapers.Option1;
51 | import com.stuffbox.webscraper.scrapers.Option2;
52 | import com.stuffbox.webscraper.scrapers.Scraper;
53 | import com.stuffbox.webscraper.scrapers.XStreamScraper;
54 |
55 | import org.jsoup.Jsoup;
56 | import org.jsoup.nodes.Document;
57 |
58 | import java.util.ArrayList;
59 | import java.util.List;
60 | import java.util.Timer;
61 | import java.util.TimerTask;
62 |
63 |
64 | public class WatchVideo extends AppCompatActivity {
65 | PlayerView playerView;
66 | SimpleExoPlayer player;
67 | LinearLayout controls;
68 | ImageButton nextEpisodeButton, previousEpisodeButton, qualityChangerButton;
69 | ProgressBar progressBar;
70 | TextView title;
71 | String imageLink;
72 | boolean changedScraper = false;
73 | long time;
74 | AnimeDatabase animeDatabase;
75 | String nextVideoLink = null;
76 | String previousVideoLink = null;
77 | public static String url = "https://gogoanime.pe/";
78 | int currentScraper = 2;
79 | ArrayList scrapers = new ArrayList<>();
80 | boolean startedPlaying = false;
81 | Context context;
82 | ArrayList qualities;
83 | String vidStreamUrl;
84 | int currentQuality;
85 | String link;
86 | BroadcastReceiver receiver;
87 | String host;
88 | private static final String ACTION_MEDIA_CONTROL = "media_control";
89 | private static final String EXTRA_CONTROL_TYPE = "control_type";
90 | private String animeName;
91 | int episodeNumber;
92 | boolean changedAnime = false;
93 | String backStack = "";
94 | Anime currentAnime;
95 | String tempGogoAnimeLink ;
96 | Timer updateTimer;
97 | private PictureInPictureParams.Builder mPictureInPictureParamsBuilder;
98 | View.OnClickListener nextEpisodeOnClickListener = new View.OnClickListener() {
99 | @Override
100 | public void onClick(View view) {
101 | Log.i("igotcalled","igotcalled with episode number "+ episodeNumber);
102 | if (nextVideoLink == null || nextVideoLink.equals(""))
103 | Toast.makeText(getApplicationContext(), "Last Episode", Toast.LENGTH_SHORT).show();
104 | else {
105 | updateTimer.cancel();
106 | episodeNumber += 1;
107 | changedAnime = true;
108 | executeQuery(animeName, episodeNumber, nextVideoLink, imageLink);
109 | currentScraper = 3;
110 | player.setPlayWhenReady(false);
111 | changedEpisode = false;
112 | new ScrapeVideoLink(nextVideoLink, context).execute();
113 | }
114 | }
115 | };
116 | Player.EventListener eventListener = new Player.EventListener() {
117 | @Override
118 | public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
119 | if (playbackState == ExoPlayer.STATE_ENDED && playWhenReady ) {
120 | if (nextVideoLink == null || nextVideoLink.equals(""))
121 | Toast.makeText(getApplicationContext(), "Last Episode", Toast.LENGTH_SHORT).show();
122 | else {
123 | changedEpisode = true;
124 |
125 | updateTimer.cancel();
126 | episodeNumber += 1;
127 | changedAnime = true;
128 | executeQuery(animeName, episodeNumber, nextVideoLink, imageLink);
129 | currentScraper = 2;
130 | // player.setPlayWhenReady(false);
131 | changedEpisode = false;
132 | new ScrapeVideoLink(nextVideoLink, context).execute();
133 | }
134 | } else if (playbackState == ExoPlayer.STATE_BUFFERING) {
135 | progressBar.setVisibility(View.VISIBLE);
136 | } else {
137 | progressBar.setVisibility(View.INVISIBLE);
138 | }
139 | }
140 |
141 | @Override
142 | public void onPlayerError(ExoPlaybackException error) {
143 | Log.i("exoerror", error.getMessage());
144 | currentScraper--;
145 | if (currentScraper <0)
146 | useFallBack();
147 | else {
148 | link = tempGogoAnimeLink;
149 | changingScraper();
150 | }
151 | // useFallBack();
152 | }
153 | };
154 | View.OnClickListener previousEpisodeOnClickListener = new View.OnClickListener() {
155 | @Override
156 | public void onClick(View view) {
157 | if (previousVideoLink == null || previousVideoLink.equals(""))
158 | Toast.makeText(getApplicationContext(), "First Episode", Toast.LENGTH_SHORT).show();
159 | else {
160 | updateTimer.cancel();
161 | changedAnime = true;
162 | episodeNumber -= 1;
163 | currentScraper = 2;
164 | player.setPlayWhenReady(false);
165 | executeQuery(animeName, episodeNumber, previousVideoLink, imageLink);
166 |
167 | new ScrapeVideoLink(previousVideoLink, context).execute();
168 | }
169 | }
170 | };
171 |
172 | View.OnClickListener qualityChangerOnClickListener = new View.OnClickListener() {
173 |
174 | @Override
175 | public void onClick(View view) {
176 | ArrayList qualityInfo = new ArrayList<>();
177 | for (Quality quality : qualities)
178 | qualityInfo.add(quality.getQuality());
179 | AlertDialog.Builder builder = new AlertDialog.Builder(WatchVideo.this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
180 | builder.setTitle("Quality")
181 | .setItems(qualityInfo.toArray(new String[0]), new DialogInterface.OnClickListener() {
182 | public void onClick(DialogInterface dialog, int which) {
183 | if (currentQuality != which) {
184 | long t = player.getCurrentPosition();
185 | currentQuality = which;
186 |
187 | DefaultHttpDataSourceFactory dataSourceFactory = getSettedHeadersDataFactory();
188 | HlsMediaSource hlsMediaSource =
189 | new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(qualities.get(currentQuality).getQualityUrl()));
190 | player.prepare(hlsMediaSource);
191 | player.setPlayWhenReady(true);
192 | player.seekTo(t);
193 | }
194 | }
195 | });
196 |
197 | builder.show();
198 | }
199 | };
200 | private boolean changedEpisode = false;
201 |
202 | DefaultHttpDataSourceFactory getSettedHeadersDataFactory() {
203 |
204 |
205 | String userAgent = Util.getUserAgent(context, "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5");
206 | if (currentScraper == 0 || currentScraper >=2)
207 | return new DefaultHttpDataSourceFactory(userAgent);
208 | DefaultHttpDataSourceFactory dataSourceFactory = new DefaultHttpDataSourceFactory(userAgent);
209 |
210 | dataSourceFactory.getDefaultRequestProperties().set("Accept", "*/*");
211 | dataSourceFactory.getDefaultRequestProperties().set("Accept-Encoding", "gzip,deflate,br");
212 | dataSourceFactory.getDefaultRequestProperties().set("Accept-Language", "en-IN,en;q=0.9,ur-IN;q=0.8,ur;q=0.7,en-GB;q=0.6,en-US;q=0.5");
213 | dataSourceFactory.getDefaultRequestProperties().set("Connection", "keep-alive");
214 | dataSourceFactory.getDefaultRequestProperties().set("Origin", "https://vidstreaming.io");
215 | dataSourceFactory.getDefaultRequestProperties().set("Referer", "https://vidstreaming.io");
216 | dataSourceFactory.getDefaultRequestProperties().set("Sec-Fetch-Mode", "cors");
217 | dataSourceFactory.getDefaultRequestProperties().set("Sec-Fetch-Site", "cross-site");
218 | dataSourceFactory.getDefaultRequestProperties().set("User-Agent", userAgent);
219 | dataSourceFactory.getDefaultRequestProperties().set("Host", host);
220 | return dataSourceFactory;
221 | }
222 |
223 | @Override
224 | protected void onCreate(@Nullable Bundle savedInstanceState) {
225 | super.onCreate(savedInstanceState);
226 | setContentView(R.layout.videoviewer);
227 | setVideoOptions();
228 | initUIElements();
229 | context = this;
230 | player = ExoPlayerFactory.newSimpleInstance(this);
231 | playerView.setPlayer(player);
232 | animeDatabase = AnimeDatabase.getInstance(getApplicationContext());
233 | link = getIntent().getStringExtra("link");
234 |
235 | int lastIndexOfDash = link.lastIndexOf("-");
236 | episodeNumber = Integer.parseInt(link.substring(lastIndexOfDash + 1));
237 | animeName = getIntent().getStringExtra("animename");
238 | Log.i("linkis", link);
239 | imageLink = getIntent().getStringExtra("imagelink");
240 | // time = Long.parseLong(getIntent().getStringExtra("time"));
241 | currentAnime = animeDatabase.animeDao().getAnimeByNameAndEpisodeNo(animeName, String.valueOf(episodeNumber));
242 | Log.i("yotimertimer", "soja" + currentAnime.getTime());
243 | // Log.i("yotimerepisode",String.valueOf(episodeNumber));
244 |
245 | // currentAnime.setTime(String.valueOf(time));
246 |
247 | new ScrapeVideoLink(link, this).execute();
248 | if (android.os.Build.VERSION.SDK_INT >= 26)
249 | mPictureInPictureParamsBuilder = new PictureInPictureParams.Builder();
250 |
251 | }
252 |
253 | void initUIElements() {
254 | playerView = findViewById(R.id.exoplayer);
255 | controls = findViewById(R.id.wholecontroller);
256 | progressBar = findViewById(R.id.buffer);
257 | title = findViewById(R.id.titleofanime);
258 | qualityChangerButton = findViewById(R.id.qualitychanger);
259 | nextEpisodeButton = findViewById(R.id.exo_nextvideo);
260 | previousEpisodeButton = findViewById(R.id.exo_prevvideo);
261 | }
262 |
263 | void setVideoOptions() {
264 | View decorView = getWindow().getDecorView();
265 | int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
266 | | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
267 | decorView.setSystemUiVisibility(uiOptions);
268 | }
269 |
270 |
271 | private void hideSystemUI() {
272 | View decorView = getWindow().getDecorView();
273 | int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
274 | | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
275 | decorView.setSystemUiVisibility(uiOptions);
276 | }
277 |
278 | private void showSystemUI() {
279 | View decorView = getWindow().getDecorView();
280 | decorView.setSystemUiVisibility(
281 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
282 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
283 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
284 | }
285 |
286 | void executeQuery(String animeName, int episodeNumber, String link, String imageLink) {
287 | Anime temp = animeDatabase.animeDao().getAnimeByNameAndEpisodeNo(animeName, String.valueOf(episodeNumber));
288 | String time = "0";
289 | if (temp != null)
290 | time = temp.getTime();
291 |
292 | animeDatabase.animeDao().deleteAnimeByNameAndEpisodeNo(animeName, String.valueOf(episodeNumber));
293 | Anime anime = new Anime(animeName, link, String.valueOf(episodeNumber), imageLink, time);
294 | animeDatabase.animeDao().insertAnime(anime);
295 | currentAnime = anime;
296 |
297 |
298 | }
299 |
300 | class ScrapeVideoLink extends AsyncTask {
301 | String gogoAnimeUrl;
302 | Context context;
303 |
304 | ScrapeVideoLink(String gogoAnimeUrl, Context context) {
305 | this.gogoAnimeUrl = gogoAnimeUrl;
306 | this.context = context;
307 | }
308 |
309 | @Override
310 | protected void onPreExecute() {
311 | super.onPreExecute();
312 | tempGogoAnimeLink = gogoAnimeUrl;
313 | // player.setPlayWhenReady(false);
314 | title.setVisibility(View.GONE);
315 | progressBar.setVisibility(View.VISIBLE);
316 | scrapers.clear();
317 | qualities = new ArrayList<>();
318 |
319 | }
320 |
321 | @Override
322 | protected void onPostExecute(Void aVoid) {
323 | super.onPostExecute(aVoid);
324 | try {
325 |
326 | DefaultHttpDataSourceFactory dataSourceFactory = getSettedHeadersDataFactory();
327 | Log.i("currentScraper",""+currentScraper);
328 | Log.i("currentlyplaying","soja"+ qualities.get(currentQuality).getQualityUrl());
329 |
330 | if(currentScraper<2)
331 | {
332 | HlsMediaSource hlsMediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(qualities.get(currentQuality).getQualityUrl()));
333 | player.prepare(hlsMediaSource);
334 |
335 | }
336 | else
337 | {
338 |
339 | MediaSource m = mediaSource(Uri.parse(qualities.get(currentQuality).getQualityUrl()),context);
340 | player.prepare(m);
341 |
342 | }
343 | player.setPlayWhenReady(true);
344 | // if(changedAnime)
345 | // {
346 | // changedAnime = false;
347 | // player.seekTo(0);
348 | // }
349 | // else
350 | player.seekTo(Long.parseLong(currentAnime.getTime()));
351 | startedPlaying = true;
352 | updateTimer = new Timer();
353 | updateTimer.scheduleAtFixedRate(new TimerTask() {
354 | @Override
355 | public void run() {
356 | // Enter your code
357 |
358 |
359 | currentAnime.setTime(String.valueOf(player.getCurrentPosition()));
360 | Log.i("yotimer", currentAnime.getTime());
361 | animeDatabase.animeDao().updateAnime(currentAnime);
362 | }
363 | }, 0, 2000);
364 | } catch (Exception e) {
365 | // Log.i("exoerror", e.getMessage());
366 | //useFallBack();
367 | }
368 | try {
369 | player.removeListener(eventListener);
370 | }
371 | catch (Exception e)
372 | {
373 | e.printStackTrace();
374 | }
375 | player.addListener(eventListener);
376 | progressBar.setVisibility(View.GONE);
377 | title.setText(animeName + " Episode " + episodeNumber);
378 | nextEpisodeButton.setOnClickListener(nextEpisodeOnClickListener);
379 | previousEpisodeButton.setOnClickListener(previousEpisodeOnClickListener);
380 | qualityChangerButton.setOnClickListener(qualityChangerOnClickListener);
381 | title.setVisibility(View.VISIBLE);
382 | }
383 |
384 | @Override
385 | protected Void doInBackground(Void... voids) {
386 | Document gogoAnimePageDocument = null;
387 | Log.i("currentPlaying", gogoAnimeUrl);
388 | try {
389 | if (gogoAnimeUrl.equals("https://www1.gogoanimes.ai/ansatsu-kyoushitsu-tv--episode-1"))//edge case
390 | gogoAnimeUrl = url + "ansatsu-kyoushitsu-tv--episode-1";
391 |
392 |
393 | gogoAnimePageDocument = Jsoup.connect(gogoAnimeUrl).get();
394 | vidStreamUrl = "https:" + gogoAnimePageDocument.getElementsByClass("play-video").get(0).getElementsByTag("iframe").get(0).attr("src");
395 | previousVideoLink = gogoAnimePageDocument.select("div[class=anime_video_body_episodes_l]").select("a").attr("abs:href");
396 | nextVideoLink = gogoAnimePageDocument.select("div[class=anime_video_body_episodes_r]").select("a").attr("abs:href");
397 | Option1 option1 = new Option1(gogoAnimePageDocument);
398 | Option2 option2 = new Option2(gogoAnimePageDocument);
399 | scrapers.add(option1);
400 | scrapers.add(option2);
401 | scrapers.add(new NewScraper(gogoAnimePageDocument));
402 | scrapers.add(new XStreamScraper(gogoAnimePageDocument));
403 |
404 | qualities = scrapers.get(currentScraper).getQualityUrls();
405 | if (qualities.size() == 0) {
406 | currentScraper--;
407 | if (currentScraper<0) {
408 | useFallBack();
409 | } else {
410 | link = gogoAnimeUrl;
411 | changingScraper();
412 | }
413 | }
414 | host = scrapers.get(currentScraper).getHost();
415 | if(currentScraper==0)
416 | currentQuality = 0;
417 | else
418 | currentQuality = qualities.size()-1;
419 |
420 |
421 | } catch (Exception e) {
422 | Log.i("gogoanimeerror", e.toString());
423 | }
424 | return null;
425 | }
426 | }
427 |
428 |
429 | @Override
430 | public void onUserLeaveHint() {
431 | if (android.os.Build.VERSION.SDK_INT >= 26 && player.getPlayWhenReady())
432 | try {
433 | backStack = "lost";
434 | int x = playerView.getPlayer().getPlayWhenReady() ? R.drawable.pip_pause : R.drawable.pip_play;
435 | updatePictureInPictureActions(x, "soja", 0, 0, null);
436 | enterPictureInPictureMode(mPictureInPictureParamsBuilder.build());
437 |
438 | } catch (Exception e) {
439 | e.printStackTrace();
440 | }
441 |
442 |
443 | }
444 |
445 | @Override
446 | public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
447 | if (isInPictureInPictureMode) {
448 | controls.setVisibility(View.GONE);
449 | title.setVisibility(View.GONE);
450 | receiver = new BroadcastReceiver() {
451 | @Override
452 | public void onReceive(Context context, Intent intent) {
453 |
454 | if (intent == null)
455 | return;
456 | Log.i("sojaasd", "marja");
457 |
458 | if (player.getPlayWhenReady()) {
459 | player.setPlayWhenReady(false);
460 | updatePictureInPictureActions(R.drawable.pip_play, "play", 0, 0, intent);
461 | } else {
462 | player.setPlayWhenReady(true);
463 | updatePictureInPictureActions(R.drawable.pip_pause, "pause", 0, 0, intent);
464 | }
465 |
466 |
467 | }
468 | };
469 | registerReceiver(receiver, new IntentFilter(ACTION_MEDIA_CONTROL));
470 |
471 | } else {
472 |
473 | title.setVisibility(View.VISIBLE);
474 | controls.setVisibility(View.VISIBLE);
475 | unregisterReceiver(receiver);
476 | receiver = null;
477 | }
478 | }
479 |
480 | void updatePictureInPictureActions(@DrawableRes int iconId, String title, int controlType, int requestCode, Intent newintent) {
481 | final ArrayList actions = new ArrayList<>();
482 | if (newintent == null)
483 | newintent = new Intent(ACTION_MEDIA_CONTROL).putExtra(EXTRA_CONTROL_TYPE, controlType);
484 | final PendingIntent intent =
485 | PendingIntent.getBroadcast(
486 | WatchVideo.this,
487 | requestCode,
488 | newintent,
489 | 0);
490 | final Icon icon = Icon.createWithResource(
491 | WatchVideo.this, iconId);
492 | RemoteAction action = new RemoteAction(icon, title, title, intent);
493 | actions.add(action);
494 | mPictureInPictureParamsBuilder.setActions(actions);
495 | setPictureInPictureParams(mPictureInPictureParamsBuilder.build());
496 | }
497 |
498 | @Override
499 | public void onWindowFocusChanged(boolean hasFocus) {
500 | super.onWindowFocusChanged(hasFocus);
501 | if (hasFocus) {
502 | hideSystemUI();
503 |
504 | }
505 |
506 | }
507 |
508 | // LifeCycleEvents
509 | @Override
510 | public void onSaveInstanceState(@NonNull Bundle outState) {
511 | outState.putString("videolink", qualities.get(currentQuality).getQualityUrl());
512 |
513 | super.onSaveInstanceState(outState);
514 | }
515 |
516 | @Override
517 | public void onPause() {
518 | super.onPause();
519 |
520 | time = player.getCurrentPosition();
521 | }
522 |
523 | @Override
524 | public void onStop() {
525 | super.onStop();
526 | time = player.getCurrentPosition();
527 | player.setPlayWhenReady(false);
528 |
529 | }
530 |
531 | @Override
532 | public void onResume() {
533 | super.onResume();
534 |
535 |
536 | playerView.getPlayer().setPlayWhenReady(true);
537 |
538 |
539 | }
540 |
541 | @Override
542 | public boolean onKeyDown(int keyCode, KeyEvent event) {
543 |
544 |
545 | if (keyCode == KeyEvent.KEYCODE_BACK) {
546 | playerView.getPlayer().release();
547 | if (backStack.equals("lost")) {
548 |
549 | ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
550 | if (am != null) {
551 | List tasks = am.getAppTasks();
552 | if (tasks != null && tasks.size() > 1) {
553 |
554 | tasks.get(0).setExcludeFromRecents(true);
555 | tasks.get(1).moveToFront();
556 | }
557 | }
558 |
559 |
560 | }
561 | try {
562 | updateTimer.cancel();
563 | } catch (Exception e) {
564 | e.printStackTrace();
565 | }
566 | super.onBackPressed();
567 | }
568 | return false;
569 | }
570 |
571 | void useFallBack() {
572 | player.release();
573 | Intent intent = new Intent(context, webvideo.class);
574 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
575 | intent.putExtra("videostreamlink", vidStreamUrl);
576 | try {
577 | updateTimer.cancel();
578 | } catch (Exception e) {
579 | e.printStackTrace();
580 | }
581 |
582 | startActivity(intent);
583 |
584 | finish();
585 | }
586 |
587 | void changingScraper() {
588 | new ScrapeVideoLink(link, context).execute();
589 | changedScraper = true;
590 | if (startedPlaying)
591 | time = player.getCurrentPosition();
592 | }
593 | private MediaSource mediaSource(Uri uri, Context context) {
594 | return new ExtractorMediaSource.Factory(
595 | new DefaultHttpDataSourceFactory("exoplayer")).
596 | createMediaSource(uri);
597 | }
598 |
599 | }
--------------------------------------------------------------------------------