diff --git a/app/src/main/java/me/harshithgoka/youtubedl/Format.java b/app/src/main/java/me/harshithgoka/youtubedl/Format.java index 3f79ad1..211a1d0 100644 --- a/app/src/main/java/me/harshithgoka/youtubedl/Format.java +++ b/app/src/main/java/me/harshithgoka/youtubedl/Format.java @@ -1,7 +1,17 @@ package me.harshithgoka.youtubedl; +import android.app.DownloadManager; +import android.content.ContentProvider; +import android.content.Context; +import android.net.Uri; +import android.os.Environment; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; + +import java.io.File; + +import me.harshithgoka.youtubedl.Utils.Utils; /** * Created by harshithgoka on 12/16/2017 AD. @@ -14,6 +24,9 @@ public class Format implements Parcelable { public String quality; public String type; + public String extension; + public String description; + public Format (String title) { this.title = title; } @@ -23,6 +36,10 @@ protected Format(Parcel in) { url = in.readString(); quality = in.readString(); type = in.readString(); + + extension = Utils.getExtension(this); + title = Utils.getTitle(this); + description = Utils.getDescription(this); } public static final Creator CREATOR = new Creator() { @@ -49,4 +66,28 @@ public void writeToParcel(Parcel parcel, int i) { parcel.writeString(quality); parcel.writeString(type); } + + public void download (Context context) { + String extension = Utils.getExtension(this); + String name = title; + Log.d("Filename", title + "." + extension); + + DownloadManager.Request req = new DownloadManager.Request(Uri.parse(url)); + req.setTitle(name) + .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, File.separator + name + "." + extension) + .allowScanningByMediaScanner(); + req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + + DownloadManager dm =null; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + File[] files = context.getExternalMediaDirs(); + if (files.length > 0) { + Log.d(files[0].getAbsolutePath(), files.length > 1 ? files[1].getAbsolutePath(): ""); + } + dm = context.getSystemService(DownloadManager.class); + }else{ + dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); + } + dm.enqueue(req); + } } \ No newline at end of file diff --git a/app/src/main/java/me/harshithgoka/youtubedl/FormatAdapter.java b/app/src/main/java/me/harshithgoka/youtubedl/FormatAdapter.java index 95a2ed4..ecd9763 100644 --- a/app/src/main/java/me/harshithgoka/youtubedl/FormatAdapter.java +++ b/app/src/main/java/me/harshithgoka/youtubedl/FormatAdapter.java @@ -23,9 +23,8 @@ public class FormatAdapter extends RecyclerView.Adapter formats; Context context; - class MyViewHolder extends RecyclerView.ViewHolder { + class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView quality, type, itag, url; - public View parentView; public MyViewHolder(View itemView) { super(itemView); @@ -33,14 +32,25 @@ public MyViewHolder(View itemView) { type = itemView.findViewById(R.id.format_type); itag = itemView.findViewById(R.id.format_itag); url = itemView.findViewById(R.id.format_url); - parentView = itemView; + } + + @Override + public void onClick(View view) { + String finalurl = ((TextView) view.findViewById(R.id.format_url)).getText().toString(); + + ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + assert clipboard != null; + ClipData clip = ClipData.newRawUri("DownloadURL", Uri.parse(finalurl)); + clipboard.setPrimaryClip(clip); + + Toast.makeText(context, String.format("(%s) Quality link copied to Clipboard", ((TextView) view.findViewById(R.id.format_quality)).getText().toString()), Toast.LENGTH_SHORT).show(); + + formats.get(getLayoutPosition()).download(context); } } public FormatAdapter( Context context, List formats ) { - this.formats = new ArrayList<>(); - this.formats.addAll(formats); - + this.formats = formats; this.context = context; } @@ -60,30 +70,16 @@ public void onBindViewHolder(final FormatAdapter.MyViewHolder holder, int positi else holder.quality.setText("Quality not defined"); if (format.type != null) - holder.type.setText(format.type); + holder.type.setText(format.title); else holder.type.setText("Type not defined"); if (format.url != null) - holder.url.setText(format.url); + holder.url.setText(format.description); else holder.url.setText("URL not found"); holder.itag.setText(format.itag + ""); - - holder.parentView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - String finalurl = ((TextView) view.findViewById(R.id.format_url)).getText().toString(); - - ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - assert clipboard != null; - ClipData clip = ClipData.newRawUri("DownloadURL", Uri.parse(finalurl)); - clipboard.setPrimaryClip(clip); - - Toast.makeText(context, String.format("(%s) Quality link copied to Clipboard", ((TextView) view.findViewById(R.id.format_quality)).getText().toString()), Toast.LENGTH_SHORT).show(); - } - }); } @Override diff --git a/app/src/main/java/me/harshithgoka/youtubedl/MainActivity.java b/app/src/main/java/me/harshithgoka/youtubedl/MainActivity.java index 526b2ff..d7c12c5 100644 --- a/app/src/main/java/me/harshithgoka/youtubedl/MainActivity.java +++ b/app/src/main/java/me/harshithgoka/youtubedl/MainActivity.java @@ -24,15 +24,17 @@ import android.widget.TextView; import android.widget.Toast; +import com.google.android.material.bottomappbar.BottomAppBar; +import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.snackbar.Snackbar; -import com.google.code.regexp.Matcher; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import me.harshithgoka.youtubedl.Utils.Utils; @@ -45,12 +47,18 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe FloatingActionButton btnCopy; Button btnDownload, btnAllFormats; - List curr_formats; + List formats; Extractor extractor; Pattern youtubeUrlPattern; + RecyclerView recyclerView; + FormatAdapter adapter; + LinearLayoutManager linearLayoutManager; + + BottomSheetBehavior bottomSheetBehavior; + @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { @@ -95,11 +103,29 @@ protected void onCreate(Bundle savedInstanceState) { urlEdit = (EditText) findViewById(R.id.url); - curr_formats = new ArrayList<>(); + formats = new ArrayList<>(); extractor = new Extractor(); youtubeUrlPattern = Pattern.compile(extractor._VALID_URL); + bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottom_sheet)); + bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); + + recyclerView = findViewById(R.id.recycler_view); + adapter = new FormatAdapter(getApplicationContext(), formats); + recyclerView.setAdapter(adapter); + linearLayoutManager = new LinearLayoutManager(getApplicationContext()); + recyclerView.setLayoutManager(linearLayoutManager); + + BottomAppBar bar = (BottomAppBar) findViewById(R.id.bar); + bar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // Handle the navigation click by showing a BottomDrawer etc. + bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); + } + }); + // ATTENTION: This was auto-generated to handle app links. Intent appLinkIntent = getIntent(); String appLinkAction = appLinkIntent.getAction(); @@ -163,13 +189,13 @@ public void pasteFromClipboard(View button) { if (clipboard.hasPrimaryClip()) { ClipData clipData = clipboard.getPrimaryClip(); Uri uri; - String url; + CharSequence url; if ( clipData.getItemCount() > 0 ) { if ((uri = clipData.getItemAt(0).getUri()) != null) { urlEdit.setText(uri.toString()); } - else if ((url = clipData.getItemAt(0).getText().toString()) != null ) { - urlEdit.setText(url); + else if ((url = clipData.getItemAt(0).getText()) != null ) { + urlEdit.setText(url.toString()); } startPoint(button); } @@ -177,9 +203,9 @@ else if ((url = clipData.getItemAt(0).getText().toString()) != null ) { } public void showAllFormats(View view) { - if (curr_formats.size() > 0) { + if (formats.size() > 0) { Intent intent = new Intent(getApplicationContext(), FormatsActivity.class); - intent.putParcelableArrayListExtra(FormatsActivity.FORMATS, (ArrayList) curr_formats); + intent.putParcelableArrayListExtra(FormatsActivity.FORMATS, (ArrayList) formats); startActivity(intent); } } @@ -217,33 +243,13 @@ protected List doInBackground(String... strings) { return ytextractor.getFormats(you_url); } - public void download (String url, String name, String extension) { - - DownloadManager.Request req = new DownloadManager.Request(Uri.parse(url)); - req.setTitle(name) - .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, File.separator + name + "." + extension) - .allowScanningByMediaScanner(); - req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); - - DownloadManager dm =null; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { - File[] files = context.getExternalMediaDirs(); - if (files.length > 0) { - Log.d(files[0].getAbsolutePath(), files.length > 1 ? files[1].getAbsolutePath(): ""); - } - dm = context.getSystemService(DownloadManager.class); - }else{ - dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); - } - dm.enqueue(req); - } - @Override protected void onPostExecute(List formats) { if (formats != null) { if (formats.size() > 0) { - curr_formats.clear(); - curr_formats.addAll(formats); + MainActivity.this.formats.clear(); + MainActivity.this.formats.addAll(formats); + MainActivity.this.adapter.notifyDataSetChanged(); String finalurl = formats.get(0).url; println(finalurl); @@ -254,11 +260,6 @@ protected void onPostExecute(List formats) { clipboard.setPrimaryClip(clip); Toast.makeText(getApplicationContext(), String.format("Best quality link (%s) copied to Clipboard", formats.get(0).quality), Toast.LENGTH_SHORT).show(); - String extension = ""; - Format format = formats.get(0); - download(finalurl, format.title, Utils.getExtension(format)); - Log.d("Filename", format.title + "." + Utils.getExtension(format)); - } else { println("No. of formats: 0"); diff --git a/app/src/main/java/me/harshithgoka/youtubedl/Utils/Utils.java b/app/src/main/java/me/harshithgoka/youtubedl/Utils/Utils.java index 9fdb3ca..9ab672c 100644 --- a/app/src/main/java/me/harshithgoka/youtubedl/Utils/Utils.java +++ b/app/src/main/java/me/harshithgoka/youtubedl/Utils/Utils.java @@ -606,5 +606,55 @@ public static String getExtension (Format format) { return ""; } + public static String getTitle (Format format) { + String ret = ""; + if (formats != null) { + try { + JSONObject fmt = (JSONObject) formats.get(format.itag + ""); + boolean audio = fmt.has("acodec"); + boolean video = fmt.has("vcodec"); + + if ( audio && video) { + ret = "Video + Audio "; + + if (fmt.has("height")) { + ret += fmt.getInt("height") + "p"; + } + + if (fmt.has("abr")) { + ret += fmt.getInt("abr") + "kbps audio"; + } + } + else if (video) { + ret = "Video Only "; + if (fmt.has("height")) { + ret += fmt.getInt("height") + "p"; + } + } + else if (audio) { + ret = "Audio Only "; + if (fmt.has("abr")) { + ret += fmt.getInt("abr") + "kbps"; + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + return ret; + } + + public static String getDescription(Format format) { + if (formats != null) { + try { + JSONObject fmt = (JSONObject) formats.get(format.itag + ""); + return fmt.getString("ext"); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return ""; + } + } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 5d2f1c3..b9e5aad 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -6,77 +6,79 @@ android:layout_width="match_parent" android:layout_height="match_parent" tools:context="me.harshithgoka.youtubedl.MainActivity"> - - + - + - + - - + + - + - - + + + + diff --git a/app/src/main/res/layout/formats_layout.xml b/app/src/main/res/layout/formats_layout.xml new file mode 100644 index 0000000..a470abe --- /dev/null +++ b/app/src/main/res/layout/formats_layout.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 0197a99..5154225 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,4 +3,6 @@ #6202ee #6000dd #FF4081 + #FFFFFF + #000000