new settings features
implemented alot of sponsorblock and ytdlp features as settings moved settings fragment to a different activity added boilerplate bottom nav pages that will be added later
This commit is contained in:
parent
a061c78ae0
commit
d931edad72
30 changed files with 714 additions and 264 deletions
|
|
@ -23,7 +23,7 @@
|
|||
<PersistentState>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/delete_sweep/baseline_delete_sweep_24.xml" />
|
||||
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/arrow_downward/baseline_arrow_downward_24.xml" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
|
|
@ -33,9 +33,8 @@
|
|||
</option>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="assetSourceType" value="FILE" />
|
||||
<entry key="color" value="00a6ff" />
|
||||
<entry key="outputName" value="ic_no_results" />
|
||||
<entry key="outputName" value="ic_down" />
|
||||
<entry key="sourceFile" value="C:\Users\denis\Desktop\eaKdW401.svg" />
|
||||
</map>
|
||||
</option>
|
||||
|
|
|
|||
|
|
@ -36,25 +36,34 @@
|
|||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/xml/root_preferences.xml" value="0.33" />
|
||||
<entry key="..\:/Users/denis/Desktop/ytdlnis/ytdlnis/app/src/main/res/xml/shortcuts.xml" value="0.13852073535699017" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_announcement.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_back.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_chapters.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_cloud_download.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_code.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_delete_all.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_down.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_download.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_go_up.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_home.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_image.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_lines.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_more.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_music.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_music_downloaded.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_no_results.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_refresh.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_search.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_subtitles.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_update.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_update_app.xml" value="0.109" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_video.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/drawable/ic_video_downloaded.xml" value="0.1275" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/activity_main.xml" value="0.18" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/activity_settings.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/download_all_card.xml" value="0.3375" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/empty_history_hint.xml" value="0.2" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_history.xml" value="0.2" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_home.xml" value="0.1" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_home.xml" value="0.2" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/fragment_settings.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/history_bottom_sheet.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/history_card.xml" value="0.1" />
|
||||
|
|
@ -65,9 +74,14 @@
|
|||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/layout/search_result.xml" value="0.33" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/bottom_nav_menu.xml" value="0.20555555555555555" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/history_menu.xml" value="0.17" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/main_menu.xml" value="0.33" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/main_menu.xml" value="0.25" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/menu/settings_menu.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/root_preferences.xml" value="0.18" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/about_preferences.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/display_preferences.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/download_preferences.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/notification_preferences.xml" value="0.16875" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/root_preferences.xml" value="0.25" />
|
||||
<entry key="..\:/Users/denis/Documents/GitHub/ytdlnis/app/src/main/res/xml/update_preferences.xml" value="0.16875" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ dependencies {
|
|||
implementation 'androidx.core:core:1.8.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation 'androidx.preference:preference:1.2.0'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.5.2'
|
||||
implementation 'androidx.navigation:navigation-ui:2.5.2'
|
||||
testImplementation "junit:junit:$junitVer"
|
||||
androidTestImplementation "androidx.test.ext:junit:$androidJunitVer"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVer"
|
||||
|
|
@ -78,4 +80,5 @@ dependencies {
|
|||
|
||||
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
|
||||
implementation 'com.facebook.shimmer:shimmer:0.5.0'
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@
|
|||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".page.settings.SettingsActivity"
|
||||
android:parentActivityName=".MainActivity"
|
||||
/>
|
||||
<service
|
||||
android:name=".DownloaderService"
|
||||
android:enabled="true"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import android.app.Application;
|
|||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.devbrackets.android.exomedia.BuildConfig;
|
||||
import com.google.android.material.color.DynamicColors;
|
||||
import com.yausername.ffmpeg.FFmpeg;
|
||||
import com.yausername.youtubedl_android.YoutubeDL;
|
||||
|
|
@ -17,12 +16,12 @@ import io.reactivex.observers.DisposableCompletableObserver;
|
|||
import io.reactivex.plugins.RxJavaPlugins;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import com.deniscerri.ytdl.util.NotificationUtil;
|
||||
|
||||
public class App extends Application {
|
||||
|
||||
private static final String TAG = "App";
|
||||
public static NotificationUtil notificationUtil;
|
||||
public static String arch = System.getProperty("os.arch");
|
||||
public static String versionName = BuildConfig.VERSION_NAME;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.deniscerri.ytdl.service;
|
||||
package com.deniscerri.ytdl;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
|
|
@ -9,10 +9,6 @@ import android.os.IBinder;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import com.deniscerri.ytdl.App;
|
||||
import com.deniscerri.ytdl.MainActivity;
|
||||
import com.deniscerri.ytdl.util.NotificationUtil;
|
||||
|
||||
public class DownloaderService extends Service {
|
||||
|
||||
private LocalBinder binder = new LocalBinder();
|
||||
|
|
@ -4,7 +4,6 @@ import android.content.ComponentName;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
|
@ -14,8 +13,6 @@ import androidx.fragment.app.FragmentManager;
|
|||
import com.deniscerri.ytdl.databinding.ActivityMainBinding;
|
||||
import com.deniscerri.ytdl.page.HistoryFragment;
|
||||
import com.deniscerri.ytdl.page.HomeFragment;
|
||||
import com.deniscerri.ytdl.page.SettingsFragment;
|
||||
import com.deniscerri.ytdl.service.DownloaderService;
|
||||
|
||||
|
||||
public class MainActivity extends AppCompatActivity{
|
||||
|
|
@ -27,7 +24,6 @@ public class MainActivity extends AppCompatActivity{
|
|||
|
||||
private HomeFragment homeFragment;
|
||||
private HistoryFragment historyFragment;
|
||||
private SettingsFragment settingsFragment;
|
||||
private Fragment lastFragment;
|
||||
private FragmentManager fm;
|
||||
|
||||
|
|
@ -63,14 +59,11 @@ public class MainActivity extends AppCompatActivity{
|
|||
|
||||
homeFragment = new HomeFragment();
|
||||
historyFragment = new HistoryFragment();
|
||||
settingsFragment = new SettingsFragment();
|
||||
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.frame_layout, homeFragment)
|
||||
.add(R.id.frame_layout, historyFragment)
|
||||
.add(R.id.frame_layout, settingsFragment)
|
||||
.hide(historyFragment)
|
||||
.hide(settingsFragment)
|
||||
.commit();
|
||||
|
||||
lastFragment = homeFragment;
|
||||
|
|
@ -93,11 +86,6 @@ public class MainActivity extends AppCompatActivity{
|
|||
}
|
||||
replaceFragment(historyFragment);
|
||||
break;
|
||||
case R.id.settings:
|
||||
this.setTitle(getString(R.string.settings));;
|
||||
replaceFragment(settingsFragment);
|
||||
break;
|
||||
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
|
@ -119,15 +107,12 @@ public class MainActivity extends AppCompatActivity{
|
|||
|
||||
homeFragment = new HomeFragment();
|
||||
historyFragment = new HistoryFragment();
|
||||
settingsFragment = new SettingsFragment();
|
||||
|
||||
homeFragment.handleIntent(intent);
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.frame_layout, homeFragment)
|
||||
.add(R.id.frame_layout, historyFragment)
|
||||
.add(R.id.frame_layout, settingsFragment)
|
||||
.hide(historyFragment)
|
||||
.hide(settingsFragment)
|
||||
.commit();
|
||||
|
||||
lastFragment = homeFragment;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.deniscerri.ytdl.util;
|
||||
package com.deniscerri.ytdl;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
|
|
@ -62,7 +62,7 @@ public class NotificationUtil {
|
|||
|
||||
public void updateDownloadNotification(int id, String desc, int progress, int queue, String title){
|
||||
String contentText = "";
|
||||
if (queue > 0) contentText += queue + " items left\n";
|
||||
if (queue > 1) contentText += queue + " items left\n";
|
||||
contentText += desc.replaceAll("\\[.*?\\]", "");
|
||||
|
||||
notificationBuilder.setProgress(100, (int) progress, false)
|
||||
|
|
@ -39,7 +39,8 @@ import com.deniscerri.ytdl.adapter.HomeRecyclerViewAdapter;
|
|||
import com.deniscerri.ytdl.api.YoutubeAPIManager;
|
||||
import com.deniscerri.ytdl.database.DBManager;
|
||||
import com.deniscerri.ytdl.database.Video;
|
||||
import com.deniscerri.ytdl.util.NotificationUtil;
|
||||
import com.deniscerri.ytdl.NotificationUtil;
|
||||
import com.deniscerri.ytdl.page.settings.SettingsActivity;
|
||||
import com.facebook.shimmer.ShimmerFrameLayout;
|
||||
import com.google.android.material.appbar.AppBarLayout;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
|
|
@ -249,6 +250,10 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
case R.id.refresh_results:
|
||||
recyclerView.removeAllViews();
|
||||
initCards();
|
||||
return true;
|
||||
case R.id.open_settings:
|
||||
Intent intent = new Intent(context, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
|
@ -445,7 +450,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
}
|
||||
|
||||
try {
|
||||
video = videos.remove();
|
||||
video = videos.peek();
|
||||
} catch (Exception e) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -466,24 +471,57 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
|
||||
MaterialButton clickedButton = null;
|
||||
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
|
||||
int concurrentFragments = sharedPreferences.getInt("concurrent_fragments", 1);
|
||||
request.addOption("-N", concurrentFragments);
|
||||
|
||||
String limitRate = sharedPreferences.getString("limit_rate", "");
|
||||
if(!limitRate.equals("")){
|
||||
request.addOption("-r", limitRate);
|
||||
}
|
||||
|
||||
boolean writeThumbnail = sharedPreferences.getBoolean("write_thumbnail", false);
|
||||
if(writeThumbnail){
|
||||
request.addOption("--write-thumbnail");
|
||||
}
|
||||
|
||||
if (type.equals("mp3")) {
|
||||
request.addOption("--embed-thumbnail");
|
||||
request.addOption("--sponsorblock-remove", "all");
|
||||
boolean embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false);
|
||||
if(embedThumb){
|
||||
request.addOption("--embed-thumbnail");
|
||||
}
|
||||
boolean removeNonMusic = sharedPreferences.getBoolean("remove_non_music", false);
|
||||
if(removeNonMusic){
|
||||
request.addOption("--sponsorblock-remove", "all");
|
||||
}
|
||||
request.addOption("--postprocessor-args", "-write_id3v1 1 -id3v2_version 3");
|
||||
request.addOption("--add-metadata");
|
||||
request.addOption("--no-mtime");
|
||||
request.addOption("-x");
|
||||
request.addOption("--audio-format", "mp3");
|
||||
String format = sharedPreferences.getString("audio_format", "");
|
||||
request.addOption("--audio-format", format);
|
||||
|
||||
clickedButton = recyclerView.findViewWithTag(id + "##mp3");
|
||||
} else if (type.equals("mp4")) {
|
||||
request.addOption("--embed-thumbnail");
|
||||
request.addOption("--sponsorblock-mark", "all");
|
||||
request.addOption("--embed-subs", "");
|
||||
request.addOption("-f", "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best");
|
||||
boolean embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false);
|
||||
if(embedThumb){
|
||||
request.addOption("--embed-thumbnail");
|
||||
}
|
||||
boolean addChapters = sharedPreferences.getBoolean("add_chapters", false);
|
||||
if(addChapters){
|
||||
request.addOption("--sponsorblock-mark", "all");
|
||||
}
|
||||
boolean embedSubs = sharedPreferences.getBoolean("embed_subtitles", false);
|
||||
if(embedSubs){
|
||||
request.addOption("--embed-subs", "");
|
||||
}
|
||||
String format = sharedPreferences.getString("video_format", "");
|
||||
request.addOption("-f", "bestvideo[ext="+format+"]+bestaudio[ext=m4a]/best[ext="+format+"]/best");
|
||||
|
||||
clickedButton = recyclerView.findViewWithTag(id + "##mp4");
|
||||
}
|
||||
|
||||
request.addOption("-o", youtubeDLDir.getAbsolutePath() + "/%(title)s.%(ext)s");
|
||||
|
||||
progressBar = fragmentView.findViewWithTag(id + "##progress");
|
||||
|
|
@ -524,6 +562,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
MediaScannerConnection.scanFile(context, new String[]{youtubeDLDir.getAbsolutePath()}, null, null);
|
||||
|
||||
// SCAN NEXT IN QUEUE
|
||||
videos.remove();
|
||||
startDownload(videos);
|
||||
}, e -> {
|
||||
if (BuildConfig.DEBUG) Log.e(TAG, getString(R.string.failed_download), e);
|
||||
|
|
@ -535,6 +574,7 @@ public class HomeFragment extends Fragment implements HomeRecyclerViewAdapter.On
|
|||
downloading = false;
|
||||
|
||||
// SCAN NEXT IN QUEUE
|
||||
videos.remove();
|
||||
startDownload(videos);
|
||||
});
|
||||
compositeDisposable.add(disposable);
|
||||
|
|
|
|||
|
|
@ -1,184 +0,0 @@
|
|||
package com.deniscerri.ytdl.page;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResult;
|
||||
import androidx.activity.result.ActivityResultCallback;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
|
||||
import com.deniscerri.ytdl.BuildConfig;
|
||||
import com.deniscerri.ytdl.R;
|
||||
import com.yausername.youtubedl_android.YoutubeDL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class SettingsFragment extends PreferenceFragmentCompat {
|
||||
|
||||
Preference musicPath;
|
||||
Preference videoPath;
|
||||
Preference update;
|
||||
public static final int MUSIC_PATH_CODE = 33333;
|
||||
public static final int VIDEO_PATH_CODE = 55555;
|
||||
public static boolean updating;
|
||||
|
||||
private static final String TAG = "SettingsFragment";
|
||||
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
setPreferencesFromResource(R.xml.root_preferences, rootKey);
|
||||
|
||||
musicPath = findPreference("music_path");
|
||||
videoPath = findPreference("video_path");
|
||||
|
||||
SharedPreferences preferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
String music_path = preferences.getString("music_path", "");
|
||||
String video_path = preferences.getString("video_path", "");
|
||||
|
||||
if(music_path.isEmpty()){
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putString("music_path", "/storage/emulated/0/Music/");
|
||||
editor.apply();
|
||||
music_path = preferences.getString("music_path", "");
|
||||
}
|
||||
musicPath.setSummary(music_path);
|
||||
musicPath.setOnPreferenceClickListener(preference -> {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
musicPathResultLauncher.launch(intent);
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
if(video_path.isEmpty()){
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putString("video_path", "/storage/emulated/0/Movies/");
|
||||
editor.apply();
|
||||
video_path = preferences.getString("video_path", "");
|
||||
}
|
||||
videoPath.setSummary(video_path);
|
||||
videoPath.setOnPreferenceClickListener(preference -> {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
videoPathResultLauncher.launch(intent);
|
||||
return true;
|
||||
});
|
||||
|
||||
update = findPreference("update");
|
||||
if(update != null){
|
||||
update.setOnPreferenceClickListener(preference -> {
|
||||
updateYoutubeDL();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
ActivityResultLauncher<Intent> musicPathResultLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
new ActivityResultCallback<ActivityResult>() {
|
||||
@Override
|
||||
public void onActivityResult(ActivityResult result) {
|
||||
if (result.getResultCode() == Activity.RESULT_OK) {
|
||||
changePath(musicPath, result.getData(), MUSIC_PATH_CODE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ActivityResultLauncher<Intent> videoPathResultLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
new ActivityResultCallback<ActivityResult>() {
|
||||
@Override
|
||||
public void onActivityResult(ActivityResult result) {
|
||||
if (result.getResultCode() == Activity.RESULT_OK) {
|
||||
changePath(videoPath, result.getData(), VIDEO_PATH_CODE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
public void changePath(Preference p, Intent data, int requestCode){
|
||||
Log.e("TEST", data.toUri(0));
|
||||
String dataValue = data.getData().toString();
|
||||
dataValue = dataValue.replace("content://com.android.externalstorage.documents/tree/", "");
|
||||
dataValue = dataValue.replaceAll("%3A", "/");
|
||||
|
||||
try{
|
||||
dataValue = java.net.URLDecoder.decode(dataValue, StandardCharsets.UTF_8.name());
|
||||
}catch(Exception ignored){}
|
||||
|
||||
String[] pieces = dataValue.split("/");
|
||||
|
||||
int index = 1;
|
||||
StringBuilder path = new StringBuilder("/storage/");
|
||||
if(pieces[0].equals("primary")){
|
||||
path.append("emulated/0/");
|
||||
}else{
|
||||
path.append(pieces[0]).append("/");
|
||||
}
|
||||
|
||||
for(int i = index; i < pieces.length; i++){
|
||||
path.append(pieces[i]).append("/");
|
||||
}
|
||||
|
||||
Log.e("TEST", path.toString());
|
||||
p.setSummary(path.toString());
|
||||
SharedPreferences sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
switch (requestCode){
|
||||
case MUSIC_PATH_CODE:
|
||||
editor.putString("music_path", path.toString());
|
||||
break;
|
||||
case VIDEO_PATH_CODE:
|
||||
editor.putString("video_path", path.toString());
|
||||
break;
|
||||
}
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private void updateYoutubeDL() {
|
||||
if (updating) {
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_already_updating), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_updating_started), Toast.LENGTH_SHORT).show();
|
||||
|
||||
updating = true;
|
||||
Disposable disposable = Observable.fromCallable(() -> YoutubeDL.getInstance().updateYoutubeDL(getContext()))
|
||||
.subscribeOn(Schedulers.newThread())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(status -> {
|
||||
switch (status) {
|
||||
case DONE:
|
||||
Toast.makeText(getContext(), getString(R.string.ytld_update_success), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case ALREADY_UP_TO_DATE:
|
||||
Toast.makeText(getContext(), getString(R.string.you_are_in_latest_version), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
default:
|
||||
Toast.makeText(getContext(), status.toString(), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
updating = false;
|
||||
}, e -> {
|
||||
if(BuildConfig.DEBUG) Log.e(TAG, getString(R.string.ytdl_update_failed), e);
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_update_failed), Toast.LENGTH_LONG).show();
|
||||
updating = false;
|
||||
});
|
||||
compositeDisposable.add(disposable);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.deniscerri.ytdl.page.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
|
||||
import com.deniscerri.ytdl.R;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
|
||||
|
||||
public class SettingsActivity extends AppCompatActivity{
|
||||
|
||||
private FragmentManager fm;
|
||||
private MaterialToolbar topAppBar;
|
||||
Context context;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_settings);
|
||||
context = getBaseContext();
|
||||
topAppBar = findViewById(R.id.settings_toolbar);
|
||||
topAppBar.setNavigationOnClickListener(view -> onBackPressed());
|
||||
|
||||
fm = getSupportFragmentManager();
|
||||
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.settings_frame_layout, new SettingsFragment())
|
||||
.commit();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,341 @@
|
|||
package com.deniscerri.ytdl.page.settings;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResult;
|
||||
import androidx.activity.result.ActivityResultCallback;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.preference.EditTextPreference;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.SeekBarPreference;
|
||||
import androidx.preference.SwitchPreferenceCompat;
|
||||
import com.deniscerri.ytdl.BuildConfig;
|
||||
import com.deniscerri.ytdl.R;
|
||||
import com.yausername.youtubedl_android.YoutubeDL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class SettingsFragment extends PreferenceFragmentCompat {
|
||||
|
||||
Preference musicPath;
|
||||
Preference videoPath;
|
||||
|
||||
SeekBarPreference concurrentFragments;
|
||||
EditTextPreference limitRate;
|
||||
|
||||
SwitchPreferenceCompat removeNonMusic;
|
||||
SwitchPreferenceCompat embedSubtitles;
|
||||
SwitchPreferenceCompat embedThumbnail;
|
||||
SwitchPreferenceCompat addChapters;
|
||||
SwitchPreferenceCompat writeThumbnail;
|
||||
ListPreference audioFormat;
|
||||
ListPreference videoFormat;
|
||||
SeekBarPreference audioQuality;
|
||||
|
||||
Preference updateYTDL;
|
||||
Preference updateApp;
|
||||
|
||||
public static final int MUSIC_PATH_CODE = 33333;
|
||||
public static final int VIDEO_PATH_CODE = 55555;
|
||||
public static boolean updatingYTDL;
|
||||
public static boolean updatingApp;
|
||||
private static boolean firstRun = true;
|
||||
|
||||
private static final String TAG = "SettingsFragment";
|
||||
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
setPreferencesFromResource(R.xml.root_preferences, rootKey);
|
||||
|
||||
musicPath = findPreference("music_path");
|
||||
videoPath = findPreference("video_path");
|
||||
|
||||
concurrentFragments = findPreference("concurrent_fragments");
|
||||
limitRate = findPreference("limit_rate");
|
||||
|
||||
removeNonMusic = findPreference("remove_non_music");
|
||||
embedSubtitles = findPreference("embed_subtitles");
|
||||
embedThumbnail = findPreference("embed_thumbnail");
|
||||
addChapters = findPreference("add_chapters");
|
||||
writeThumbnail = findPreference("write_thumbnail");
|
||||
audioFormat = findPreference("audio_format");
|
||||
videoFormat = findPreference("video_format");
|
||||
audioQuality = findPreference("audio_quality");
|
||||
|
||||
|
||||
updateYTDL = findPreference("update_ytdl");
|
||||
updateApp = findPreference("update_app");
|
||||
|
||||
if(firstRun){
|
||||
initPreferences();
|
||||
}
|
||||
initListeners();
|
||||
}
|
||||
|
||||
private void initPreferences(){
|
||||
SharedPreferences preferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
|
||||
if(preferences.getString("music_path", "").isEmpty()){
|
||||
editor.putString("music_path", "/storage/emulated/0/Music/");
|
||||
}
|
||||
if(preferences.getString("video_path", "").isEmpty()){
|
||||
editor.putString("video_path", "/storage/emulated/0/Movies/");
|
||||
}
|
||||
|
||||
editor.putInt("concurrent_fragments", concurrentFragments.getValue());
|
||||
editor.putString("limit_rate", limitRate.getText());
|
||||
editor.putBoolean("remove_non_music", removeNonMusic.isChecked());
|
||||
editor.putBoolean("embed_subtitles", embedSubtitles.isChecked());
|
||||
editor.putBoolean("embed_thumbnail", embedThumbnail.isChecked());
|
||||
editor.putBoolean("add_chapters", addChapters.isChecked());
|
||||
editor.putBoolean("write_thumbnail", writeThumbnail.isChecked());
|
||||
editor.putString("audio_format", audioFormat.getValue());
|
||||
editor.putString("video_format", videoFormat.getValue());
|
||||
editor.putInt("audio_quality", audioQuality.getValue());
|
||||
|
||||
editor.apply();
|
||||
firstRun = false;
|
||||
}
|
||||
|
||||
private void initListeners(){
|
||||
SharedPreferences preferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
|
||||
musicPath.setSummary(preferences.getString("music_path", ""));
|
||||
musicPath.setOnPreferenceClickListener(preference -> {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
musicPathResultLauncher.launch(intent);
|
||||
return true;
|
||||
});
|
||||
|
||||
videoPath.setSummary(preferences.getString("video_path", ""));
|
||||
videoPath.setOnPreferenceClickListener(preference -> {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
videoPathResultLauncher.launch(intent);
|
||||
return true;
|
||||
});
|
||||
|
||||
concurrentFragments.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
int value = Integer.parseInt(String.valueOf(newValue));
|
||||
editor.putInt("concurrent_fragments", value);
|
||||
editor.apply();
|
||||
return true;
|
||||
});
|
||||
|
||||
limitRate.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
editor.putString("limit_rate", String.valueOf(newValue));
|
||||
editor.apply();
|
||||
return true;
|
||||
});
|
||||
|
||||
removeNonMusic.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean remove = (Boolean) newValue;
|
||||
editor.putBoolean("remove_non_music", remove);
|
||||
editor.apply();
|
||||
return true;
|
||||
});
|
||||
|
||||
embedSubtitles.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean embed = (Boolean) newValue;
|
||||
editor.putBoolean("embed_subtitles", embed);
|
||||
editor.apply();
|
||||
return true;
|
||||
});
|
||||
|
||||
embedThumbnail.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean embed = (Boolean) newValue;
|
||||
editor.putBoolean("embed_thumbnail", embed);
|
||||
editor.apply();
|
||||
return true;
|
||||
});
|
||||
|
||||
addChapters.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean add = (Boolean) newValue;
|
||||
editor.putBoolean("add_chapters", add);
|
||||
editor.apply();
|
||||
return true;
|
||||
});
|
||||
|
||||
writeThumbnail.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean write = (Boolean) newValue;
|
||||
editor.putBoolean("write_thumbnail", write);
|
||||
editor.apply();
|
||||
return true;
|
||||
});
|
||||
|
||||
audioFormat.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
editor.putString("audio_format", String.valueOf(newValue));
|
||||
editor.apply();
|
||||
return true;
|
||||
});
|
||||
|
||||
videoFormat.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
editor.putString("video_format", String.valueOf(newValue));
|
||||
editor.apply();
|
||||
return true;
|
||||
});
|
||||
|
||||
audioQuality.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
editor.putInt("audio_format", Integer.parseInt(String.valueOf(newValue)));
|
||||
editor.apply();
|
||||
return true;
|
||||
});
|
||||
|
||||
updateYTDL.setOnPreferenceClickListener(preference -> {
|
||||
updateYoutubeDL();
|
||||
return true;
|
||||
});
|
||||
|
||||
updateApp.setOnPreferenceClickListener(preference -> {
|
||||
updateApp();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
ActivityResultLauncher<Intent> musicPathResultLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
new ActivityResultCallback<ActivityResult>() {
|
||||
@Override
|
||||
public void onActivityResult(ActivityResult result) {
|
||||
if (result.getResultCode() == Activity.RESULT_OK) {
|
||||
changePath(musicPath, result.getData(), MUSIC_PATH_CODE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ActivityResultLauncher<Intent> videoPathResultLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
new ActivityResultCallback<ActivityResult>() {
|
||||
@Override
|
||||
public void onActivityResult(ActivityResult result) {
|
||||
if (result.getResultCode() == Activity.RESULT_OK) {
|
||||
changePath(videoPath, result.getData(), VIDEO_PATH_CODE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
public void changePath(Preference p, Intent data, int requestCode){
|
||||
Log.e("TEST", data.toUri(0));
|
||||
String dataValue = data.getData().toString();
|
||||
dataValue = dataValue.replace("content://com.android.externalstorage.documents/tree/", "");
|
||||
dataValue = dataValue.replaceAll("%3A", "/");
|
||||
|
||||
try{
|
||||
dataValue = java.net.URLDecoder.decode(dataValue, StandardCharsets.UTF_8.name());
|
||||
}catch(Exception ignored){}
|
||||
|
||||
String[] pieces = dataValue.split("/");
|
||||
|
||||
int index = 1;
|
||||
StringBuilder path = new StringBuilder("/storage/");
|
||||
if(pieces[0].equals("primary")){
|
||||
path.append("emulated/0/");
|
||||
}else{
|
||||
path.append(pieces[0]).append("/");
|
||||
}
|
||||
|
||||
for(int i = index; i < pieces.length; i++){
|
||||
path.append(pieces[i]).append("/");
|
||||
}
|
||||
|
||||
Log.e("TEST", path.toString());
|
||||
p.setSummary(path.toString());
|
||||
SharedPreferences sharedPreferences = requireContext().getSharedPreferences("root_preferences", Activity.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
switch (requestCode){
|
||||
case MUSIC_PATH_CODE:
|
||||
editor.putString("music_path", path.toString());
|
||||
break;
|
||||
case VIDEO_PATH_CODE:
|
||||
editor.putString("video_path", path.toString());
|
||||
break;
|
||||
}
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private void updateYoutubeDL() {
|
||||
if (updatingYTDL) {
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_already_updating), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_updating_started), Toast.LENGTH_SHORT).show();
|
||||
|
||||
updatingYTDL = true;
|
||||
Disposable disposable = Observable.fromCallable(() -> YoutubeDL.getInstance().updateYoutubeDL(getContext()))
|
||||
.subscribeOn(Schedulers.newThread())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(status -> {
|
||||
switch (status) {
|
||||
case DONE:
|
||||
Toast.makeText(getContext(), getString(R.string.ytld_update_success), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case ALREADY_UP_TO_DATE:
|
||||
Toast.makeText(getContext(), getString(R.string.you_are_in_latest_version), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
default:
|
||||
Toast.makeText(getContext(), status.toString(), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
updatingYTDL = false;
|
||||
}, e -> {
|
||||
if(BuildConfig.DEBUG) Log.e(TAG, getString(R.string.ytdl_update_failed), e);
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_update_failed), Toast.LENGTH_LONG).show();
|
||||
updatingYTDL = false;
|
||||
});
|
||||
compositeDisposable.add(disposable);
|
||||
}
|
||||
|
||||
|
||||
private void updateApp(){
|
||||
if (updatingApp) {
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_already_updating), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_updating_started), Toast.LENGTH_SHORT).show();
|
||||
|
||||
updatingApp = true;
|
||||
Disposable disposable = Observable.fromCallable(() -> YoutubeDL.getInstance().updateYoutubeDL(getContext()))
|
||||
.subscribeOn(Schedulers.newThread())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(status -> {
|
||||
switch (status) {
|
||||
case DONE:
|
||||
Toast.makeText(getContext(), getString(R.string.ytld_update_success), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case ALREADY_UP_TO_DATE:
|
||||
Toast.makeText(getContext(), getString(R.string.you_are_in_latest_version), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
default:
|
||||
Toast.makeText(getContext(), status.toString(), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
updatingApp = false;
|
||||
}, e -> {
|
||||
if(BuildConfig.DEBUG) Log.e(TAG, getString(R.string.ytdl_update_failed), e);
|
||||
Toast.makeText(getContext(), getString(R.string.ytdl_update_failed), Toast.LENGTH_LONG).show();
|
||||
updatingApp = false;
|
||||
});
|
||||
compositeDisposable.add(disposable);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
5
app/src/main/res/drawable/ic_back.xml
Normal file
5
app/src/main/res/drawable/ic_back.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:textColorPrimary" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||
</vector>
|
||||
8
app/src/main/res/drawable/ic_chapters.xml
Normal file
8
app/src/main/res/drawable/ic_chapters.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M21,5c-1.11,-0.35 -2.33,-0.5 -3.5,-0.5c-1.95,0 -4.05,0.4 -5.5,1.5c-1.45,-1.1 -3.55,-1.5 -5.5,-1.5S2.45,4.9 1,6v14.65c0,0.25 0.25,0.5 0.5,0.5c0.1,0 0.15,-0.05 0.25,-0.05C3.1,20.45 5.05,20 6.5,20c1.95,0 4.05,0.4 5.5,1.5c1.35,-0.85 3.8,-1.5 5.5,-1.5c1.65,0 3.35,0.3 4.75,1.05c0.1,0.05 0.15,0.05 0.25,0.05c0.25,0 0.5,-0.25 0.5,-0.5V6C22.4,5.55 21.75,5.25 21,5zM21,18.5c-1.1,-0.35 -2.3,-0.5 -3.5,-0.5c-1.7,0 -4.15,0.65 -5.5,1.5V8c1.35,-0.85 3.8,-1.5 5.5,-1.5c1.2,0 2.4,0.15 3.5,0.5V18.5z"/>
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M17.5,10.5c0.88,0 1.73,0.09 2.5,0.26V9.24C19.21,9.09 18.36,9 17.5,9c-1.7,0 -3.24,0.29 -4.5,0.83v1.66C14.13,10.85 15.7,10.5 17.5,10.5z"/>
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M13,12.49v1.66c1.13,-0.64 2.7,-0.99 4.5,-0.99c0.88,0 1.73,0.09 2.5,0.26V11.9c-0.79,-0.15 -1.64,-0.24 -2.5,-0.24C15.8,11.66 14.26,11.96 13,12.49z"/>
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M17.5,14.33c-1.7,0 -3.24,0.29 -4.5,0.83v1.66c1.13,-0.64 2.7,-0.99 4.5,-0.99c0.88,0 1.73,0.09 2.5,0.26v-1.52C19.21,14.41 18.36,14.33 17.5,14.33z"/>
|
||||
</vector>
|
||||
5
app/src/main/res/drawable/ic_down.xml
Normal file
5
app/src/main/res/drawable/ic_down.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M20,12l-1.41,-1.41L13,16.17V4h-2v12.17l-5.58,-5.59L4,12l8,8 8,-8z"/>
|
||||
</vector>
|
||||
5
app/src/main/res/drawable/ic_image.xml
Normal file
5
app/src/main/res/drawable/ic_image.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z"/>
|
||||
</vector>
|
||||
5
app/src/main/res/drawable/ic_lines.xml
Normal file
5
app/src/main/res/drawable/ic_lines.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M4,22H2V2h2V22zM22,7H6v3h16V7zM16,14H6v3h10V14z"/>
|
||||
</vector>
|
||||
5
app/src/main/res/drawable/ic_more.xml
Normal file
5
app/src/main/res/drawable/ic_more.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:textColorPrimary" android:pathData="M6,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
||||
</vector>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFA600"
|
||||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#fff" android:pathData="M12,3v10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55 -2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4V7h4V3h-6z"/>
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M12,3v10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55 -2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4V7h4V3h-6z"/>
|
||||
</vector>
|
||||
|
|
|
|||
5
app/src/main/res/drawable/ic_subtitles.xml
Normal file
5
app/src/main/res/drawable/ic_subtitles.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M20,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM4,12h4v2L4,14v-2zM14,18L4,18v-2h10v2zM20,18h-4v-2h4v2zM20,14L10,14v-2h10v2z"/>
|
||||
</vector>
|
||||
5
app/src/main/res/drawable/ic_update_app.xml
Normal file
5
app/src/main/res/drawable/ic_update_app.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M21.81,12.74l-0.82,-0.63v-0.22l0.8,-0.63c0.16,-0.12 0.2,-0.34 0.1,-0.51l-0.85,-1.48c-0.07,-0.13 -0.21,-0.2 -0.35,-0.2 -0.05,0 -0.1,0.01 -0.15,0.03l-0.95,0.38c-0.08,-0.05 -0.11,-0.07 -0.19,-0.11l-0.15,-1.01c-0.03,-0.21 -0.2,-0.36 -0.4,-0.36h-1.71c-0.2,0 -0.37,0.15 -0.4,0.34l-0.14,1.01c-0.03,0.02 -0.07,0.03 -0.1,0.05l-0.09,0.06 -0.95,-0.38c-0.05,-0.02 -0.1,-0.03 -0.15,-0.03 -0.14,0 -0.27,0.07 -0.35,0.2l-0.85,1.48c-0.1,0.17 -0.06,0.39 0.1,0.51l0.8,0.63v0.23l-0.8,0.63c-0.16,0.12 -0.2,0.34 -0.1,0.51l0.85,1.48c0.07,0.13 0.21,0.2 0.35,0.2 0.05,0 0.1,-0.01 0.15,-0.03l0.95,-0.37c0.08,0.05 0.12,0.07 0.2,0.11l0.15,1.01c0.03,0.2 0.2,0.34 0.4,0.34h1.71c0.2,0 0.37,-0.15 0.4,-0.34l0.15,-1.01c0.03,-0.02 0.07,-0.03 0.1,-0.05l0.09,-0.06 0.95,0.38c0.05,0.02 0.1,0.03 0.15,0.03 0.14,0 0.27,-0.07 0.35,-0.2l0.85,-1.48c0.1,-0.17 0.06,-0.39 -0.1,-0.51zM18,13.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM17,17h2v4c0,1.1 -0.9,2 -2,2H7c-1.1,0 -2,-0.9 -2,-2V3c0,-1.1 0.9,-2 2,-2h10c1.1,0 2,0.9 2,2v4h-2V6H7v12h10v-1z"/>
|
||||
</vector>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FF4D00"
|
||||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z"/>
|
||||
<path android:fillColor="?android:colorAccent" android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z"/>
|
||||
</vector>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
android:id="@+id/bottomNavigationView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:labelVisibilityMode="labeled"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
|
|
|
|||
39
app/src/main/res/layout/activity_settings.xml
Normal file
39
app/src/main/res/layout/activity_settings.xml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.deniscerri.ytdl.page.settings.SettingsActivity">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/settings_frame_layout"
|
||||
android:layout_width="match_parent"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:liftOnScroll="false"
|
||||
android:background="@android:color/transparent"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/settings_toolbar"
|
||||
android:elevation="0dp"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap"
|
||||
app:title="@string/settings"
|
||||
android:layout_width="match_parent"
|
||||
app:navigationIcon="@drawable/ic_back"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/preference_coordinatorLayout"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
|
|
|||
|
|
@ -7,7 +7,13 @@
|
|||
<item android:title="@string/history"
|
||||
android:icon="@drawable/ic_history"
|
||||
android:id="@+id/history"/>
|
||||
<item android:title="@string/settings"
|
||||
android:icon="@drawable/ic_settings"
|
||||
android:id="@+id/settings"/>
|
||||
<item android:title="@string/music_editor"
|
||||
android:icon="@drawable/ic_music_downloaded"
|
||||
android:id="@+id/music_editor"/>
|
||||
<item android:title="@string/cli"
|
||||
android:icon="@drawable/ic_code"
|
||||
android:id="@+id/cli"/>
|
||||
<item android:title="@string/more"
|
||||
android:icon="@drawable/ic_more"
|
||||
android:id="@+id/more"/>
|
||||
</menu>
|
||||
|
|
@ -14,12 +14,17 @@
|
|||
android:id="@+id/refresh_results"
|
||||
android:icon="@drawable/ic_refresh"
|
||||
android:title="@string/refresh_results"
|
||||
app:showAsAction="ifRoom" />
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/delete_results"
|
||||
android:title="@string/fshi_rezultatet"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/open_settings"
|
||||
android:title="@string/settings"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,21 @@
|
|||
<resources>
|
||||
<!-- Reply Preference -->
|
||||
<string-array name="music_formats">
|
||||
<item>mp3</item>
|
||||
<item>m4a</item>
|
||||
<item>aac</item>
|
||||
<item>alac</item>
|
||||
<item>flac</item>
|
||||
<item>opus</item>
|
||||
<item>vorbis</item>
|
||||
<item>wav</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<string-array name="video_formats">
|
||||
<item>mp4</item>
|
||||
<item>mkv</item>
|
||||
<item>mov</item>
|
||||
<item>webm</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
|
@ -42,4 +42,9 @@
|
|||
<string name="confirm_delete_history">Confirm</string>
|
||||
<string name="search_history_hint">Search from History</string>
|
||||
<string name="no_results">No Results</string>
|
||||
<string name="music_editor">TAG Editor</string>
|
||||
<string name="cli">Commands</string>
|
||||
<string name="more">More</string>
|
||||
<string name="update_app">Update App</string>
|
||||
<string name="download_latest_version">Download the latest version of the app</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -3,39 +3,130 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
>
|
||||
|
||||
<Preference
|
||||
android:layout="@layout/fragment_settings"/>
|
||||
<PreferenceCategory android:title="@string/directories">
|
||||
<Preference
|
||||
app:key="music_path"
|
||||
app:icon="@drawable/ic_music_downloaded"
|
||||
app:title="@string/music_directory" />
|
||||
|
||||
<Preference />
|
||||
<Preference
|
||||
app:key="video_path"
|
||||
app:icon="@drawable/ic_video_downloaded"
|
||||
app:title="@string/video_directory" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<Preference
|
||||
app:key="music_path"
|
||||
app:allowDividerAbove="true"
|
||||
app:icon="@drawable/ic_music_downloaded"
|
||||
app:title="@string/music_directory" />
|
||||
|
||||
<Preference
|
||||
app:key="video_path"
|
||||
app:icon="@drawable/ic_video_downloaded"
|
||||
app:title="@string/video_directory" />
|
||||
|
||||
<Preference
|
||||
app:key="update"
|
||||
app:allowDividerAbove="true"
|
||||
app:icon="@drawable/ic_update"
|
||||
app:summary="@string/ytdl_update_hint"
|
||||
app:title="@string/update_ytdl" />
|
||||
|
||||
<Preference
|
||||
app:key="rreth"
|
||||
app:allowDividerAbove="true"
|
||||
app:icon="@drawable/ic_code"
|
||||
app:summary="https://github.com/deniscerri/ytdlnis"
|
||||
app:title="@string/source_code">
|
||||
<intent
|
||||
android:action="android.intent.action.VIEW"
|
||||
android:data="https://github.com/deniscerri/ytdlnis"
|
||||
<PreferenceCategory app:title="Downloading">
|
||||
<SeekBarPreference
|
||||
app:key="concurrent_fragments"
|
||||
app:title="Concurrent Fragments"
|
||||
android:icon="@drawable/ic_lines"
|
||||
app:summary=" Number of fragments of a dash/hlsnative video that should be downloaded concurrently"
|
||||
android:defaultValue="1"
|
||||
android:max="10"
|
||||
app:min="1"
|
||||
app:showSeekBarValue="true"
|
||||
/>
|
||||
</Preference>
|
||||
|
||||
<EditTextPreference
|
||||
app:key="limit_rate"
|
||||
android:icon="@drawable/ic_down"
|
||||
app:title="Limit Rate"
|
||||
app:summary="Maximum download rate in bytes per second, e.g. 50K or 4.2M"
|
||||
/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
<PreferenceCategory android:title="Processing">
|
||||
<SwitchPreferenceCompat
|
||||
app:key="remove_non_music"
|
||||
app:icon="@drawable/ic_music"
|
||||
app:defaultValue="true"
|
||||
app:title="Remove non music parts" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:key="embed_subtitles"
|
||||
app:defaultValue="true"
|
||||
app:summary="Embed subtitles in the video (only for mp4,webm and mkv videos)"
|
||||
app:icon="@drawable/ic_subtitles"
|
||||
app:title="Embed Subtitles on Videos" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:key="embed_thumbnail"
|
||||
app:defaultValue="true"
|
||||
app:icon="@drawable/ic_image"
|
||||
app:summary="Embed thumbnail as cover art"
|
||||
app:title="Embed Thumbnail" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:key="add_chapters"
|
||||
app:defaultValue="true"
|
||||
app:icon="@drawable/ic_chapters"
|
||||
app:title="Add Chapters on Videos" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:key="write_thumbnail"
|
||||
app:defaultValue="false"
|
||||
app:icon="@drawable/ic_image"
|
||||
app:title="Write Thumbnail to disk" />
|
||||
|
||||
<ListPreference
|
||||
app:key="audio_format"
|
||||
app:title="Audio Format"
|
||||
android:defaultValue="mp3"
|
||||
android:icon="@drawable/ic_code"
|
||||
android:entries="@array/music_formats"
|
||||
android:entryValues="@array/music_formats" />
|
||||
|
||||
<ListPreference
|
||||
app:key="video_format"
|
||||
app:title="Video Format"
|
||||
android:defaultValue="mp4"
|
||||
android:icon="@drawable/ic_code"
|
||||
android:entries="@array/video_formats"
|
||||
android:entryValues="@array/video_formats" />
|
||||
|
||||
|
||||
<SeekBarPreference
|
||||
app:key="audio_quality"
|
||||
app:title="Audio Quality"
|
||||
android:icon="@drawable/ic_music"
|
||||
app:summary="0 (Best) 10 (Worst)"
|
||||
android:defaultValue="5"
|
||||
android:max="10"
|
||||
app:min="0"
|
||||
app:showSeekBarValue="true"
|
||||
/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
<PreferenceCategory android:title="@string/updating">
|
||||
<Preference
|
||||
app:key="update_ytdl"
|
||||
app:icon="@drawable/ic_update"
|
||||
app:summary="@string/ytdl_update_hint"
|
||||
app:title="@string/update_ytdl" />
|
||||
|
||||
<Preference
|
||||
app:key="update_app"
|
||||
app:icon="@drawable/ic_update_app"
|
||||
app:summary="@string/download_latest_version"
|
||||
app:title="@string/update_app" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/about">
|
||||
<Preference
|
||||
app:key="rreth"
|
||||
app:icon="@drawable/ic_code"
|
||||
app:summary="https://github.com/deniscerri/ytdlnis"
|
||||
app:title="@string/source_code">
|
||||
<intent
|
||||
android:action="android.intent.action.VIEW"
|
||||
android:data="https://github.com/deniscerri/ytdlnis"
|
||||
/>
|
||||
</Preference>
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
</PreferenceScreen>
|
||||
Loading…
Reference in a new issue