Ditched external server calls & made the app show all playlist items and not first 50 videos
This commit is contained in:
parent
217c0f431f
commit
9230185930
9 changed files with 243 additions and 136 deletions
|
|
@ -23,10 +23,13 @@
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_launcher_background.xml" value="0.1275" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_launcher_background.xml" value="0.1275" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_music.xml" value="0.1275" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_music.xml" value="0.1275" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_search.xml" value="0.1275" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/ic_search.xml" value="0.1275" />
|
||||||
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/drawable/round_corner.xml" value="0.1275" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/activity_main.xml" value="0.27704147071398033" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/activity_main.xml" value="0.27704147071398033" />
|
||||||
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/download_all_card.xml" value="0.33" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/fragment_history.xml" value="0.2057460611677479" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/fragment_history.xml" value="0.2057460611677479" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/fragment_history_list.xml" value="0.2057460611677479" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/fragment_history_list.xml" value="0.2057460611677479" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/fragment_home.xml" value="0.2057460611677479" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/fragment_home.xml" value="0.2057460611677479" />
|
||||||
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/layout/result_card.xml" value="0.25" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/menu/bottom_nav_menu.xml" value="0.2057460611677479" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/menu/bottom_nav_menu.xml" value="0.2057460611677479" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/menu/history_menu.xml" value="0.25" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/menu/history_menu.xml" value="0.25" />
|
||||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/menu/main_menu.xml" value="0.2057460611677479" />
|
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/menu/main_menu.xml" value="0.2057460611677479" />
|
||||||
|
|
|
||||||
2
app/.gitignore
vendored
2
app/.gitignore
vendored
|
|
@ -1 +1 @@
|
||||||
/build
|
/build
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
apply plugin: 'com.android.application'
|
plugins {
|
||||||
|
id 'com.android.application'
|
||||||
|
id 'com.google.secrets_gradle_plugin' version '0.4'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 31
|
compileSdkVersion 31
|
||||||
|
|
@ -43,7 +47,6 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,11 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name = "ytAPIkey"
|
||||||
|
android:value = "${ytAPI}"
|
||||||
|
/>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
@ -27,29 +27,23 @@ import android.widget.RelativeLayout;
|
||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.widget.SearchView;
|
import androidx.appcompat.widget.SearchView;
|
||||||
import androidx.cardview.widget.CardView;
|
import androidx.cardview.widget.CardView;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import com.deniscerri.ytdl.api.YoutubeAPIManager;
|
||||||
import com.deniscerri.ytdl.database.DBManager;
|
import com.deniscerri.ytdl.database.DBManager;
|
||||||
import com.deniscerri.ytdl.database.Video;
|
import com.deniscerri.ytdl.database.Video;
|
||||||
import com.squareup.picasso.Picasso;
|
import com.squareup.picasso.Picasso;
|
||||||
import com.yausername.youtubedl_android.DownloadProgressCallback;
|
import com.yausername.youtubedl_android.DownloadProgressCallback;
|
||||||
import com.yausername.youtubedl_android.YoutubeDL;
|
import com.yausername.youtubedl_android.YoutubeDL;
|
||||||
import com.yausername.youtubedl_android.YoutubeDLRequest;
|
import com.yausername.youtubedl_android.YoutubeDLRequest;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStreamReader;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.net.URL;
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -68,11 +62,7 @@ import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple {@link Fragment} subclass.
|
|
||||||
* Use the {@link HomeFragment#newInstance} factory method to
|
|
||||||
* create an instance of this fragment.
|
|
||||||
*/
|
|
||||||
public class HomeFragment extends Fragment implements View.OnClickListener{
|
public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
private boolean downloading = false;
|
private boolean downloading = false;
|
||||||
|
|
@ -82,9 +72,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
private LinearLayout linearLayout;
|
private LinearLayout linearLayout;
|
||||||
private ScrollView scrollView;
|
private ScrollView scrollView;
|
||||||
|
|
||||||
private JSONObject requestData;
|
|
||||||
private String videoID;
|
|
||||||
|
|
||||||
private static final String TAG = "HomeFragment";
|
private static final String TAG = "HomeFragment";
|
||||||
|
|
||||||
private ArrayList<Video> resultObjects;
|
private ArrayList<Video> resultObjects;
|
||||||
|
|
@ -94,6 +81,7 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
private DBManager dbManager;
|
private DBManager dbManager;
|
||||||
|
private YoutubeAPIManager youtubeAPIManager;
|
||||||
|
|
||||||
private final DownloadProgressCallback callback = new DownloadProgressCallback() {
|
private final DownloadProgressCallback callback = new DownloadProgressCallback() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -110,6 +98,7 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
private static final String ARG_PARAM1 = "param1";
|
private static final String ARG_PARAM1 = "param1";
|
||||||
private static final String ARG_PARAM2 = "param2";
|
private static final String ARG_PARAM2 = "param2";
|
||||||
|
|
||||||
|
|
||||||
public HomeFragment() {
|
public HomeFragment() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
|
|
@ -139,6 +128,7 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
fragmentView = inflater.inflate(R.layout.fragment_home, container, false);
|
fragmentView = inflater.inflate(R.layout.fragment_home, container, false);
|
||||||
|
|
||||||
initViews();
|
initViews();
|
||||||
|
|
||||||
fragmentView.setOnScrollChangeListener((view, i, i1, i2, i3) -> positions = new int[]{i,i1});
|
fragmentView.setOnScrollChangeListener((view, i, i1, i2, i3) -> positions = new int[]{i,i1});
|
||||||
|
|
@ -167,7 +157,7 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews(){
|
||||||
linearLayout = fragmentView.findViewById(R.id.linearLayout1);
|
linearLayout = fragmentView.findViewById(R.id.linearLayout1);
|
||||||
scrollView = fragmentView.findViewById(R.id.scrollView1);
|
scrollView = fragmentView.findViewById(R.id.scrollView1);
|
||||||
}
|
}
|
||||||
|
|
@ -228,11 +218,16 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
inputQuery = intent.getStringExtra(Intent.EXTRA_TEXT);
|
inputQuery = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void scrollToTop(){
|
||||||
|
fragmentView.scrollTo(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
private void parseQuery() {
|
private void parseQuery() {
|
||||||
linearLayout.removeAllViews();
|
linearLayout.removeAllViews();
|
||||||
|
|
||||||
resultObjects = new ArrayList<>();
|
resultObjects = new ArrayList<>();
|
||||||
dbManager = new DBManager(requireContext());
|
dbManager = new DBManager(requireContext());
|
||||||
|
youtubeAPIManager = new YoutubeAPIManager(requireContext());
|
||||||
|
|
||||||
String type = "Search";
|
String type = "Search";
|
||||||
Pattern p = Pattern.compile("^(https?)://(www.)?youtu(.be)?");
|
Pattern p = Pattern.compile("^(https?)://(www.)?youtu(.be)?");
|
||||||
|
|
@ -240,7 +235,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
if(m.find()){
|
if(m.find()){
|
||||||
type = "Video";
|
type = "Video";
|
||||||
|
|
||||||
if (inputQuery.contains("list=")) {
|
if (inputQuery.contains("list=")) {
|
||||||
type = "Playlist";
|
type = "Playlist";
|
||||||
}
|
}
|
||||||
|
|
@ -253,29 +247,16 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
case "Search": {
|
case "Search": {
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
requestData = makeRequest("https://ytdl.deniscerri.repl.co/search?Query=" + inputQuery);
|
resultObjects = youtubeAPIManager.search(inputQuery);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
Log.e(TAG, e.toString());
|
Log.e(TAG, e.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
thread.start();
|
thread.start();
|
||||||
thread.join();
|
thread.join();
|
||||||
|
for(int i = 0; i < resultObjects.size(); i++){
|
||||||
JSONArray dataArray = requestData.getJSONArray("items");
|
createCard(resultObjects.get(i));
|
||||||
for(int i = 0; i < dataArray.length(); i++){
|
|
||||||
JSONObject element = dataArray.getJSONObject(i);
|
|
||||||
JSONObject snippet = element.getJSONObject("snippet");
|
|
||||||
if(element.getJSONObject("id").getString("kind").equals("youtube#video")){
|
|
||||||
|
|
||||||
videoID = element.getJSONObject("id").getString("videoId");
|
|
||||||
snippet.put("videoID", videoID);
|
|
||||||
snippet = fixThumbnail(snippet);
|
|
||||||
Video video = createVideofromJSON(snippet);
|
|
||||||
resultObjects.add(video);
|
|
||||||
createCard(video);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dbManager.shtoVideoRezultat(resultObjects);
|
dbManager.shtoVideoRezultat(resultObjects);
|
||||||
break;
|
break;
|
||||||
}case "Video": {
|
}case "Video": {
|
||||||
|
|
@ -288,28 +269,22 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
requestData = makeRequest("https://ytdl.deniscerri.repl.co/video?id=" + inputQuery).getJSONArray("items").getJSONObject(0);
|
resultObjects.add(youtubeAPIManager.getVideo(inputQuery));
|
||||||
videoID = requestData.getString("id");
|
|
||||||
requestData = requestData.getJSONObject("snippet");
|
|
||||||
requestData.put("videoID", videoID);
|
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
Log.e(TAG, e.toString());
|
Log.e(TAG, e.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
thread.start();
|
thread.start();
|
||||||
thread.join();
|
thread.join();
|
||||||
|
|
||||||
requestData = fixThumbnail(requestData);
|
|
||||||
Video video = createVideofromJSON(requestData);
|
|
||||||
resultObjects.add(video);
|
|
||||||
dbManager.shtoVideoRezultat(resultObjects);
|
dbManager.shtoVideoRezultat(resultObjects);
|
||||||
createCard(video);
|
createCard(resultObjects.get(0));
|
||||||
break;
|
break;
|
||||||
}case "Playlist": {
|
}case "Playlist": {
|
||||||
inputQuery = inputQuery.split("list=")[1];
|
inputQuery = inputQuery.split("list=")[1];
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
requestData = makeRequest("https://ytdl.deniscerri.repl.co/ytPlaylist?id=" + inputQuery);
|
resultObjects = youtubeAPIManager.getPlaylist(inputQuery, "");
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
Log.e(TAG, e.toString());
|
Log.e(TAG, e.toString());
|
||||||
}
|
}
|
||||||
|
|
@ -317,20 +292,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
thread.start();
|
thread.start();
|
||||||
thread.join();
|
thread.join();
|
||||||
|
|
||||||
|
|
||||||
JSONArray dataArray = requestData.getJSONArray("items");
|
|
||||||
for(int i = 0; i < dataArray.length(); i++){
|
|
||||||
JSONObject element = dataArray.getJSONObject(i);
|
|
||||||
JSONObject snippet = element.getJSONObject("snippet");
|
|
||||||
if(snippet.getJSONObject("resourceId").getString("kind").equals("youtube#video")){
|
|
||||||
videoID = snippet.getJSONObject("resourceId").getString("videoId");
|
|
||||||
snippet.put("videoID", videoID);
|
|
||||||
snippet = fixThumbnail(snippet);
|
|
||||||
Video video = createVideofromJSON(snippet);
|
|
||||||
video.setIsPlaylistItem(1);
|
|
||||||
resultObjects.add(video);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbManager.shtoVideoRezultat(resultObjects);
|
dbManager.shtoVideoRezultat(resultObjects);
|
||||||
|
|
||||||
// DOWNLOAD ALL BUTTON
|
// DOWNLOAD ALL BUTTON
|
||||||
|
|
@ -350,20 +311,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Video createVideofromJSON(JSONObject obj){
|
|
||||||
Video video = null;
|
|
||||||
try{
|
|
||||||
String id = obj.getString("videoID");
|
|
||||||
String title = obj.getString("title");
|
|
||||||
String author = obj.getString("channelTitle");
|
|
||||||
String thumb = obj.getString("thumb");
|
|
||||||
|
|
||||||
video = new Video(id, title, author, thumb);
|
|
||||||
}catch(Exception ignored){}
|
|
||||||
|
|
||||||
return video;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createDownloadAllCard(){
|
private void createDownloadAllCard(){
|
||||||
RelativeLayout r = new RelativeLayout(getContext());
|
RelativeLayout r = new RelativeLayout(getContext());
|
||||||
r.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
|
r.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
@ -429,63 +376,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONObject fixThumbnail(JSONObject o){
|
|
||||||
String imageURL = "";
|
|
||||||
try{
|
|
||||||
JSONObject thumbs = o.getJSONObject("thumbnails");
|
|
||||||
imageURL = thumbs.getJSONObject("maxres").getString("url");
|
|
||||||
}catch(Exception e){
|
|
||||||
try {
|
|
||||||
JSONObject thumbs = o.getJSONObject("thumbnails");
|
|
||||||
imageURL = thumbs.getJSONObject("high").getString("url");
|
|
||||||
}catch(Exception ignored){}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
o.put("thumb", imageURL);
|
|
||||||
}catch(Exception ignored){}
|
|
||||||
|
|
||||||
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JSONObject makeRequest(String query){
|
|
||||||
Log.e(TAG, query);
|
|
||||||
BufferedReader reader;
|
|
||||||
String line;
|
|
||||||
StringBuilder responseContent = new StringBuilder();
|
|
||||||
HttpURLConnection conn;
|
|
||||||
JSONObject json = new JSONObject();
|
|
||||||
|
|
||||||
try{
|
|
||||||
URL url = new URL(query);
|
|
||||||
conn = (HttpURLConnection) url.openConnection();
|
|
||||||
|
|
||||||
conn.setRequestMethod("GET");
|
|
||||||
conn.setConnectTimeout(10000);
|
|
||||||
conn.setReadTimeout(5000);
|
|
||||||
|
|
||||||
if(conn.getResponseCode() < 300){
|
|
||||||
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
|
||||||
while((line = reader.readLine()) != null){
|
|
||||||
responseContent.append(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
json = new JSONObject(responseContent.toString());
|
|
||||||
if(json.has("error")){
|
|
||||||
throw new Exception();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}catch(Exception e){
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getDp(int value){
|
private int getDp(int value){
|
||||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, getResources().getDisplayMetrics());
|
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, getResources().getDisplayMetrics());
|
||||||
}
|
}
|
||||||
|
|
@ -521,14 +411,18 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
|
|
||||||
// TITLE ----------------------------------
|
// TITLE ----------------------------------
|
||||||
TextView videoTitle = new TextView(getContext());
|
TextView videoTitle = new TextView(getContext());
|
||||||
videoTitle.setLayoutParams(new RelativeLayout.LayoutParams(getDp(300), getDp(100)));
|
videoTitle.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, getDp(100)));
|
||||||
int padding = getDp(20);
|
int padding = getDp(20);
|
||||||
videoTitle.setPadding(padding, padding, padding, padding);
|
videoTitle.setPadding(padding, padding, padding, padding);
|
||||||
String title = video.getTitle();
|
String title = video.getTitle();
|
||||||
|
|
||||||
|
title = title.replace("&", "&").replace(""", "\"");
|
||||||
|
|
||||||
|
|
||||||
if(title.length() > 50){
|
if(title.length() > 50){
|
||||||
title = title.substring(0, 40) + "...";
|
title = title.substring(0, 40) + "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
videoTitle.setText(title);
|
videoTitle.setText(title);
|
||||||
videoTitle.setTextSize(getSp(5));
|
videoTitle.setTextSize(getSp(5));
|
||||||
videoTitle.setTextColor(ContextCompat.getColor(requireContext(), R.color.white));
|
videoTitle.setTextColor(ContextCompat.getColor(requireContext(), R.color.white));
|
||||||
|
|
@ -620,7 +514,6 @@ public class HomeFragment extends Fragment implements View.OnClickListener{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
//do what you want to do when button is clicked
|
//do what you want to do when button is clicked
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,9 @@ public class MainActivity extends AppCompatActivity{
|
||||||
binding.bottomNavigationView.setOnItemSelectedListener(item -> {
|
binding.bottomNavigationView.setOnItemSelectedListener(item -> {
|
||||||
switch(item.getItemId()){
|
switch(item.getItemId()){
|
||||||
case R.id.home:
|
case R.id.home:
|
||||||
|
if(lastFragment == homeFragment){
|
||||||
|
homeFragment.scrollToTop();
|
||||||
|
}
|
||||||
replaceFragment(homeFragment);
|
replaceFragment(homeFragment);
|
||||||
break;
|
break;
|
||||||
case R.id.history:
|
case R.id.history:
|
||||||
|
|
|
||||||
191
app/src/main/java/com/deniscerri/ytdl/api/YoutubeAPIManager.java
Normal file
191
app/src/main/java/com/deniscerri/ytdl/api/YoutubeAPIManager.java
Normal file
|
|
@ -0,0 +1,191 @@
|
||||||
|
package com.deniscerri.ytdl.api;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.deniscerri.ytdl.database.Video;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.sql.Array;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
|
||||||
|
public class YoutubeAPIManager {
|
||||||
|
private static final String TAG = "API MANAGER";
|
||||||
|
private ArrayList<Video> videos;
|
||||||
|
private String key;
|
||||||
|
Properties properties = new Properties();
|
||||||
|
|
||||||
|
public YoutubeAPIManager(Context context) {
|
||||||
|
AssetManager assetManager = context.getAssets();
|
||||||
|
try{
|
||||||
|
InputStream inputStream = assetManager.open("config.properties");
|
||||||
|
properties.load(inputStream);
|
||||||
|
key = properties.getProperty("ytAPI");
|
||||||
|
}catch(Exception ignored){
|
||||||
|
Toast.makeText(context, "Couldn't find API Key for the request", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
videos = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Video> search(String query) throws JSONException{
|
||||||
|
JSONObject res = genericRequest("https://youtube.googleapis.com/youtube/v3/search?part=snippet&q="+query+"&maxResults=25®ionCode=US&key="+key);
|
||||||
|
JSONArray dataArray = res.getJSONArray("items");
|
||||||
|
for(int i = 0; i < dataArray.length(); i++){
|
||||||
|
JSONObject element = dataArray.getJSONObject(i);
|
||||||
|
JSONObject snippet = element.getJSONObject("snippet");
|
||||||
|
if(element.getJSONObject("id").getString("kind").equals("youtube#video")){
|
||||||
|
snippet.put("videoID", element.getJSONObject("id").getString("videoId"));
|
||||||
|
snippet = fixThumbnail(snippet);
|
||||||
|
Video v = createVideofromJSON(snippet);
|
||||||
|
v.setTitle(v.getTitle().replace("&", "&").replace(""", "\""));
|
||||||
|
v.setAuthor(v.getAuthor().replace("&", "&").replace(""", "\""));
|
||||||
|
videos.add(createVideofromJSON(snippet));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return videos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Video> getPlaylist(String id, String nextPageToken) throws JSONException{
|
||||||
|
String url = "https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet&pageToken="+nextPageToken+"&maxResults=50&playlistId="+id+"&key="+key;
|
||||||
|
JSONObject res = genericRequest(url);
|
||||||
|
JSONArray dataArray = res.getJSONArray("items");
|
||||||
|
|
||||||
|
for(int i = 0; i < dataArray.length(); i++){
|
||||||
|
JSONObject element = dataArray.getJSONObject(i);
|
||||||
|
JSONObject snippet = element.getJSONObject("snippet");
|
||||||
|
if(snippet.getJSONObject("resourceId").getString("kind").equals("youtube#video")){
|
||||||
|
snippet.put("videoID", snippet.getJSONObject("resourceId").getString("videoId"));
|
||||||
|
snippet = fixThumbnail(snippet);
|
||||||
|
Video v = createVideofromJSON(snippet);
|
||||||
|
|
||||||
|
if(v.getThumb().isEmpty()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.setIsPlaylistItem(1);
|
||||||
|
v.setTitle(v.getTitle().replace("&", "&").replace(""", "\""));
|
||||||
|
v.setAuthor(v.getAuthor().replace("&", "&").replace(""", "\""));
|
||||||
|
|
||||||
|
videos.add(v);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String next = res.optString("nextPageToken");
|
||||||
|
if(next != ""){
|
||||||
|
ArrayList<Video> nextPage = getPlaylist(id,next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return videos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Video getVideo(String id) throws JSONException {
|
||||||
|
JSONObject res = genericRequest("https://youtube.googleapis.com/youtube/v3/videos?part=snippet&id="+id+"&key="+key);
|
||||||
|
res = res.getJSONObject("snippet");
|
||||||
|
res.put("videoID", res.getString("id"));
|
||||||
|
res = fixThumbnail(res);
|
||||||
|
|
||||||
|
Video v = createVideofromJSON(res);
|
||||||
|
v.setTitle(v.getTitle().replace("&", "&").replace(""", "\""));
|
||||||
|
v.setAuthor(v.getAuthor().replace("&", "&").replace(""", "\""));
|
||||||
|
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Video createVideofromJSON(JSONObject obj){
|
||||||
|
Video video = null;
|
||||||
|
try{
|
||||||
|
String id = obj.getString("videoID");
|
||||||
|
String title = obj.getString("title");
|
||||||
|
String author = obj.getString("channelTitle");
|
||||||
|
String thumb = obj.getString("thumb");
|
||||||
|
|
||||||
|
video = new Video(id, title, author, thumb);
|
||||||
|
}catch(Exception ignored){}
|
||||||
|
|
||||||
|
return video;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject genericRequest(String url){
|
||||||
|
Log.e(TAG, url);
|
||||||
|
|
||||||
|
BufferedReader reader;
|
||||||
|
String line;
|
||||||
|
StringBuilder responseContent = new StringBuilder();
|
||||||
|
HttpURLConnection conn;
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
|
||||||
|
try{
|
||||||
|
URL req = new URL(url);
|
||||||
|
conn = (HttpURLConnection) req.openConnection();
|
||||||
|
|
||||||
|
conn.setRequestMethod("GET");
|
||||||
|
conn.setConnectTimeout(10000);
|
||||||
|
conn.setReadTimeout(5000);
|
||||||
|
|
||||||
|
if(conn.getResponseCode() < 300){
|
||||||
|
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||||
|
while((line = reader.readLine()) != null){
|
||||||
|
responseContent.append(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
json = new JSONObject(responseContent.toString());
|
||||||
|
if(json.has("error")){
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
Log.e(TAG, e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject fixThumbnail(JSONObject o){
|
||||||
|
String imageURL = "";
|
||||||
|
try{
|
||||||
|
JSONObject thumbs = o.getJSONObject("thumbnails");
|
||||||
|
imageURL = thumbs.getJSONObject("maxres").getString("url");
|
||||||
|
}catch(Exception e){
|
||||||
|
try {
|
||||||
|
JSONObject thumbs = o.getJSONObject("thumbnails");
|
||||||
|
imageURL = thumbs.getJSONObject("high").getString("url");
|
||||||
|
}catch(Exception u){
|
||||||
|
try{
|
||||||
|
JSONObject thumbs = o.getJSONObject("thumbnails");
|
||||||
|
imageURL = thumbs.getJSONObject("default").getString("url");
|
||||||
|
}catch(Exception ignored){}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
o.put("thumb", imageURL);
|
||||||
|
}catch(Exception ignored){}
|
||||||
|
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
5
app/src/main/res/drawable/round_corner.xml
Normal file
5
app/src/main/res/drawable/round_corner.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="#33DDFF" />
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
</shape>
|
||||||
|
|
@ -14,6 +14,10 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/linearLayout1"
|
android:id="@+id/linearLayout1"
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp"
|
||||||
android:orientation="vertical" />
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
Loading…
Reference in a new issue