mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-09-22 21:40:52 +02:00
Compare commits
106 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d0d41c6b16 | ||
![]() |
f7a531e71b | ||
![]() |
c28fddc4dd | ||
![]() |
b6ea10fc73 | ||
![]() |
320eb44061 | ||
![]() |
7a6b5dd5b7 | ||
![]() |
460653ed16 | ||
![]() |
b6fda788c5 | ||
![]() |
da4b9306fa | ||
![]() |
d76c02cbf4 | ||
![]() |
4d5466b5cd | ||
![]() |
e9c20ac8b0 | ||
![]() |
961820a250 | ||
![]() |
4cc2976061 | ||
![]() |
477f182b43 | ||
![]() |
a5252bb765 | ||
![]() |
3f0078f38a | ||
![]() |
91434dd2ac | ||
![]() |
f29bd0a6e7 | ||
![]() |
7186f58374 | ||
![]() |
5c8bcf15ba | ||
![]() |
130757ee99 | ||
![]() |
5020a4f9dc | ||
![]() |
ef15902ec4 | ||
![]() |
ed8d13f837 | ||
![]() |
27f2c65e6d | ||
![]() |
0b3428ede9 | ||
![]() |
3e0102ad2a | ||
![]() |
c42002ccc5 | ||
![]() |
e8101d5d91 | ||
![]() |
ecdf4ad502 | ||
![]() |
af760f9cdc | ||
![]() |
b3491da49f | ||
![]() |
c322feeaff | ||
![]() |
b26f46a063 | ||
![]() |
9f0944dc5a | ||
![]() |
e869098434 | ||
![]() |
4baa23af5f | ||
![]() |
78fc5bbbd5 | ||
![]() |
a69784d168 | ||
![]() |
d48a7f1a18 | ||
![]() |
082c6128ad | ||
![]() |
7c9771873b | ||
![]() |
7257cdacc8 | ||
![]() |
140b480f82 | ||
![]() |
77db2f8a48 | ||
![]() |
22bc81b0eb | ||
![]() |
b52b3d4be0 | ||
![]() |
f845098b42 | ||
![]() |
0f7397e3b8 | ||
![]() |
0b9d99fdc9 | ||
![]() |
9a1da5cc75 | ||
![]() |
9e76f94cf6 | ||
![]() |
7d6b92e064 | ||
![]() |
849a45a3ca | ||
![]() |
7ddea5a71b | ||
![]() |
5d81358c15 | ||
![]() |
492aad9d70 | ||
![]() |
647cfcd401 | ||
![]() |
c60d98e52d | ||
![]() |
d3cfac6b15 | ||
![]() |
7fb4e5a143 | ||
![]() |
8e451b2a83 | ||
![]() |
8083f06fe7 | ||
![]() |
44521a2e56 | ||
![]() |
dfeed3d0eb | ||
![]() |
081a45b70d | ||
![]() |
616a721bba | ||
![]() |
c9aa553b32 | ||
![]() |
e3d59c3cff | ||
![]() |
df51635674 | ||
![]() |
1e81f61760 | ||
![]() |
a4043eab83 | ||
![]() |
60dc19d2bc | ||
![]() |
a2e4585fe8 | ||
![]() |
b5df281447 | ||
![]() |
650917f9f9 | ||
![]() |
3a9c95a9ae | ||
![]() |
5458acfcad | ||
![]() |
68e80e6054 | ||
![]() |
e4aa69b8d3 | ||
![]() |
dfd40e43da | ||
![]() |
7efd111d9c | ||
![]() |
6809172203 | ||
![]() |
40a4343f06 | ||
![]() |
cd9333b39e | ||
![]() |
82d426c781 | ||
![]() |
c7e773de25 | ||
![]() |
2ded33110f | ||
![]() |
b26c0aa9da | ||
![]() |
2fc8fb6f17 | ||
![]() |
ea76f1d6e2 | ||
![]() |
7cda1d116b | ||
![]() |
8bf7a1a9db | ||
![]() |
0aa0ad65c0 | ||
![]() |
53ff58daa3 | ||
![]() |
b3225bebe6 | ||
![]() |
4beafad71f | ||
![]() |
c96f933626 | ||
![]() |
bea6359d5f | ||
![]() |
1b9a6e53ce | ||
![]() |
c7abf377eb | ||
![]() |
175d8ce572 | ||
![]() |
1708a401cf | ||
![]() |
141278e668 | ||
![]() |
754bd82699 |
5
.github/CONTRIBUTING.md
vendored
5
.github/CONTRIBUTING.md
vendored
@@ -13,6 +13,9 @@ Do not report crashes in the GitHub issue tracker. NewPipe has an automated cras
|
|||||||
* Check if this issue/feature is already fixed/implemented in the repository
|
* Check if this issue/feature is already fixed/implemented in the repository
|
||||||
* If you are an android/java developer you are always welcome to fix/implement an issue/a feature yourself
|
* If you are an android/java developer you are always welcome to fix/implement an issue/a feature yourself
|
||||||
|
|
||||||
|
## Bugfixing
|
||||||
|
* If you want to help NewPipe getting bug free, you can send me a mail to tnp@newpipe.schabi.org to let me know that you intent to help, and than register at our [sentry](https://support.schabi.org) setup.
|
||||||
|
|
||||||
## Translation
|
## Translation
|
||||||
|
|
||||||
* NewPipe can be translated on [weblate](https://hosted.weblate.org/projects/newpipe/strings/)
|
* NewPipe can be translated on [weblate](https://hosted.weblate.org/projects/newpipe/strings/)
|
||||||
@@ -31,6 +34,6 @@ Do not report crashes in the GitHub issue tracker. NewPipe has an automated cras
|
|||||||
|
|
||||||
## Communication
|
## Communication
|
||||||
|
|
||||||
* I hereby declare our Slack channel as dead!!! There are no plans on building a new chat, but if there is interest on creating one and keeping it alive, I'd be pleased to create one again.
|
* WE DO NOW HAVE A MAILING LIST: [newpipe@list.schabi.org](https://list.schabi.org/cgi-bin/mailman/listinfo/newpipe).
|
||||||
* If you want to get in contact with me or one of our other contributors you can send me an email at tnp(at)schabi.org
|
* If you want to get in contact with me or one of our other contributors you can send me an email at tnp(at)schabi.org
|
||||||
* Feel free to post suggestions, changes, ideas etc!
|
* Feel free to post suggestions, changes, ideas etc!
|
||||||
|
@@ -37,12 +37,12 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
|
|||||||
* Listen to YouTube videos (experimental)
|
* Listen to YouTube videos (experimental)
|
||||||
* Select the streaming player to watch the video with
|
* Select the streaming player to watch the video with
|
||||||
* Download videos
|
* Download videos
|
||||||
* Download audio only
|
* Download audio only * Open a video in Kodi
|
||||||
* Open a video in Kodi
|
|
||||||
* Show Next/Related videos
|
* Show Next/Related videos
|
||||||
* Search YouTube in a specific language
|
* Search YouTube in a specific language
|
||||||
* Watch age restricted material
|
* Watch age restricted material
|
||||||
* Display general information about channels
|
* Display general information about channels
|
||||||
|
* Search channels
|
||||||
|
|
||||||
### Coming Features
|
### Coming Features
|
||||||
|
|
||||||
@@ -50,7 +50,6 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
|
|||||||
* Bookmarks
|
* Bookmarks
|
||||||
* View history
|
* View history
|
||||||
* Search history
|
* Search history
|
||||||
* Search channels
|
|
||||||
* Subscribe to channels
|
* Subscribe to channels
|
||||||
* Watch videos from a channel
|
* Watch videos from a channel
|
||||||
* Search/Watch Playlists
|
* Search/Watch Playlists
|
||||||
|
@@ -8,8 +8,8 @@ android {
|
|||||||
applicationId "org.schabi.newpipe"
|
applicationId "org.schabi.newpipe"
|
||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 21
|
versionCode 24
|
||||||
versionName "0.8.7"
|
versionName "0.8.10"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
@@ -32,10 +32,10 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
compile 'com.android.support:appcompat-v7:25.1.0'
|
compile 'com.android.support:appcompat-v7:25.1.1'
|
||||||
compile 'com.android.support:support-v4:25.1.0'
|
compile 'com.android.support:support-v4:25.1.1'
|
||||||
compile 'com.android.support:design:25.1.0'
|
compile 'com.android.support:design:25.1.1'
|
||||||
compile 'com.android.support:recyclerview-v7:25.1.0'
|
compile 'com.android.support:recyclerview-v7:25.1.1'
|
||||||
compile 'org.jsoup:jsoup:1.8.3'
|
compile 'org.jsoup:jsoup:1.8.3'
|
||||||
compile 'org.mozilla:rhino:1.7.7'
|
compile 'org.mozilla:rhino:1.7.7'
|
||||||
compile 'info.guardianproject.netcipher:netcipher:1.2'
|
compile 'info.guardianproject.netcipher:netcipher:1.2'
|
||||||
@@ -45,6 +45,8 @@ dependencies {
|
|||||||
compile 'com.google.android.exoplayer:exoplayer:r1.5.5'
|
compile 'com.google.android.exoplayer:exoplayer:r1.5.5'
|
||||||
compile 'com.google.code.gson:gson:2.4'
|
compile 'com.google.code.gson:gson:2.4'
|
||||||
compile 'com.nononsenseapps:filepicker:3.0.0'
|
compile 'com.nononsenseapps:filepicker:3.0.0'
|
||||||
testCompile 'junit:junit:4.12'
|
|
||||||
compile 'ch.acra:acra:4.9.0'
|
compile 'ch.acra:acra:4.9.0'
|
||||||
|
testCompile 'junit:junit:4.12'
|
||||||
|
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||||
|
testCompile 'org.json:json:20160810'
|
||||||
}
|
}
|
||||||
|
@@ -1,52 +0,0 @@
|
|||||||
package org.schabi.newpipe.extractor.youtube;
|
|
||||||
|
|
||||||
import android.test.AndroidTestCase;
|
|
||||||
|
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
|
||||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamExtractor;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Christian Schabesberger on 11.03.16.
|
|
||||||
*
|
|
||||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
|
||||||
* YoutubeStreamExtractorLiveStreamTest.java is part of NewPipe.
|
|
||||||
*
|
|
||||||
* NewPipe is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* NewPipe is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public class YoutubeStreamExtractorLiveStreamTest extends AndroidTestCase {
|
|
||||||
|
|
||||||
private StreamExtractor extractor;
|
|
||||||
|
|
||||||
public void setUp() throws IOException, ExtractionException {
|
|
||||||
//todo: make the extractor not throw over a livestream
|
|
||||||
/*
|
|
||||||
|
|
||||||
NewPipe.init(Downloader.getInstance());
|
|
||||||
extractor = NewPipe.getService("Youtube")
|
|
||||||
.getExtractorInstance("https://www.youtube.com/watch?v=J0s6NjqdjLE", Downloader.getInstance());
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testStreamType() throws ParsingException {
|
|
||||||
assertTrue(true);
|
|
||||||
// assertTrue(extractor.getStreamType() == AbstractVideoInfo.StreamType.LIVE_STREAM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@@ -156,11 +156,22 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".ChannelActivity"
|
android:name=".ChannelActivity"
|
||||||
android:label="@string/title_activity_channel"
|
android:label="@string/title_activity_channel"
|
||||||
|
android:launchMode="singleTask"
|
||||||
android:theme="@style/AppTheme.NoActionBar" />
|
android:theme="@style/AppTheme.NoActionBar" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ReCaptchaActivity"
|
android:name=".ReCaptchaActivity"
|
||||||
android:label="@string/reCaptchaActivity" />
|
android:label="@string/reCaptchaActivity" />
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="android.support.v4.content.FileProvider"
|
||||||
|
android:authorities="${applicationId}.provider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/provider_paths"/>
|
||||||
|
</provider>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
@@ -48,6 +48,7 @@ public class App extends Application {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
// init crashreport
|
// init crashreport
|
||||||
try {
|
try {
|
||||||
final ACRAConfiguration acraConfig = new ConfigurationBuilder(this)
|
final ACRAConfiguration acraConfig = new ConfigurationBuilder(this)
|
||||||
|
@@ -1,17 +1,24 @@
|
|||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
import android.support.design.widget.CollapsingToolbarLayout;
|
import android.support.design.widget.CollapsingToolbarLayout;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
import android.support.design.widget.FloatingActionButton;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@@ -29,8 +36,13 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
|||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
import org.schabi.newpipe.util.NavStack;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static android.os.Build.VERSION.SDK;
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||||
@@ -51,15 +63,9 @@ import java.io.IOException;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class ChannelActivity extends AppCompatActivity {
|
public class ChannelActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
|
||||||
private static final String TAG = ChannelActivity.class.toString();
|
private static final String TAG = ChannelActivity.class.toString();
|
||||||
private View rootView = null;
|
private View rootView = null;
|
||||||
|
|
||||||
// intent const
|
|
||||||
public static final String CHANNEL_URL = "channel_url";
|
|
||||||
public static final String SERVICE_ID = "service_id";
|
|
||||||
|
|
||||||
private int serviceId = -1;
|
private int serviceId = -1;
|
||||||
private String channelUrl = "";
|
private String channelUrl = "";
|
||||||
private int pageNumber = 0;
|
private int pageNumber = 0;
|
||||||
@@ -72,27 +78,42 @@ public class ChannelActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
//since we set themeing we have to set translucent statusBar by hand
|
||||||
|
if (PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
.getString("theme", getResources().getString(R.string.light_theme_title)).
|
||||||
|
equals(getResources().getString(R.string.dark_theme_title))) {
|
||||||
|
setTheme(R.style.DarkTheme_NoActionBar);
|
||||||
|
}
|
||||||
|
setTranslucentStatusBar(getWindow());
|
||||||
|
|
||||||
setContentView(R.layout.activity_channel);
|
setContentView(R.layout.activity_channel);
|
||||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
rootView = findViewById(R.id.rootView);
|
rootView = findViewById(R.id.rootView);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
Intent i = getIntent();
|
if(savedInstanceState == null) {
|
||||||
channelUrl = i.getStringExtra(CHANNEL_URL);
|
Intent i = getIntent();
|
||||||
serviceId = i.getIntExtra(SERVICE_ID, -1);
|
channelUrl = i.getStringExtra(NavStack.URL);
|
||||||
|
serviceId = i.getIntExtra(NavStack.SERVICE_ID, -1);
|
||||||
|
} else {
|
||||||
|
channelUrl = savedInstanceState.getString(NavStack.URL);
|
||||||
|
serviceId = savedInstanceState.getInt(NavStack.SERVICE_ID);
|
||||||
|
NavStack.getInstance()
|
||||||
|
.restoreSavedInstanceState(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
infoListAdapter = new InfoListAdapter(this, rootView);
|
infoListAdapter = new InfoListAdapter(this, rootView);
|
||||||
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.channel_streams_view);
|
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.channel_streams_view);
|
||||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
||||||
recyclerView.setLayoutManager(layoutManager);
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
recyclerView.setAdapter(infoListAdapter);
|
recyclerView.setAdapter(infoListAdapter);
|
||||||
infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
infoListAdapter.setOnStreamInfoItemSelectedListener(
|
||||||
|
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void selected(String url) {
|
public void selected(String url, int serviceId) {
|
||||||
Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class);
|
NavStack.getInstance()
|
||||||
detailIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, url);
|
.openDetailActivity(ChannelActivity.this, url, serviceId);
|
||||||
detailIntent.putExtra(
|
|
||||||
VideoItemDetailFragment.STREAMING_SERVICE, serviceId);
|
|
||||||
startActivity(detailIntent);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -122,13 +143,20 @@ public class ChannelActivity extends AppCompatActivity {
|
|||||||
requestData(false);
|
requestData(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
outState.putString(NavStack.URL, channelUrl);
|
||||||
|
outState.putInt(NavStack.SERVICE_ID, serviceId);
|
||||||
|
NavStack.getInstance()
|
||||||
|
.onSaveInstanceState(outState);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateUi(final ChannelInfo info) {
|
private void updateUi(final ChannelInfo info) {
|
||||||
CollapsingToolbarLayout ctl = (CollapsingToolbarLayout) findViewById(R.id.channel_toolbar_layout);
|
CollapsingToolbarLayout ctl = (CollapsingToolbarLayout) findViewById(R.id.channel_toolbar_layout);
|
||||||
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
|
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
|
||||||
ImageView channelBanner = (ImageView) findViewById(R.id.channel_banner_image);
|
ImageView channelBanner = (ImageView) findViewById(R.id.channel_banner_image);
|
||||||
FloatingActionButton feedButton = (FloatingActionButton) findViewById(R.id.channel_rss_fab);
|
final FloatingActionButton feedButton = (FloatingActionButton) findViewById(R.id.channel_rss_fab);
|
||||||
ImageView avatarView = (ImageView) findViewById(R.id.channel_avatar_view);
|
ImageView avatarView = (ImageView) findViewById(R.id.channel_avatar_view);
|
||||||
ImageView haloView = (ImageView) findViewById(R.id.channel_avatar_halo);
|
ImageView haloView = (ImageView) findViewById(R.id.channel_avatar_halo);
|
||||||
|
|
||||||
@@ -165,7 +193,7 @@ public class ChannelActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addVideos(final ChannelInfo info) {
|
private void addVideos(final ChannelInfo info) {
|
||||||
infoListAdapter.addStreamItemList(info.related_streams);
|
infoListAdapter.addInfoItemList(info.related_streams);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postNewErrorToast(Handler h, final int stringResource) {
|
private void postNewErrorToast(Handler h, final int stringResource) {
|
||||||
@@ -237,9 +265,13 @@ public class ChannelActivity extends AppCompatActivity {
|
|||||||
});
|
});
|
||||||
pe.printStackTrace();
|
pe.printStackTrace();
|
||||||
} catch(ExtractionException ex) {
|
} catch(ExtractionException ex) {
|
||||||
|
String name = "none";
|
||||||
|
if(service != null) {
|
||||||
|
name = service.getServiceInfo().name;
|
||||||
|
}
|
||||||
ErrorActivity.reportError(h, ChannelActivity.this, ex, VideoItemDetailFragment.class, null,
|
ErrorActivity.reportError(h, ChannelActivity.this, ex, VideoItemDetailFragment.class, null,
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_CHANNEL,
|
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_CHANNEL,
|
||||||
service.getServiceInfo().name, channelUrl, R.string.parsing_error));
|
name, channelUrl, R.string.parsing_error));
|
||||||
h.post(new Runnable() {
|
h.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -265,4 +297,38 @@ public class ChannelActivity extends AppCompatActivity {
|
|||||||
channelExtractorThread.start();
|
channelExtractorThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// fix transparent statusbar fuckup (fuck google why can't they just leave something that worked
|
||||||
|
// as it is, and everyone gets happy)
|
||||||
|
public static void setTranslucentStatusBar(Window window) {
|
||||||
|
if (window == null) return;
|
||||||
|
int sdkInt = Build.VERSION.SDK_INT;
|
||||||
|
if (sdkInt >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
setTranslucentStatusBarLollipop(window);
|
||||||
|
} else if (sdkInt >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
setTranslucentStatusBarKiKat(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
private static void setTranslucentStatusBarLollipop(Window window) {
|
||||||
|
window.setStatusBarColor(
|
||||||
|
ContextCompat.getColor(window.getContext(), android.R.color.transparent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||||
|
private static void setTranslucentStatusBarKiKat(Window window) {
|
||||||
|
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
try {
|
||||||
|
NavStack.getInstance()
|
||||||
|
.navBack(this);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ErrorActivity.reportUiError(this, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,13 +4,17 @@ import android.content.Intent;
|
|||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.NavUtils;
|
import android.support.v4.app.NavUtils;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.download.DownloadActivity;
|
||||||
import org.schabi.newpipe.settings.SettingsActivity;
|
import org.schabi.newpipe.settings.SettingsActivity;
|
||||||
|
import org.schabi.newpipe.util.PermissionHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 02.08.16.
|
* Created by Christian Schabesberger on 02.08.16.
|
||||||
@@ -32,15 +36,14 @@ import org.schabi.newpipe.settings.SettingsActivity;
|
|||||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends ThemableActivity {
|
||||||
|
|
||||||
private Fragment mainFragment = null;
|
private Fragment mainFragment = null;
|
||||||
|
private static final String TAG = MainActivity.class.toString();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||||
mainFragment = getSupportFragmentManager()
|
mainFragment = getSupportFragmentManager()
|
||||||
.findFragmentById(R.id.search_fragment);
|
.findFragmentById(R.id.search_fragment);
|
||||||
@@ -52,8 +55,6 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
MenuInflater inflater = getMenuInflater();
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
|
||||||
inflater.inflate(R.menu.main_menu, menu);
|
inflater.inflate(R.menu.main_menu, menu);
|
||||||
|
|
||||||
mainFragment.onCreateOptionsMenu(menu, inflater);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
|
|
||||||
switch(id) {
|
switch (id) {
|
||||||
case android.R.id.home: {
|
case android.R.id.home: {
|
||||||
Intent intent = new Intent(this, MainActivity.class);
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
@@ -74,13 +75,20 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case R.id.action_show_downloads: {
|
case R.id.action_show_downloads: {
|
||||||
Intent intent = new Intent(this, org.schabi.newpipe.download.DownloadActivity.class);
|
if (!PermissionHelper.checkStoragePermissions(this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Intent intent = new Intent(this, DownloadActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return mainFragment.onOptionsItemSelected(item) ||
|
return super.onOptionsItemSelected(item);
|
||||||
super.onOptionsItemSelected(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
//ignore back
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
28
app/src/main/java/org/schabi/newpipe/ThemableActivity.java
Normal file
28
app/src/main/java/org/schabi/newpipe/ThemableActivity.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
|
||||||
|
public class ThemableActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
.getString("theme", getResources().getString(R.string.light_theme_title)).
|
||||||
|
equals(getResources().getString(R.string.dark_theme_title))) {
|
||||||
|
setTheme(R.style.DarkTheme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
if (PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
.getString("theme", getResources().getString(R.string.light_theme_title)).
|
||||||
|
equals(getResources().getString(R.string.dark_theme_title))) {
|
||||||
|
setTheme(R.style.DarkTheme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -125,10 +125,13 @@ public class StreamInfoWorker {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (YoutubeStreamExtractor.DecryptException de) {
|
} catch (YoutubeStreamExtractor.DecryptException de) {
|
||||||
// custom service related exceptions
|
// custom service related exceptions
|
||||||
|
ErrorActivity.reportError(h, a, de, VideoItemDetailFragment.class, null,
|
||||||
|
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
|
||||||
|
service.getServiceInfo().name, videoUrl, R.string.youtube_signature_decryption_error));
|
||||||
h.post(new Runnable() {
|
h.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
onStreamInfoReceivedListener.onError(R.string.youtube_signature_decryption_error);
|
a.finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
de.printStackTrace();
|
de.printStackTrace();
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
package org.schabi.newpipe.detail;
|
package org.schabi.newpipe.detail;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.v4.app.NavUtils;
|
import android.support.v4.app.NavUtils;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@@ -14,12 +14,17 @@ import android.widget.Toast;
|
|||||||
import org.schabi.newpipe.App;
|
import org.schabi.newpipe.App;
|
||||||
import org.schabi.newpipe.MainActivity;
|
import org.schabi.newpipe.MainActivity;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.ThemableActivity;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
import org.schabi.newpipe.util.NavStack;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||||
@@ -39,7 +44,7 @@ import java.util.HashSet;
|
|||||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class VideoItemDetailActivity extends AppCompatActivity {
|
public class VideoItemDetailActivity extends ThemableActivity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes invisible separators (\p{Z}) and punctuation characters including
|
* Removes invisible separators (\p{Z}) and punctuation characters including
|
||||||
@@ -81,8 +86,10 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
|||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
handleIntent(getIntent());
|
handleIntent(getIntent());
|
||||||
} else {
|
} else {
|
||||||
videoUrl = savedInstanceState.getString(VideoItemDetailFragment.VIDEO_URL);
|
videoUrl = savedInstanceState.getString(NavStack.URL);
|
||||||
currentStreamingService = savedInstanceState.getInt(VideoItemDetailFragment.STREAMING_SERVICE);
|
currentStreamingService = savedInstanceState.getInt(NavStack.SERVICE_ID);
|
||||||
|
NavStack.getInstance()
|
||||||
|
.restoreSavedInstanceState(savedInstanceState);
|
||||||
addFragment(savedInstanceState);
|
addFragment(savedInstanceState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,12 +121,12 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
|||||||
currentStreamingService = getServiceIdByUrl(videoUrl);
|
currentStreamingService = getServiceIdByUrl(videoUrl);
|
||||||
} else {
|
} else {
|
||||||
//this is if the video was called through another NewPipe activity
|
//this is if the video was called through another NewPipe activity
|
||||||
videoUrl = intent.getStringExtra(VideoItemDetailFragment.VIDEO_URL);
|
videoUrl = intent.getStringExtra(NavStack.URL);
|
||||||
currentStreamingService = intent.getIntExtra(VideoItemDetailFragment.STREAMING_SERVICE, -1);
|
currentStreamingService = intent.getIntExtra(NavStack.SERVICE_ID, -1);
|
||||||
}
|
}
|
||||||
arguments.putBoolean(VideoItemDetailFragment.AUTO_PLAY, autoplay);
|
arguments.putBoolean(VideoItemDetailFragment.AUTO_PLAY, autoplay);
|
||||||
arguments.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
|
arguments.putString(NavStack.URL, videoUrl);
|
||||||
arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingService);
|
arguments.putInt(NavStack.SERVICE_ID, currentStreamingService);
|
||||||
addFragment(arguments);
|
addFragment(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,13 +148,17 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
outState.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
|
super.onSaveInstanceState(outState);
|
||||||
outState.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingService);
|
outState.putString(NavStack.URL, videoUrl);
|
||||||
|
outState.putInt(NavStack.SERVICE_ID, currentStreamingService);
|
||||||
outState.putBoolean(VideoItemDetailFragment.AUTO_PLAY, false);
|
outState.putBoolean(VideoItemDetailFragment.AUTO_PLAY, false);
|
||||||
|
NavStack.getInstance()
|
||||||
|
.onSaveInstanceState(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
super.onOptionsItemSelected(item);
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
if (id == android.R.id.home) {
|
if (id == android.R.id.home) {
|
||||||
// This ID represents the Home or Up button. In the case of this
|
// This ID represents the Home or Up button. In the case of this
|
||||||
@@ -157,24 +168,24 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
|
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
|
||||||
|
|
||||||
Intent intent = new Intent(this, MainActivity.class);
|
NavStack.getInstance()
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
.openMainActivity(this);
|
||||||
NavUtils.navigateUpTo(this, intent);
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return fragment.onOptionsItemSelected(item) ||
|
return super.onOptionsItemSelected(item);
|
||||||
super.onOptionsItemSelected(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public void onBackPressed() {
|
||||||
super.onCreateOptionsMenu(menu);
|
try {
|
||||||
fragment.onCreateOptionsMenu(menu, getMenuInflater());
|
NavStack.getInstance()
|
||||||
return true;
|
.navBack(this);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ErrorActivity.reportUiError(this, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all Strings which look remotely like URLs from a text.
|
* Retrieves all Strings which look remotely like URLs from a text.
|
||||||
* Used if NewPipe was called through share menu.
|
* Used if NewPipe was called through share menu.
|
||||||
@@ -231,7 +242,7 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
|||||||
StreamingService[] serviceList = NewPipe.getServices();
|
StreamingService[] serviceList = NewPipe.getServices();
|
||||||
int service = -1;
|
int service = -1;
|
||||||
for (int i = 0; i < serviceList.length; i++) {
|
for (int i = 0; i < serviceList.length; i++) {
|
||||||
if (serviceList[i].getUrlIdHandlerInstance().acceptUrl(videoUrl)) {
|
if (serviceList[i].getStreamUrlIdHandlerInstance().acceptUrl(videoUrl)) {
|
||||||
service = i;
|
service = i;
|
||||||
//videoExtractor = ServiceList.getService(i).getExtractorInstance();
|
//videoExtractor = ServiceList.getService(i).getExtractorInstance();
|
||||||
break;
|
break;
|
||||||
|
@@ -21,6 +21,7 @@ import android.util.Log;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -30,7 +31,6 @@ import android.widget.LinearLayout;
|
|||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.android.exoplayer.util.Util;
|
import com.google.android.exoplayer.util.Util;
|
||||||
@@ -39,26 +39,27 @@ import com.nostra13.universalimageloader.core.ImageLoader;
|
|||||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||||
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.ActivityCommunicator;
|
import org.schabi.newpipe.ActivityCommunicator;
|
||||||
import org.schabi.newpipe.ChannelActivity;
|
|
||||||
import org.schabi.newpipe.ReCaptchaActivity;
|
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
|
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamPreviewInfo;
|
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
|
||||||
import org.schabi.newpipe.ImageErrorLoadingListener;
|
import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||||
import org.schabi.newpipe.Localization;
|
import org.schabi.newpipe.Localization;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.ReCaptchaActivity;
|
||||||
import org.schabi.newpipe.download.DownloadDialog;
|
import org.schabi.newpipe.download.DownloadDialog;
|
||||||
import org.schabi.newpipe.extractor.stream_info.AudioStream;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.MediaFormat;
|
import org.schabi.newpipe.extractor.MediaFormat;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
|
import org.schabi.newpipe.extractor.stream_info.AudioStream;
|
||||||
|
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
|
||||||
import org.schabi.newpipe.extractor.stream_info.VideoStream;
|
import org.schabi.newpipe.extractor.stream_info.VideoStream;
|
||||||
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.player.BackgroundPlayer;
|
import org.schabi.newpipe.player.BackgroundPlayer;
|
||||||
import org.schabi.newpipe.player.PlayVideoActivity;
|
|
||||||
import org.schabi.newpipe.player.ExoPlayerActivity;
|
import org.schabi.newpipe.player.ExoPlayerActivity;
|
||||||
|
import org.schabi.newpipe.player.PlayVideoActivity;
|
||||||
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.util.NavStack;
|
||||||
|
import org.schabi.newpipe.util.PermissionHelper;
|
||||||
|
|
||||||
import static android.app.Activity.RESULT_OK;
|
import static android.app.Activity.RESULT_OK;
|
||||||
import static org.schabi.newpipe.ReCaptchaActivity.RECAPTCHA_REQUEST;
|
import static org.schabi.newpipe.ReCaptchaActivity.RECAPTCHA_REQUEST;
|
||||||
@@ -91,8 +92,6 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
* The fragment argument representing the item ID that this fragment
|
* The fragment argument representing the item ID that this fragment
|
||||||
* represents.
|
* represents.
|
||||||
*/
|
*/
|
||||||
public static final String VIDEO_URL = "video_url";
|
|
||||||
public static final String STREAMING_SERVICE = "streaming_service";
|
|
||||||
public static final String AUTO_PLAY = "auto_play";
|
public static final String AUTO_PLAY = "auto_play";
|
||||||
|
|
||||||
private AppCompatActivity activity;
|
private AppCompatActivity activity;
|
||||||
@@ -144,6 +143,7 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
TextView similarTitle = (TextView) activity.findViewById(R.id.detail_similar_title);
|
TextView similarTitle = (TextView) activity.findViewById(R.id.detail_similar_title);
|
||||||
Button backgroundButton = (Button)
|
Button backgroundButton = (Button)
|
||||||
activity.findViewById(R.id.detail_stream_thumbnail_window_background_button);
|
activity.findViewById(R.id.detail_stream_thumbnail_window_background_button);
|
||||||
|
View thumbnailView = activity.findViewById(R.id.detail_thumbnail_view);
|
||||||
View topView = activity.findViewById(R.id.detailTopView);
|
View topView = activity.findViewById(R.id.detailTopView);
|
||||||
Button channelButton = (Button) activity.findViewById(R.id.channel_button);
|
Button channelButton = (Button) activity.findViewById(R.id.channel_button);
|
||||||
|
|
||||||
@@ -275,14 +275,20 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//todo: make backgroundButton handle this
|
||||||
|
thumbnailView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
playVideo(info);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (info.channel_url != null && info.channel_url != "") {
|
if (info.channel_url != null && info.channel_url != "") {
|
||||||
channelButton.setOnClickListener(new View.OnClickListener() {
|
channelButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Intent i = new Intent(activity, ChannelActivity.class);
|
NavStack.getInstance()
|
||||||
i.putExtra(ChannelActivity.CHANNEL_URL, info.channel_url);
|
.openChannelActivity(getActivity(), info.channel_url, info.service_id);
|
||||||
i.putExtra(ChannelActivity.SERVICE_ID, info.service_id);
|
|
||||||
startActivity(i);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -393,6 +399,10 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
actionBarHandler.setOnDownloadListener(new ActionBarHandler.OnActionListener() {
|
actionBarHandler.setOnDownloadListener(new ActionBarHandler.OnActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onActionSelected(int selectedStreamId) {
|
public void onActionSelected(int selectedStreamId) {
|
||||||
|
if(!PermissionHelper.checkStoragePermissions(getActivity())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
|
|
||||||
@@ -523,13 +533,15 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
|
|
||||||
private void initSimilarVideos(final StreamInfo info) {
|
private void initSimilarVideos(final StreamInfo info) {
|
||||||
LinearLayout similarLayout = (LinearLayout) activity.findViewById(R.id.similar_streams_view);
|
LinearLayout similarLayout = (LinearLayout) activity.findViewById(R.id.similar_streams_view);
|
||||||
for (final StreamPreviewInfo item : info.related_streams) {
|
for (final InfoItem item : info.related_streams) {
|
||||||
similarLayout.addView(infoItemBuilder.buildView(similarLayout, item));
|
similarLayout.addView(infoItemBuilder.buildView(similarLayout, item));
|
||||||
}
|
}
|
||||||
infoItemBuilder.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
infoItemBuilder.setOnStreamInfoItemSelectedListener(
|
||||||
|
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void selected(String url) {
|
public void selected(String url, int serviceId) {
|
||||||
openStreamUrl(url);
|
NavStack.getInstance()
|
||||||
|
.openDetailActivity(getContext(), url, serviceId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -629,6 +641,7 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
onNotSpecifiedContentError();
|
onNotSpecifiedContentError();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
setHasOptionsMenu(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -647,10 +660,9 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(Bundle savedInstanceBundle) {
|
public void onStart() {
|
||||||
super.onActivityCreated(savedInstanceBundle);
|
super.onStart();
|
||||||
Activity a = getActivity();
|
Activity a = getActivity();
|
||||||
|
|
||||||
infoItemBuilder = new InfoItemBuilder(a, a.findViewById(android.R.id.content));
|
infoItemBuilder = new InfoItemBuilder(a, a.findViewById(android.R.id.content));
|
||||||
|
|
||||||
if (android.os.Build.VERSION.SDK_INT < 18) {
|
if (android.os.Build.VERSION.SDK_INT < 18) {
|
||||||
@@ -664,8 +676,8 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
// then we must not try to access objects of this fragment.
|
// then we must not try to access objects of this fragment.
|
||||||
// Otherwise the applications would crash.
|
// Otherwise the applications would crash.
|
||||||
if(backgroundButton != null) {
|
if(backgroundButton != null) {
|
||||||
streamingServiceId = getArguments().getInt(STREAMING_SERVICE);
|
streamingServiceId = getArguments().getInt(NavStack.SERVICE_ID);
|
||||||
String videoUrl = getArguments().getString(VIDEO_URL);
|
String videoUrl = getArguments().getString(NavStack.URL);
|
||||||
StreamInfoWorker siw = StreamInfoWorker.getInstance();
|
StreamInfoWorker siw = StreamInfoWorker.getInstance();
|
||||||
siw.search(streamingServiceId, videoUrl, getActivity());
|
siw.search(streamingServiceId, videoUrl, getActivity());
|
||||||
|
|
||||||
@@ -779,11 +791,13 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
actionBarHandler.setupMenu(menu, inflater);
|
actionBarHandler.setupMenu(menu, inflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
super.onOptionsItemSelected(item);
|
||||||
return actionBarHandler.onItemSelected(item);
|
return actionBarHandler.onItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -796,20 +810,13 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
stringResource, Toast.LENGTH_LONG).show();
|
stringResource, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openStreamUrl(String url) {
|
|
||||||
Intent detailIntent = new Intent(activity, VideoItemDetailActivity.class);
|
|
||||||
detailIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, url);
|
|
||||||
detailIntent.putExtra(
|
|
||||||
VideoItemDetailFragment.STREAMING_SERVICE, streamingServiceId);
|
|
||||||
activity.startActivity(detailIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case RECAPTCHA_REQUEST:
|
case RECAPTCHA_REQUEST:
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
String videoUrl = getArguments().getString(VIDEO_URL);
|
String videoUrl = getArguments().getString(NavStack.URL);
|
||||||
StreamInfoWorker siw = StreamInfoWorker.getInstance();
|
StreamInfoWorker siw = StreamInfoWorker.getInstance();
|
||||||
siw.search(streamingServiceId, videoUrl, getActivity());
|
siw.search(streamingServiceId, videoUrl, getActivity());
|
||||||
} else {
|
} else {
|
||||||
|
@@ -13,8 +13,8 @@ import android.os.IBinder;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.v4.app.NavUtils;
|
import android.support.v4.app.NavUtils;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
@@ -28,8 +28,10 @@ import android.widget.SeekBar;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.ThemableActivity;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.settings.NewPipeSettings;
|
||||||
import org.schabi.newpipe.settings.SettingsActivity;
|
import org.schabi.newpipe.settings.SettingsActivity;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -42,7 +44,7 @@ import us.shandian.giga.ui.fragment.MissionsFragment;
|
|||||||
import us.shandian.giga.util.CrashHandler;
|
import us.shandian.giga.util.CrashHandler;
|
||||||
import us.shandian.giga.util.Utility;
|
import us.shandian.giga.util.Utility;
|
||||||
|
|
||||||
public class DownloadActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
|
public class DownloadActivity extends ThemableActivity implements AdapterView.OnItemClickListener{
|
||||||
|
|
||||||
public static final String INTENT_DOWNLOAD = "us.shandian.giga.intent.DOWNLOAD";
|
public static final String INTENT_DOWNLOAD = "us.shandian.giga.intent.DOWNLOAD";
|
||||||
|
|
||||||
@@ -53,26 +55,11 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
|||||||
|
|
||||||
|
|
||||||
private MissionsFragment mFragment;
|
private MissionsFragment mFragment;
|
||||||
private DownloadManager mManager;
|
|
||||||
private DownloadManagerService.DMBinder mBinder;
|
|
||||||
|
|
||||||
private String mPendingUrl;
|
private String mPendingUrl;
|
||||||
private SharedPreferences mPrefs;
|
private SharedPreferences mPrefs;
|
||||||
|
|
||||||
private ServiceConnection mConnection = new ServiceConnection() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceConnected(ComponentName p1, IBinder binder) {
|
|
||||||
mBinder = (DownloadManagerService.DMBinder) binder;
|
|
||||||
mManager = mBinder.getDownloadManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceDisconnected(ComponentName p1) {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@TargetApi(21)
|
@TargetApi(21)
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -83,7 +70,6 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
|||||||
Intent i = new Intent();
|
Intent i = new Intent();
|
||||||
i.setClass(this, DownloadManagerService.class);
|
i.setClass(this, DownloadManagerService.class);
|
||||||
startService(i);
|
startService(i);
|
||||||
bindService(i, mConnection, Context.BIND_AUTO_CREATE);
|
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_downloader);
|
setContentView(R.layout.activity_downloader);
|
||||||
@@ -91,7 +77,7 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
|||||||
|
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
|
|
||||||
// its ok if this failes, we will catch that error later, and send it as report
|
// its ok if this fails, we will catch that error later, and send it as report
|
||||||
ActionBar actionBar = getSupportActionBar();
|
ActionBar actionBar = getSupportActionBar();
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
actionBar.setTitle(R.string.downloads_title);
|
actionBar.setTitle(R.string.downloads_title);
|
||||||
@@ -202,22 +188,24 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
|||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
if (item.getItemId() == R.id.okay) {
|
if (item.getItemId() == R.id.okay) {
|
||||||
|
|
||||||
|
String location;
|
||||||
|
if(audioButton.isChecked()) {
|
||||||
|
location = NewPipeSettings.getAudioDownloadPath(DownloadActivity.this);
|
||||||
|
} else {
|
||||||
|
location = NewPipeSettings.getVideoDownloadPath(DownloadActivity.this);
|
||||||
|
}
|
||||||
|
|
||||||
String fName = name.getText().toString().trim();
|
String fName = name.getText().toString().trim();
|
||||||
|
|
||||||
File f = new File(mManager.getLocation() + "/" + fName);
|
File f = new File(location, fName);
|
||||||
|
|
||||||
if (f.exists()) {
|
if (f.exists()) {
|
||||||
Toast.makeText(DownloadActivity.this, R.string.msg_exists, Toast.LENGTH_SHORT).show();
|
Toast.makeText(DownloadActivity.this, R.string.msg_exists, Toast.LENGTH_SHORT).show();
|
||||||
} else {
|
} else {
|
||||||
|
DownloadManagerService.startMission(
|
||||||
while (mBinder == null);
|
DownloadActivity.this,
|
||||||
|
getIntent().getData().toString(), location, fName,
|
||||||
int res = mManager.startMission(
|
audioButton.isChecked(), threads.getProgress() + 1);
|
||||||
getIntent().getData().toString(),
|
|
||||||
fName,
|
|
||||||
audioButton.isChecked(),
|
|
||||||
threads.getProgress() + 1);
|
|
||||||
mBinder.onMissionAdded(mManager.getMission(res));
|
|
||||||
mFragment.notifyChange();
|
mFragment.notifyChange();
|
||||||
|
|
||||||
mPrefs.edit().putInt(THREADS, threads.getProgress() + 1).commit();
|
mPrefs.edit().putInt(THREADS, threads.getProgress() + 1).commit();
|
||||||
@@ -254,9 +242,7 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
|||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case android.R.id.home: {
|
case android.R.id.home: {
|
||||||
Intent intent = new Intent(this, org.schabi.newpipe.MainActivity.class);
|
onBackPressed();
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
||||||
NavUtils.navigateUpTo(this, intent);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case R.id.action_settings: {
|
case R.id.action_settings: {
|
||||||
@@ -264,17 +250,9 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case R.id.action_report_error: {
|
|
||||||
ErrorActivity.reportError(DownloadActivity.this, new Vector<Throwable>(),
|
|
||||||
null, null,
|
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.USER_REPORT,
|
|
||||||
null,
|
|
||||||
"user_report", R.string.user_report));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return mFragment.onOptionsItemSelected(item) ||
|
return super.onOptionsItemSelected(item);
|
||||||
super.onOptionsItemSelected(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,8 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import org.schabi.newpipe.App;
|
import org.schabi.newpipe.App;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
|
import org.schabi.newpipe.settings.NewPipeSettings;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -65,24 +67,6 @@ public class DownloadDialog extends DialogFragment {
|
|||||||
public static final String AUDIO_URL = "audio_url";
|
public static final String AUDIO_URL = "audio_url";
|
||||||
public static final String VIDEO_URL = "video_url";
|
public static final String VIDEO_URL = "video_url";
|
||||||
|
|
||||||
private DownloadManager mManager;
|
|
||||||
private DownloadManagerService.DMBinder mBinder;
|
|
||||||
|
|
||||||
private ServiceConnection mConnection = new ServiceConnection() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceConnected(ComponentName p1, IBinder binder) {
|
|
||||||
mBinder = (DownloadManagerService.DMBinder) binder;
|
|
||||||
mManager = mBinder.getDownloadManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceDisconnected(ComponentName p1) {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
public DownloadDialog() {
|
public DownloadDialog() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -102,12 +86,6 @@ public class DownloadDialog extends DialogFragment {
|
|||||||
if(ContextCompat.checkSelfPermission(this.getContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
if(ContextCompat.checkSelfPermission(this.getContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0);
|
ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0);
|
||||||
|
|
||||||
Intent i = new Intent();
|
|
||||||
i.setClass(getContext(), DownloadManagerService.class);
|
|
||||||
getContext().startService(i);
|
|
||||||
getContext().bindService(i, mConnection, Context.BIND_AUTO_CREATE);
|
|
||||||
|
|
||||||
|
|
||||||
return inflater.inflate(R.layout.dialog_url, container);
|
return inflater.inflate(R.layout.dialog_url, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,36 +197,22 @@ public class DownloadDialog extends DialogFragment {
|
|||||||
|
|
||||||
String fName = name.getText().toString().trim();
|
String fName = name.getText().toString().trim();
|
||||||
|
|
||||||
// todo: add timeout? would be bad if the thread gets locked dueto this.
|
boolean isAudio = audioButton.isChecked();
|
||||||
while (mBinder == null);
|
String url, location, filename;
|
||||||
|
if(isAudio) {
|
||||||
if(audioButton.isChecked()){
|
url = arguments.getString(AUDIO_URL);
|
||||||
int res = mManager.startMission(
|
location = NewPipeSettings.getAudioDownloadPath(getContext());
|
||||||
arguments.getString(AUDIO_URL),
|
filename = fName + arguments.getString(FILE_SUFFIX_AUDIO);
|
||||||
fName + arguments.getString(FILE_SUFFIX_AUDIO),
|
} else {
|
||||||
audioButton.isChecked(),
|
url = arguments.getString(VIDEO_URL);
|
||||||
threads.getProgress() + 1);
|
location = NewPipeSettings.getVideoDownloadPath(getContext());
|
||||||
DownloadMission mission = mManager.getMission(res);
|
filename = fName + arguments.getString(FILE_SUFFIX_VIDEO);
|
||||||
mBinder.onMissionAdded(mission);
|
|
||||||
// add download listener to allow media scan notification
|
|
||||||
DownloadListener listener = new DownloadListener(getContext(), mission);
|
|
||||||
mission.addListener(listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(videoButton.isChecked()){
|
DownloadManagerService.startMission(getContext(), url, location, filename, isAudio,
|
||||||
int res = mManager.startMission(
|
threads.getProgress() + 1);
|
||||||
arguments.getString(VIDEO_URL),
|
|
||||||
fName + arguments.getString(FILE_SUFFIX_VIDEO),
|
|
||||||
audioButton.isChecked(),
|
|
||||||
threads.getProgress() + 1);
|
|
||||||
DownloadMission mission = mManager.getMission(res);
|
|
||||||
mBinder.onMissionAdded(mission);
|
|
||||||
// add download listener to allow media scan notification
|
|
||||||
DownloadListener listener = new DownloadListener(getContext(), mission);
|
|
||||||
mission.addListener(listener);
|
|
||||||
}
|
|
||||||
getDialog().dismiss();
|
getDialog().dismiss();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void download(String url, String title,
|
private void download(String url, String title,
|
||||||
|
@@ -1,62 +0,0 @@
|
|||||||
package org.schabi.newpipe.download;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import us.shandian.giga.get.DownloadMission;
|
|
||||||
import us.shandian.giga.get.DownloadMission.MissionListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by erwin on 06.11.16.
|
|
||||||
*
|
|
||||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
|
||||||
* DownloadListener.java is part of NewPipe.
|
|
||||||
*
|
|
||||||
* NewPipe is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* NewPipe is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class DownloadListener implements MissionListener
|
|
||||||
{
|
|
||||||
DownloadMission mMission;
|
|
||||||
Context mContext;
|
|
||||||
|
|
||||||
public DownloadListener(Context context, DownloadMission mission)
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
mMission = mission;
|
|
||||||
mContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onProgressUpdate(long done, long total)
|
|
||||||
{
|
|
||||||
// do nothing special ...
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFinish()
|
|
||||||
{
|
|
||||||
// notify media scanner on downloaded media file ...
|
|
||||||
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
|
|
||||||
Uri.parse( "file://" + mMission.location
|
|
||||||
+ "/" + mMission.name)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(int errCode)
|
|
||||||
{
|
|
||||||
// do nothing special ...
|
|
||||||
}
|
|
||||||
}
|
|
@@ -42,7 +42,7 @@ import info.guardianproject.netcipher.NetCipher;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// TODO: FOR HEVEN SAKE !!! DO NOT SIMPLY USE ASYNCTASK. MAKE THIS A PROPER SERVICE !!!
|
// TODO: FOR HEAVEN SAKE !!! DO NOT SIMPLY USE ASYNCTASK. MAKE THIS A PROPER SERVICE !!!
|
||||||
public class FileDownloader extends AsyncTask<Void, Integer, Void> {
|
public class FileDownloader extends AsyncTask<Void, Integer, Void> {
|
||||||
public static final String TAG = "FileDownloader";
|
public static final String TAG = "FileDownloader";
|
||||||
|
|
||||||
|
@@ -18,9 +18,9 @@ package org.schabi.newpipe.extractor;
|
|||||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**Common properties between StreamInfo and StreamPreviewInfo.*/
|
/**Common properties between StreamInfo and StreamInfoItem.*/
|
||||||
public abstract class AbstractStreamInfo {
|
public abstract class AbstractStreamInfo {
|
||||||
public static enum StreamType {
|
public enum StreamType {
|
||||||
NONE, // placeholder to check if stream type was checked or not
|
NONE, // placeholder to check if stream type was checked or not
|
||||||
VIDEO_STREAM,
|
VIDEO_STREAM,
|
||||||
AUDIO_STREAM,
|
AUDIO_STREAM,
|
||||||
|
33
app/src/main/java/org/schabi/newpipe/extractor/InfoItem.java
Normal file
33
app/src/main/java/org/schabi/newpipe/extractor/InfoItem.java
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package org.schabi.newpipe.extractor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by the-scrabi on 11.02.17.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||||
|
* InfoItem.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface InfoItem {
|
||||||
|
public enum InfoType {
|
||||||
|
STREAM,
|
||||||
|
PLAYLIST,
|
||||||
|
CHANNEL
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoType infoType();
|
||||||
|
String getTitle();
|
||||||
|
String getLink();
|
||||||
|
}
|
@@ -0,0 +1,61 @@
|
|||||||
|
package org.schabi.newpipe.extractor;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Christian Schabesberger on 12.02.17.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||||
|
* InfoItemCollector.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InfoItemCollector {
|
||||||
|
private List<InfoItem> itemList = new Vector<>();
|
||||||
|
private List<Throwable> errors = new Vector<>();
|
||||||
|
private int serviceId = -1;
|
||||||
|
|
||||||
|
public InfoItemCollector(int serviceId) {
|
||||||
|
this.serviceId = serviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<InfoItem> getItemList() {
|
||||||
|
return itemList;
|
||||||
|
}
|
||||||
|
public List<Throwable> getErrors() {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
protected void addFromCollector(InfoItemCollector otherC) throws ExtractionException {
|
||||||
|
if(serviceId != otherC.serviceId) {
|
||||||
|
throw new ExtractionException("Service Id does not equal: "
|
||||||
|
+ NewPipe.getNameOfService(serviceId)
|
||||||
|
+ " and " + NewPipe.getNameOfService(otherC.serviceId));
|
||||||
|
}
|
||||||
|
errors.addAll(otherC.errors);
|
||||||
|
itemList.addAll(otherC.itemList);
|
||||||
|
}
|
||||||
|
protected void addError(Exception e) {
|
||||||
|
errors.add(e);
|
||||||
|
}
|
||||||
|
protected void addItem(InfoItem item) {
|
||||||
|
itemList.add(item);
|
||||||
|
}
|
||||||
|
protected int getServiceId() {
|
||||||
|
return serviceId;
|
||||||
|
}
|
||||||
|
}
|
@@ -34,25 +34,22 @@ public class NewPipe {
|
|||||||
|
|
||||||
private static final String TAG = NewPipe.class.toString();
|
private static final String TAG = NewPipe.class.toString();
|
||||||
|
|
||||||
private static final StreamingService[] serviceList = {
|
|
||||||
new YoutubeService(0)
|
|
||||||
};
|
|
||||||
|
|
||||||
private static Downloader downloader = null;
|
private static Downloader downloader = null;
|
||||||
|
|
||||||
public static StreamingService[] getServices() {
|
public static StreamingService[] getServices() {
|
||||||
return serviceList;
|
return ServiceList.serviceList;
|
||||||
}
|
}
|
||||||
public static StreamingService getService(int serviceId)throws ExtractionException {
|
public static StreamingService getService(int serviceId)throws ExtractionException {
|
||||||
for(StreamingService s : serviceList) {
|
for(StreamingService s : ServiceList.serviceList) {
|
||||||
if(s.getServiceId() == serviceId) {
|
if(s.getServiceId() == serviceId) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new ExtractionException("Service not known: " + Integer.toString(serviceId));
|
return null;
|
||||||
}
|
}
|
||||||
public static StreamingService getService(String serviceName) throws ExtractionException {
|
public static StreamingService getService(String serviceName) throws ExtractionException {
|
||||||
return serviceList[getIdOfService(serviceName)];
|
return ServiceList.serviceList[getIdOfService(serviceName)];
|
||||||
}
|
}
|
||||||
public static String getNameOfService(int id) {
|
public static String getNameOfService(int id) {
|
||||||
try {
|
try {
|
||||||
@@ -63,13 +60,13 @@ public class NewPipe {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static int getIdOfService(String serviceName) throws ExtractionException {
|
public static int getIdOfService(String serviceName) {
|
||||||
for(int i = 0; i < serviceList.length; i++) {
|
for(int i = 0; i < ServiceList.serviceList.length; i++) {
|
||||||
if(serviceList[i].getServiceInfo().name.equals(serviceName)) {
|
if(ServiceList.serviceList[i].getServiceInfo().name.equals(serviceName)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new ExtractionException("Error: Service " + serviceName + " not known.");
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init(Downloader d) {
|
public static void init(Downloader d) {
|
||||||
@@ -79,4 +76,13 @@ public class NewPipe {
|
|||||||
public static Downloader getDownloader() {
|
public static Downloader getDownloader() {
|
||||||
return downloader;
|
return downloader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static StreamingService getServiceByUrl(String url) {
|
||||||
|
for(StreamingService s : ServiceList.serviceList) {
|
||||||
|
if(s.getLinkTypeByUrl(url) != StreamingService.LinkType.NONE) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,15 +42,23 @@ public class Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String matchGroup1(String pattern, String input) throws RegexException {
|
public static String matchGroup1(String pattern, String input) throws RegexException {
|
||||||
|
return matchGroup(pattern, input, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String matchGroup(String pattern, String input, int group) throws RegexException {
|
||||||
Pattern pat = Pattern.compile(pattern);
|
Pattern pat = Pattern.compile(pattern);
|
||||||
Matcher mat = pat.matcher(input);
|
Matcher mat = pat.matcher(input);
|
||||||
boolean foundMatch = mat.find();
|
boolean foundMatch = mat.find();
|
||||||
if (foundMatch) {
|
if (foundMatch) {
|
||||||
return mat.group(1);
|
return mat.group(group);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//Log.e(TAG, "failed to find pattern \""+pattern+"\" inside of \""+input+"\"");
|
//Log.e(TAG, "failed to find pattern \""+pattern+"\" inside of \""+input+"\"");
|
||||||
throw new RegexException("failed to find pattern \""+pattern+" inside of "+input+"\"");
|
if(input.length() > 1024) {
|
||||||
|
throw new RegexException("failed to find pattern \""+pattern);
|
||||||
|
} else {
|
||||||
|
throw new RegexException("failed to find pattern \"" + pattern + " inside of " + input + "\"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,13 @@
|
|||||||
|
package org.schabi.newpipe.extractor;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.services.youtube.YoutubeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by the-scrabi on 18.02.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ServiceList {
|
||||||
|
public static final StreamingService[] serviceList = {
|
||||||
|
new YoutubeService(0)
|
||||||
|
};
|
||||||
|
}
|
@@ -3,7 +3,6 @@ package org.schabi.newpipe.extractor;
|
|||||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
import org.schabi.newpipe.extractor.search.SearchEngine;
|
import org.schabi.newpipe.extractor.search.SearchEngine;
|
||||||
import org.schabi.newpipe.extractor.search.SuggestionExtractor;
|
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamExtractor;
|
import org.schabi.newpipe.extractor.stream_info.StreamExtractor;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -33,6 +32,13 @@ public abstract class StreamingService {
|
|||||||
public String name = "";
|
public String name = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum LinkType {
|
||||||
|
NONE,
|
||||||
|
STREAM,
|
||||||
|
CHANNEL,
|
||||||
|
PLAYLIST
|
||||||
|
}
|
||||||
|
|
||||||
private int serviceId;
|
private int serviceId;
|
||||||
|
|
||||||
public StreamingService(int id) {
|
public StreamingService(int id) {
|
||||||
@@ -44,7 +50,7 @@ public abstract class StreamingService {
|
|||||||
public abstract StreamExtractor getExtractorInstance(String url)
|
public abstract StreamExtractor getExtractorInstance(String url)
|
||||||
throws IOException, ExtractionException;
|
throws IOException, ExtractionException;
|
||||||
public abstract SearchEngine getSearchEngineInstance();
|
public abstract SearchEngine getSearchEngineInstance();
|
||||||
public abstract UrlIdHandler getUrlIdHandlerInstance();
|
public abstract UrlIdHandler getStreamUrlIdHandlerInstance();
|
||||||
public abstract UrlIdHandler getChannelUrlIdHandlerInstance();
|
public abstract UrlIdHandler getChannelUrlIdHandlerInstance();
|
||||||
public abstract ChannelExtractor getChannelExtractorInstance(String url, int page)
|
public abstract ChannelExtractor getChannelExtractorInstance(String url, int page)
|
||||||
throws ExtractionException, IOException;
|
throws ExtractionException, IOException;
|
||||||
@@ -53,4 +59,20 @@ public abstract class StreamingService {
|
|||||||
public final int getServiceId() {
|
public final int getServiceId() {
|
||||||
return serviceId;
|
return serviceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* figure out where the link is pointing to (a channel, video, playlist, etc.)
|
||||||
|
*/
|
||||||
|
public final LinkType getLinkTypeByUrl(String url) {
|
||||||
|
UrlIdHandler sH = getStreamUrlIdHandlerInstance();
|
||||||
|
UrlIdHandler cH = getChannelUrlIdHandlerInstance();
|
||||||
|
|
||||||
|
if(sH.acceptUrl(url)) {
|
||||||
|
return LinkType.STREAM;
|
||||||
|
} else if(cH.acceptUrl(url)) {
|
||||||
|
return LinkType.CHANNEL;
|
||||||
|
} else {
|
||||||
|
return LinkType.NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package org.schabi.newpipe.extractor.search;
|
package org.schabi.newpipe.extractor;
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
|
@@ -23,6 +23,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public interface UrlIdHandler {
|
public interface UrlIdHandler {
|
||||||
|
|
||||||
String getUrl(String videoId);
|
String getUrl(String videoId);
|
||||||
String getId(String siteUrl) throws ParsingException;
|
String getId(String siteUrl) throws ParsingException;
|
||||||
String cleanUrl(String siteUrl) throws ParsingException;
|
String cleanUrl(String siteUrl) throws ParsingException;
|
||||||
|
@@ -3,7 +3,7 @@ package org.schabi.newpipe.extractor.channel;
|
|||||||
import org.schabi.newpipe.extractor.UrlIdHandler;
|
import org.schabi.newpipe.extractor.UrlIdHandler;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamPreviewInfoCollector;
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ public abstract class ChannelExtractor {
|
|||||||
private int serviceId;
|
private int serviceId;
|
||||||
private String url;
|
private String url;
|
||||||
private UrlIdHandler urlIdHandler;
|
private UrlIdHandler urlIdHandler;
|
||||||
private StreamPreviewInfoCollector previewInfoCollector;
|
private StreamInfoItemCollector previewInfoCollector;
|
||||||
private int page = -1;
|
private int page = -1;
|
||||||
|
|
||||||
public ChannelExtractor(UrlIdHandler urlIdHandler, String url, int page, int serviceId)
|
public ChannelExtractor(UrlIdHandler urlIdHandler, String url, int page, int serviceId)
|
||||||
@@ -40,12 +40,12 @@ public abstract class ChannelExtractor {
|
|||||||
this.page = page;
|
this.page = page;
|
||||||
this.serviceId = serviceId;
|
this.serviceId = serviceId;
|
||||||
this.urlIdHandler = urlIdHandler;
|
this.urlIdHandler = urlIdHandler;
|
||||||
previewInfoCollector = new StreamPreviewInfoCollector(urlIdHandler, serviceId);
|
previewInfoCollector = new StreamInfoItemCollector(urlIdHandler, serviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUrl() { return url; }
|
public String getUrl() { return url; }
|
||||||
public UrlIdHandler getUrlIdHandler() { return urlIdHandler; }
|
public UrlIdHandler getUrlIdHandler() { return urlIdHandler; }
|
||||||
public StreamPreviewInfoCollector getStreamPreviewInfoCollector() {
|
public StreamInfoItemCollector getStreamPreviewInfoCollector() {
|
||||||
return previewInfoCollector;
|
return previewInfoCollector;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ public abstract class ChannelExtractor {
|
|||||||
public abstract String getAvatarUrl() throws ParsingException;
|
public abstract String getAvatarUrl() throws ParsingException;
|
||||||
public abstract String getBannerUrl() throws ParsingException;
|
public abstract String getBannerUrl() throws ParsingException;
|
||||||
public abstract String getFeedUrl() throws ParsingException;
|
public abstract String getFeedUrl() throws ParsingException;
|
||||||
public abstract StreamPreviewInfoCollector getStreams() throws ParsingException;
|
public abstract StreamInfoItemCollector getStreams() throws ParsingException;
|
||||||
public abstract boolean hasNextPage() throws ParsingException;
|
public abstract boolean hasNextPage() throws ParsingException;
|
||||||
public int getServiceId() {
|
public int getServiceId() {
|
||||||
return serviceId;
|
return serviceId;
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
package org.schabi.newpipe.extractor.channel;
|
package org.schabi.newpipe.extractor.channel;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamPreviewInfo;
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamPreviewInfoCollector;
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
@@ -59,7 +60,7 @@ public class ChannelInfo {
|
|||||||
info.errors.add(e);
|
info.errors.add(e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
StreamPreviewInfoCollector c = extractor.getStreams();
|
StreamInfoItemCollector c = extractor.getStreams();
|
||||||
info.related_streams = c.getItemList();
|
info.related_streams = c.getItemList();
|
||||||
info.errors.addAll(c.getErrors());
|
info.errors.addAll(c.getErrors());
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
@@ -74,7 +75,7 @@ public class ChannelInfo {
|
|||||||
public String avatar_url = "";
|
public String avatar_url = "";
|
||||||
public String banner_url = "";
|
public String banner_url = "";
|
||||||
public String feed_url = "";
|
public String feed_url = "";
|
||||||
public List<StreamPreviewInfo> related_streams = null;
|
public List<InfoItem> related_streams = null;
|
||||||
public boolean hasNextPage = false;
|
public boolean hasNextPage = false;
|
||||||
|
|
||||||
public List<Throwable> errors = new Vector<>();
|
public List<Throwable> errors = new Vector<>();
|
||||||
|
@@ -0,0 +1,44 @@
|
|||||||
|
package org.schabi.newpipe.extractor.channel;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Christian Schabesberger on 11.02.17.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||||
|
* ChannelInfoItem.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ChannelInfoItem implements InfoItem {
|
||||||
|
|
||||||
|
public int serviceId = -1;
|
||||||
|
public String channelName = "";
|
||||||
|
public String thumbnailUrl = "";
|
||||||
|
public String webPageUrl = "";
|
||||||
|
public String description = "";
|
||||||
|
public long subscriberCount = -1;
|
||||||
|
public int videoAmount = -1;
|
||||||
|
|
||||||
|
public InfoType infoType() {
|
||||||
|
return InfoType.CHANNEL;
|
||||||
|
}
|
||||||
|
public String getTitle() {
|
||||||
|
return channelName;
|
||||||
|
}
|
||||||
|
public String getLink() {
|
||||||
|
return webPageUrl;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,74 @@
|
|||||||
|
package org.schabi.newpipe.extractor.channel;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.InfoItemCollector;
|
||||||
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.FoundAdException;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||||
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Christian Schabesberger on 12.02.17.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||||
|
* ChannelInfoItemCollector.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ChannelInfoItemCollector extends InfoItemCollector {
|
||||||
|
public ChannelInfoItemCollector(int serviceId) {
|
||||||
|
super(serviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelInfoItem extract(ChannelInfoItemExtractor extractor) throws ParsingException {
|
||||||
|
ChannelInfoItem resultItem = new ChannelInfoItem();
|
||||||
|
// importand information
|
||||||
|
resultItem.channelName = extractor.getChannelName();
|
||||||
|
|
||||||
|
resultItem.serviceId = getServiceId();
|
||||||
|
resultItem.webPageUrl = extractor.getWebPageUrl();
|
||||||
|
|
||||||
|
// optional information
|
||||||
|
try {
|
||||||
|
resultItem.subscriberCount = extractor.getSubscriberCount();
|
||||||
|
} catch (Exception e) {
|
||||||
|
addError(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
resultItem.videoAmount = extractor.getVideoAmount();
|
||||||
|
} catch (Exception e) {
|
||||||
|
addError(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
resultItem.thumbnailUrl = extractor.getThumbnailUrl();
|
||||||
|
} catch (Exception e) {
|
||||||
|
addError(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
resultItem.description = extractor.getDescription();
|
||||||
|
} catch (Exception e) {
|
||||||
|
addError(e);
|
||||||
|
}
|
||||||
|
return resultItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void commit(ChannelInfoItemExtractor extractor) throws ParsingException {
|
||||||
|
try {
|
||||||
|
addItem(extract(extractor));
|
||||||
|
} catch (Exception e) {
|
||||||
|
addError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,32 @@
|
|||||||
|
package org.schabi.newpipe.extractor.channel;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Christian Schabesberger on 12.02.17.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||||
|
* ChannelInfoItemExtractor.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ChannelInfoItemExtractor {
|
||||||
|
String getThumbnailUrl() throws ParsingException;
|
||||||
|
String getChannelName() throws ParsingException;
|
||||||
|
String getWebPageUrl() throws ParsingException;
|
||||||
|
String getDescription() throws ParsingException;
|
||||||
|
long getSubscriberCount() throws ParsingException;
|
||||||
|
int getVideoAmount() throws ParsingException;
|
||||||
|
}
|
@@ -0,0 +1,79 @@
|
|||||||
|
package org.schabi.newpipe.extractor.search;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.InfoItemCollector;
|
||||||
|
import org.schabi.newpipe.extractor.UrlIdHandler;
|
||||||
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItemCollector;
|
||||||
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.FoundAdException;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||||
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Christian Schabesberger on 12.02.17.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||||
|
* InfoItemSearchCollector.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InfoItemSearchCollector extends InfoItemCollector {
|
||||||
|
private String suggestion = "";
|
||||||
|
private StreamInfoItemCollector streamCollector;
|
||||||
|
private ChannelInfoItemCollector channelCollector;
|
||||||
|
|
||||||
|
SearchResult result = new SearchResult();
|
||||||
|
|
||||||
|
InfoItemSearchCollector(UrlIdHandler handler, int serviceId) {
|
||||||
|
super(serviceId);
|
||||||
|
streamCollector = new StreamInfoItemCollector(handler, serviceId);
|
||||||
|
channelCollector = new ChannelInfoItemCollector(serviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuggestion(String suggestion) {
|
||||||
|
this.suggestion = suggestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchResult getSearchResult() throws ExtractionException {
|
||||||
|
|
||||||
|
addFromCollector(channelCollector);
|
||||||
|
addFromCollector(streamCollector);
|
||||||
|
|
||||||
|
result.suggestion = suggestion;
|
||||||
|
result.errors = getErrors();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void commit(StreamInfoItemExtractor extractor) {
|
||||||
|
try {
|
||||||
|
result.resultList.add(streamCollector.extract(extractor));
|
||||||
|
} catch(FoundAdException ae) {
|
||||||
|
System.err.println("Found add");
|
||||||
|
} catch (Exception e) {
|
||||||
|
addError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void commit(ChannelInfoItemExtractor extractor) {
|
||||||
|
try {
|
||||||
|
result.resultList.add(channelCollector.extract(extractor));
|
||||||
|
} catch(FoundAdException ae) {
|
||||||
|
System.err.println("Found add");
|
||||||
|
} catch (Exception e) {
|
||||||
|
addError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,9 +2,10 @@ package org.schabi.newpipe.extractor.search;
|
|||||||
|
|
||||||
import org.schabi.newpipe.extractor.UrlIdHandler;
|
import org.schabi.newpipe.extractor.UrlIdHandler;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.EnumSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 10.08.15.
|
* Created by Christian Schabesberger on 10.08.15.
|
||||||
@@ -26,26 +27,27 @@ import java.util.List;
|
|||||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
|
||||||
public abstract class SearchEngine {
|
public abstract class SearchEngine {
|
||||||
|
public enum Filter {
|
||||||
|
STREAM, CHANNEL, PLAY_LIST
|
||||||
|
}
|
||||||
|
|
||||||
public static class NothingFoundException extends ExtractionException {
|
public static class NothingFoundException extends ExtractionException {
|
||||||
public NothingFoundException(String message) {
|
public NothingFoundException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private InfoItemSearchCollector collector;
|
||||||
private StreamPreviewInfoSearchCollector collector;
|
|
||||||
|
|
||||||
public SearchEngine(UrlIdHandler urlIdHandler, int serviceId) {
|
public SearchEngine(UrlIdHandler urlIdHandler, int serviceId) {
|
||||||
collector = new StreamPreviewInfoSearchCollector(urlIdHandler, serviceId);
|
collector = new InfoItemSearchCollector(urlIdHandler, serviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected StreamPreviewInfoSearchCollector getStreamPreviewInfoSearchCollector() {
|
protected InfoItemSearchCollector getInfoItemSearchCollector() {
|
||||||
return collector;
|
return collector;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Result search(String query, int page);
|
//Result search(String query, int page);
|
||||||
public abstract StreamPreviewInfoSearchCollector search(
|
public abstract InfoItemSearchCollector search(
|
||||||
String query, int page, String contentCountry)
|
String query, int page, String contentCountry, EnumSet<Filter> filter)
|
||||||
throws ExtractionException, IOException;
|
throws ExtractionException, IOException;
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user