2016-03-25 19:01:22 +01:00
|
|
|
package org.schabi.newpipe.download;
|
2015-09-21 21:12:48 +02:00
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
import android.app.Activity;
|
|
|
|
import android.content.ComponentName;
|
2018-04-08 13:08:19 +02:00
|
|
|
import android.content.Context;
|
2019-04-05 19:45:39 +02:00
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.ServiceConnection;
|
2018-09-23 20:12:23 +02:00
|
|
|
import android.content.SharedPreferences;
|
2019-04-05 19:45:39 +02:00
|
|
|
import android.net.Uri;
|
2015-09-21 21:12:48 +02:00
|
|
|
import android.os.Bundle;
|
2019-08-15 04:00:11 +02:00
|
|
|
import android.os.Environment;
|
2019-04-05 19:45:39 +02:00
|
|
|
import android.os.IBinder;
|
2018-09-23 20:12:23 +02:00
|
|
|
import android.preference.PreferenceManager;
|
2015-09-21 21:12:48 +02:00
|
|
|
import android.util.Log;
|
2018-11-20 23:10:50 +01:00
|
|
|
import android.util.SparseArray;
|
2016-04-29 12:40:03 +02:00
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
2017-05-15 05:57:57 +02:00
|
|
|
import android.widget.AdapterView;
|
2016-04-29 12:40:03 +02:00
|
|
|
import android.widget.EditText;
|
2016-09-26 20:18:32 +02:00
|
|
|
import android.widget.RadioButton;
|
2017-05-15 05:57:57 +02:00
|
|
|
import android.widget.RadioGroup;
|
2016-04-29 12:40:03 +02:00
|
|
|
import android.widget.SeekBar;
|
2017-05-15 05:57:57 +02:00
|
|
|
import android.widget.Spinner;
|
2016-04-29 12:40:03 +02:00
|
|
|
import android.widget.TextView;
|
2018-04-08 13:08:19 +02:00
|
|
|
import android.widget.Toast;
|
2015-09-21 21:12:48 +02:00
|
|
|
|
2020-01-31 22:49:43 +01:00
|
|
|
import androidx.annotation.IdRes;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import androidx.annotation.StringRes;
|
|
|
|
import androidx.appcompat.app.AlertDialog;
|
|
|
|
import androidx.appcompat.view.menu.ActionMenuItemView;
|
|
|
|
import androidx.appcompat.widget.Toolbar;
|
|
|
|
import androidx.documentfile.provider.DocumentFile;
|
|
|
|
import androidx.fragment.app.DialogFragment;
|
|
|
|
|
2019-08-15 04:00:11 +02:00
|
|
|
import com.nononsenseapps.filepicker.Utils;
|
|
|
|
|
2017-05-15 05:57:57 +02:00
|
|
|
import org.schabi.newpipe.MainActivity;
|
2016-03-25 19:01:22 +01:00
|
|
|
import org.schabi.newpipe.R;
|
2019-12-16 23:59:30 +01:00
|
|
|
import org.schabi.newpipe.RouterActivity;
|
2018-09-23 20:12:23 +02:00
|
|
|
import org.schabi.newpipe.extractor.MediaFormat;
|
|
|
|
import org.schabi.newpipe.extractor.NewPipe;
|
2019-10-28 03:35:51 +01:00
|
|
|
import org.schabi.newpipe.extractor.localization.Localization;
|
2017-09-03 08:04:18 +02:00
|
|
|
import org.schabi.newpipe.extractor.stream.AudioStream;
|
2018-04-08 13:08:19 +02:00
|
|
|
import org.schabi.newpipe.extractor.stream.Stream;
|
2017-09-03 08:04:18 +02:00
|
|
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
2018-09-23 20:12:23 +02:00
|
|
|
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
|
2017-09-03 08:04:18 +02:00
|
|
|
import org.schabi.newpipe.extractor.stream.VideoStream;
|
2019-04-05 19:45:39 +02:00
|
|
|
import org.schabi.newpipe.report.ErrorActivity;
|
|
|
|
import org.schabi.newpipe.report.UserAction;
|
2019-08-15 03:15:42 +02:00
|
|
|
import org.schabi.newpipe.settings.NewPipeSettings;
|
|
|
|
import org.schabi.newpipe.util.FilePickerActivityHelper;
|
2017-07-19 16:27:40 +02:00
|
|
|
import org.schabi.newpipe.util.FilenameUtils;
|
2017-09-03 08:04:18 +02:00
|
|
|
import org.schabi.newpipe.util.ListHelper;
|
2019-08-15 04:00:11 +02:00
|
|
|
import org.schabi.newpipe.util.PermissionHelper;
|
2018-11-20 23:10:50 +01:00
|
|
|
import org.schabi.newpipe.util.SecondaryStreamHelper;
|
2018-04-08 13:08:19 +02:00
|
|
|
import org.schabi.newpipe.util.StreamItemAdapter;
|
|
|
|
import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper;
|
2017-04-26 21:32:04 +02:00
|
|
|
import org.schabi.newpipe.util.ThemeHelper;
|
2016-03-25 19:01:22 +01:00
|
|
|
|
2019-08-15 03:15:42 +02:00
|
|
|
import java.io.File;
|
2019-04-05 19:45:39 +02:00
|
|
|
import java.io.IOException;
|
2016-01-07 14:22:55 +01:00
|
|
|
import java.util.ArrayList;
|
2019-04-05 19:45:39 +02:00
|
|
|
import java.util.Collections;
|
2016-01-07 14:22:55 +01:00
|
|
|
import java.util.List;
|
2018-09-23 20:12:23 +02:00
|
|
|
import java.util.Locale;
|
2015-09-21 21:12:48 +02:00
|
|
|
|
2018-04-08 13:08:19 +02:00
|
|
|
import icepick.Icepick;
|
|
|
|
import icepick.State;
|
|
|
|
import io.reactivex.disposables.CompositeDisposable;
|
2019-09-28 23:11:05 +02:00
|
|
|
import us.shandian.giga.get.MissionRecoveryInfo;
|
2019-04-05 19:45:39 +02:00
|
|
|
import us.shandian.giga.io.StoredDirectoryHelper;
|
|
|
|
import us.shandian.giga.io.StoredFileHelper;
|
2018-09-23 20:12:23 +02:00
|
|
|
import us.shandian.giga.postprocessing.Postprocessing;
|
2019-04-05 19:45:39 +02:00
|
|
|
import us.shandian.giga.service.DownloadManager;
|
2016-04-29 12:40:03 +02:00
|
|
|
import us.shandian.giga.service.DownloadManagerService;
|
2019-04-05 19:45:39 +02:00
|
|
|
import us.shandian.giga.service.DownloadManagerService.DownloadManagerBinder;
|
|
|
|
import us.shandian.giga.service.MissionState;
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2020-01-31 22:49:43 +01:00
|
|
|
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public class DownloadDialog extends DialogFragment
|
|
|
|
implements RadioGroup.OnCheckedChangeListener, AdapterView.OnItemSelectedListener {
|
2017-05-15 05:57:57 +02:00
|
|
|
private static final String TAG = "DialogFragment";
|
|
|
|
private static final boolean DEBUG = MainActivity.DEBUG;
|
2019-08-15 03:15:42 +02:00
|
|
|
private static final int REQUEST_DOWNLOAD_SAVE_AS = 0x1230;
|
2020-03-31 19:20:15 +02:00
|
|
|
private final CompositeDisposable disposables = new CompositeDisposable();
|
2018-11-20 23:10:50 +01:00
|
|
|
@State
|
|
|
|
protected StreamInfo currentInfo;
|
|
|
|
@State
|
|
|
|
protected StreamSizeWrapper<AudioStream> wrappedAudioStreams = StreamSizeWrapper.empty();
|
|
|
|
@State
|
|
|
|
protected StreamSizeWrapper<VideoStream> wrappedVideoStreams = StreamSizeWrapper.empty();
|
|
|
|
@State
|
|
|
|
protected StreamSizeWrapper<SubtitlesStream> wrappedSubtitleStreams = StreamSizeWrapper.empty();
|
|
|
|
@State
|
|
|
|
protected int selectedVideoIndex = 0;
|
|
|
|
@State
|
|
|
|
protected int selectedAudioIndex = 0;
|
|
|
|
@State
|
|
|
|
protected int selectedSubtitleIndex = 0;
|
2020-03-31 19:20:15 +02:00
|
|
|
private StoredDirectoryHelper mainStorageAudio = null;
|
|
|
|
private StoredDirectoryHelper mainStorageVideo = null;
|
|
|
|
private DownloadManager downloadManager = null;
|
|
|
|
private ActionMenuItemView okButton = null;
|
|
|
|
private Context context;
|
|
|
|
private boolean askForSavePath;
|
2018-11-20 23:10:50 +01:00
|
|
|
private StreamItemAdapter<AudioStream, Stream> audioStreamsAdapter;
|
|
|
|
private StreamItemAdapter<VideoStream, AudioStream> videoStreamsAdapter;
|
|
|
|
private StreamItemAdapter<SubtitlesStream, Stream> subtitleStreamsAdapter;
|
2017-05-15 05:57:57 +02:00
|
|
|
private EditText nameEditText;
|
|
|
|
private Spinner streamsSpinner;
|
2019-04-05 19:45:39 +02:00
|
|
|
private RadioGroup radioStreamsGroup;
|
2017-05-15 05:57:57 +02:00
|
|
|
private TextView threadsCountTextView;
|
|
|
|
private SeekBar threadsSeekBar;
|
2018-09-23 20:12:23 +02:00
|
|
|
private SharedPreferences prefs;
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static DownloadDialog newInstance(final StreamInfo info) {
|
2016-04-29 12:40:03 +02:00
|
|
|
DownloadDialog dialog = new DownloadDialog();
|
2018-04-08 13:08:19 +02:00
|
|
|
dialog.setInfo(info);
|
2016-04-29 12:40:03 +02:00
|
|
|
return dialog;
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static DownloadDialog newInstance(final Context context, final StreamInfo info) {
|
|
|
|
final ArrayList<VideoStream> streamsList = new ArrayList<>(ListHelper
|
|
|
|
.getSortedStreamVideosList(context, info.getVideoStreams(),
|
|
|
|
info.getVideoOnlyStreams(), false));
|
2018-04-08 13:08:19 +02:00
|
|
|
final int selectedStreamIndex = ListHelper.getDefaultResolutionIndex(context, streamsList);
|
|
|
|
|
|
|
|
final DownloadDialog instance = newInstance(info);
|
|
|
|
instance.setVideoStreams(streamsList);
|
|
|
|
instance.setSelectedVideoStream(selectedStreamIndex);
|
|
|
|
instance.setAudioStreams(info.getAudioStreams());
|
2018-09-23 20:12:23 +02:00
|
|
|
instance.setSubtitleStreams(info.getSubtitles());
|
|
|
|
|
2018-04-08 13:08:19 +02:00
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private void setInfo(final StreamInfo info) {
|
2017-05-15 05:57:57 +02:00
|
|
|
this.currentInfo = info;
|
2018-04-08 13:08:19 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public void setAudioStreams(final List<AudioStream> audioStreams) {
|
2018-09-23 20:12:23 +02:00
|
|
|
setAudioStreams(new StreamSizeWrapper<>(audioStreams, getContext()));
|
2018-04-08 13:08:19 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public void setAudioStreams(final StreamSizeWrapper<AudioStream> was) {
|
|
|
|
this.wrappedAudioStreams = was;
|
2018-04-08 13:08:19 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public void setVideoStreams(final List<VideoStream> videoStreams) {
|
2018-09-23 20:12:23 +02:00
|
|
|
setVideoStreams(new StreamSizeWrapper<>(videoStreams, getContext()));
|
2018-04-08 13:08:19 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// LifeCycle
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
|
|
|
public void setVideoStreams(final StreamSizeWrapper<VideoStream> wvs) {
|
|
|
|
this.wrappedVideoStreams = wvs;
|
2018-04-08 13:08:19 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public void setSubtitleStreams(final List<SubtitlesStream> subtitleStreams) {
|
2018-09-23 20:12:23 +02:00
|
|
|
setSubtitleStreams(new StreamSizeWrapper<>(subtitleStreams, getContext()));
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public void setSubtitleStreams(
|
|
|
|
final StreamSizeWrapper<SubtitlesStream> wss) {
|
|
|
|
this.wrappedSubtitleStreams = wss;
|
2018-09-23 20:12:23 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public void setSelectedVideoStream(final int svi) {
|
|
|
|
this.selectedVideoIndex = svi;
|
2018-04-08 13:08:19 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public void setSelectedAudioStream(final int sai) {
|
|
|
|
this.selectedAudioIndex = sai;
|
2017-05-15 05:57:57 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public void setSelectedSubtitleStream(final int ssi) {
|
|
|
|
this.selectedSubtitleIndex = ssi;
|
2018-09-23 20:12:23 +02:00
|
|
|
}
|
|
|
|
|
2015-09-21 21:12:48 +02:00
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
2017-05-15 05:57:57 +02:00
|
|
|
super.onCreate(savedInstanceState);
|
2020-03-31 19:20:15 +02:00
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "onCreate() called with: "
|
|
|
|
+ "savedInstanceState = [" + savedInstanceState + "]");
|
|
|
|
}
|
2017-05-15 05:57:57 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
if (!PermissionHelper.checkStoragePermissions(getActivity(),
|
|
|
|
PermissionHelper.DOWNLOAD_DIALOG_REQUEST_CODE)) {
|
2019-08-15 04:00:11 +02:00
|
|
|
getDialog().dismiss();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-09 23:38:34 +02:00
|
|
|
context = getContext();
|
2019-04-05 19:45:39 +02:00
|
|
|
|
|
|
|
setStyle(STYLE_NO_TITLE, ThemeHelper.getDialogTheme(context));
|
2018-04-08 13:08:19 +02:00
|
|
|
Icepick.restoreInstanceState(this, savedInstanceState);
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2018-11-20 23:10:50 +01:00
|
|
|
SparseArray<SecondaryStreamHelper<AudioStream>> secondaryStreams = new SparseArray<>(4);
|
|
|
|
List<VideoStream> videoStreams = wrappedVideoStreams.getStreamsList();
|
|
|
|
|
|
|
|
for (int i = 0; i < videoStreams.size(); i++) {
|
2020-03-31 19:20:15 +02:00
|
|
|
if (!videoStreams.get(i).isVideoOnly()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
AudioStream audioStream = SecondaryStreamHelper
|
|
|
|
.getAudioStreamFor(wrappedAudioStreams.getStreamsList(), videoStreams.get(i));
|
2018-11-20 23:10:50 +01:00
|
|
|
|
|
|
|
if (audioStream != null) {
|
2020-03-31 19:20:15 +02:00
|
|
|
secondaryStreams
|
|
|
|
.append(i, new SecondaryStreamHelper<>(wrappedAudioStreams, audioStream));
|
2018-11-20 23:10:50 +01:00
|
|
|
} else if (DEBUG) {
|
2020-03-31 19:20:15 +02:00
|
|
|
Log.w(TAG, "No audio stream candidates for video format "
|
|
|
|
+ videoStreams.get(i).getFormat().name());
|
2018-11-20 23:10:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
this.videoStreamsAdapter = new StreamItemAdapter<>(context, wrappedVideoStreams,
|
|
|
|
secondaryStreams);
|
2019-04-05 19:45:39 +02:00
|
|
|
this.audioStreamsAdapter = new StreamItemAdapter<>(context, wrappedAudioStreams);
|
|
|
|
this.subtitleStreamsAdapter = new StreamItemAdapter<>(context, wrappedSubtitleStreams);
|
|
|
|
|
|
|
|
Intent intent = new Intent(context, DownloadManagerService.class);
|
|
|
|
context.startService(intent);
|
|
|
|
|
|
|
|
context.bindService(intent, new ServiceConnection() {
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onServiceConnected(final ComponentName cname, final IBinder service) {
|
2019-04-05 19:45:39 +02:00
|
|
|
DownloadManagerBinder mgr = (DownloadManagerBinder) service;
|
|
|
|
|
|
|
|
mainStorageAudio = mgr.getMainStorageAudio();
|
|
|
|
mainStorageVideo = mgr.getMainStorageVideo();
|
|
|
|
downloadManager = mgr.getDownloadManager();
|
2019-04-19 21:18:19 +02:00
|
|
|
askForSavePath = mgr.askForSavePath();
|
2019-04-05 19:45:39 +02:00
|
|
|
|
|
|
|
okButton.setEnabled(true);
|
|
|
|
|
|
|
|
context.unbindService(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onServiceDisconnected(final ComponentName name) {
|
2019-04-05 19:45:39 +02:00
|
|
|
// nothing to do
|
|
|
|
}
|
|
|
|
}, Context.BIND_AUTO_CREATE);
|
2017-05-15 05:57:57 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Inits
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
2017-05-15 05:57:57 +02:00
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container,
|
|
|
|
final Bundle savedInstanceState) {
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "onCreateView() called with: "
|
|
|
|
+ "inflater = [" + inflater + "], container = [" + container + "], "
|
|
|
|
+ "savedInstanceState = [" + savedInstanceState + "]");
|
|
|
|
}
|
2018-04-08 13:08:19 +02:00
|
|
|
return inflater.inflate(R.layout.download_dialog, container);
|
2016-04-29 12:40:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
2016-04-29 12:40:03 +02:00
|
|
|
super.onViewCreated(view, savedInstanceState);
|
2017-09-03 08:04:18 +02:00
|
|
|
nameEditText = view.findViewById(R.id.file_name);
|
2017-12-08 15:05:08 +01:00
|
|
|
nameEditText.setText(FilenameUtils.createFilename(getContext(), currentInfo.getName()));
|
2020-03-31 19:20:15 +02:00
|
|
|
selectedAudioIndex = ListHelper
|
|
|
|
.getDefaultAudioFormat(getContext(), currentInfo.getAudioStreams());
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2018-09-23 20:12:23 +02:00
|
|
|
selectedSubtitleIndex = getSubtitleIndexBy(subtitleStreamsAdapter.getAll());
|
|
|
|
|
2017-09-03 08:04:18 +02:00
|
|
|
streamsSpinner = view.findViewById(R.id.quality_spinner);
|
2017-05-15 05:57:57 +02:00
|
|
|
streamsSpinner.setOnItemSelectedListener(this);
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2017-09-03 08:04:18 +02:00
|
|
|
threadsCountTextView = view.findViewById(R.id.threads_count);
|
|
|
|
threadsSeekBar = view.findViewById(R.id.threads);
|
2018-04-08 13:08:19 +02:00
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
radioStreamsGroup = view.findViewById(R.id.video_audio_group);
|
|
|
|
radioStreamsGroup.setOnCheckedChangeListener(this);
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2018-04-08 13:08:19 +02:00
|
|
|
initToolbar(view.findViewById(R.id.toolbar));
|
|
|
|
setupDownloadOptions();
|
2017-05-15 05:57:57 +02:00
|
|
|
|
2018-09-23 20:12:23 +02:00
|
|
|
prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
|
|
|
|
|
|
|
|
int threads = prefs.getInt(getString(R.string.default_download_threads), 3);
|
|
|
|
threadsCountTextView.setText(String.valueOf(threads));
|
|
|
|
threadsSeekBar.setProgress(threads - 1);
|
2017-05-15 05:57:57 +02:00
|
|
|
threadsSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
2016-04-29 12:40:03 +02:00
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onProgressChanged(final SeekBar seekbar, final int progress,
|
|
|
|
final boolean fromUser) {
|
|
|
|
final int newProgress = progress + 1;
|
|
|
|
prefs.edit().putInt(getString(R.string.default_download_threads), newProgress)
|
|
|
|
.apply();
|
|
|
|
threadsCountTextView.setText(String.valueOf(newProgress));
|
2016-04-29 12:40:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onStartTrackingTouch(final SeekBar p1) { }
|
2016-04-29 12:40:03 +02:00
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onStopTrackingTouch(final SeekBar p1) { }
|
2016-04-29 12:40:03 +02:00
|
|
|
});
|
2018-04-08 13:08:19 +02:00
|
|
|
|
|
|
|
fetchStreamsSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void fetchStreamsSize() {
|
|
|
|
disposables.clear();
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
disposables.add(StreamSizeWrapper.fetchSizeForWrapper(wrappedVideoStreams)
|
|
|
|
.subscribe(result -> {
|
2019-04-05 19:45:39 +02:00
|
|
|
if (radioStreamsGroup.getCheckedRadioButtonId() == R.id.video_button) {
|
2018-04-08 13:08:19 +02:00
|
|
|
setupVideoSpinner();
|
|
|
|
}
|
|
|
|
}));
|
2020-03-31 19:20:15 +02:00
|
|
|
disposables.add(StreamSizeWrapper.fetchSizeForWrapper(wrappedAudioStreams)
|
|
|
|
.subscribe(result -> {
|
2019-04-05 19:45:39 +02:00
|
|
|
if (radioStreamsGroup.getCheckedRadioButtonId() == R.id.audio_button) {
|
2018-04-08 13:08:19 +02:00
|
|
|
setupAudioSpinner();
|
|
|
|
}
|
|
|
|
}));
|
2020-03-31 19:20:15 +02:00
|
|
|
disposables.add(StreamSizeWrapper.fetchSizeForWrapper(wrappedSubtitleStreams)
|
|
|
|
.subscribe(result -> {
|
2019-04-05 19:45:39 +02:00
|
|
|
if (radioStreamsGroup.getCheckedRadioButtonId() == R.id.subtitle_button) {
|
2018-09-23 20:12:23 +02:00
|
|
|
setupSubtitleSpinner();
|
|
|
|
}
|
|
|
|
}));
|
2018-04-08 13:08:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
super.onDestroy();
|
|
|
|
disposables.clear();
|
2017-05-15 05:57:57 +02:00
|
|
|
}
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Radio group Video&Audio options - Listener
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
2017-05-15 05:57:57 +02:00
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onSaveInstanceState(@NonNull final Bundle outState) {
|
2017-05-15 05:57:57 +02:00
|
|
|
super.onSaveInstanceState(outState);
|
2018-04-08 13:08:19 +02:00
|
|
|
Icepick.saveInstanceState(this, outState);
|
2017-05-15 05:57:57 +02:00
|
|
|
}
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Streams Spinner Listener
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
2019-04-05 19:45:39 +02:00
|
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
|
|
|
2019-08-15 03:15:42 +02:00
|
|
|
if (requestCode == REQUEST_DOWNLOAD_SAVE_AS && resultCode == Activity.RESULT_OK) {
|
2019-04-05 19:45:39 +02:00
|
|
|
if (data.getData() == null) {
|
|
|
|
showFailedDialog(R.string.general_error);
|
|
|
|
return;
|
|
|
|
}
|
2019-04-09 23:38:34 +02:00
|
|
|
|
2019-08-17 18:38:33 +02:00
|
|
|
if (FilePickerActivityHelper.isOwnFileUri(context, data.getData())) {
|
2019-08-15 04:00:11 +02:00
|
|
|
File file = Utils.getFileForUri(data.getData());
|
2020-03-31 19:20:15 +02:00
|
|
|
checkSelectedDownload(null, Uri.fromFile(file), file.getName(),
|
|
|
|
StoredFileHelper.DEFAULT_MIME);
|
2019-08-15 03:15:42 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-09 23:38:34 +02:00
|
|
|
DocumentFile docFile = DocumentFile.fromSingleUri(context, data.getData());
|
|
|
|
if (docFile == null) {
|
|
|
|
showFailedDialog(R.string.general_error);
|
|
|
|
return;
|
2019-04-05 19:45:39 +02:00
|
|
|
}
|
2019-04-09 23:38:34 +02:00
|
|
|
|
|
|
|
// check if the selected file was previously used
|
2020-03-31 19:20:15 +02:00
|
|
|
checkSelectedDownload(null, data.getData(), docFile.getName(),
|
|
|
|
docFile.getType());
|
2019-04-05 19:45:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private void initToolbar(final Toolbar toolbar) {
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "initToolbar() called with: toolbar = [" + toolbar + "]");
|
|
|
|
}
|
2019-04-05 19:45:39 +02:00
|
|
|
|
|
|
|
boolean isLight = ThemeHelper.isLightThemeSelected(getActivity());
|
|
|
|
|
2017-05-15 05:57:57 +02:00
|
|
|
toolbar.setTitle(R.string.download_dialog_title);
|
2020-03-31 19:20:15 +02:00
|
|
|
toolbar.setNavigationIcon(isLight ? R.drawable.ic_arrow_back_black_24dp
|
|
|
|
: R.drawable.ic_arrow_back_white_24dp);
|
2017-05-15 05:57:57 +02:00
|
|
|
toolbar.inflateMenu(R.menu.dialog_url);
|
2018-04-08 13:08:19 +02:00
|
|
|
toolbar.setNavigationOnClickListener(v -> getDialog().dismiss());
|
2019-09-22 13:26:53 +02:00
|
|
|
toolbar.setNavigationContentDescription(R.string.cancel);
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2019-04-09 23:38:34 +02:00
|
|
|
okButton = toolbar.findViewById(R.id.okay);
|
2020-03-31 19:20:15 +02:00
|
|
|
okButton.setEnabled(false); // disable until the download service connection is done
|
2019-04-05 19:45:39 +02:00
|
|
|
|
2018-04-08 13:08:19 +02:00
|
|
|
toolbar.setOnMenuItemClickListener(item -> {
|
|
|
|
if (item.getItemId() == R.id.okay) {
|
2018-09-23 20:12:23 +02:00
|
|
|
prepareSelectedDownload();
|
2019-12-26 12:24:18 +01:00
|
|
|
if (getActivity() instanceof RouterActivity) {
|
2019-12-16 23:59:30 +01:00
|
|
|
getActivity().finish();
|
|
|
|
}
|
2018-04-08 13:08:19 +02:00
|
|
|
return true;
|
2016-04-29 12:40:03 +02:00
|
|
|
}
|
2018-04-08 13:08:19 +02:00
|
|
|
return false;
|
2016-04-29 12:40:03 +02:00
|
|
|
});
|
2017-05-15 05:57:57 +02:00
|
|
|
}
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Utils
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
2018-04-08 13:08:19 +02:00
|
|
|
private void setupAudioSpinner() {
|
2020-03-31 19:20:15 +02:00
|
|
|
if (getContext() == null) {
|
|
|
|
return;
|
|
|
|
}
|
2017-05-15 05:57:57 +02:00
|
|
|
|
2018-04-08 13:08:19 +02:00
|
|
|
streamsSpinner.setAdapter(audioStreamsAdapter);
|
|
|
|
streamsSpinner.setSelection(selectedAudioIndex);
|
|
|
|
setRadioButtonsState(true);
|
2017-05-15 05:57:57 +02:00
|
|
|
}
|
|
|
|
|
2018-04-08 13:08:19 +02:00
|
|
|
private void setupVideoSpinner() {
|
2020-03-31 19:20:15 +02:00
|
|
|
if (getContext() == null) {
|
|
|
|
return;
|
|
|
|
}
|
2018-04-08 13:08:19 +02:00
|
|
|
|
|
|
|
streamsSpinner.setAdapter(videoStreamsAdapter);
|
|
|
|
streamsSpinner.setSelection(selectedVideoIndex);
|
|
|
|
setRadioButtonsState(true);
|
2016-04-29 12:40:03 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 20:12:23 +02:00
|
|
|
private void setupSubtitleSpinner() {
|
2020-03-31 19:20:15 +02:00
|
|
|
if (getContext() == null) {
|
|
|
|
return;
|
|
|
|
}
|
2018-09-23 20:12:23 +02:00
|
|
|
|
|
|
|
streamsSpinner.setAdapter(subtitleStreamsAdapter);
|
|
|
|
streamsSpinner.setSelection(selectedSubtitleIndex);
|
|
|
|
setRadioButtonsState(true);
|
|
|
|
}
|
|
|
|
|
2017-05-15 05:57:57 +02:00
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onCheckedChanged(final RadioGroup group, @IdRes final int checkedId) {
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "onCheckedChanged() called with: "
|
|
|
|
+ "group = [" + group + "], checkedId = [" + checkedId + "]");
|
|
|
|
}
|
2018-09-23 20:12:23 +02:00
|
|
|
boolean flag = true;
|
|
|
|
|
2017-05-15 05:57:57 +02:00
|
|
|
switch (checkedId) {
|
|
|
|
case R.id.audio_button:
|
2018-04-08 13:08:19 +02:00
|
|
|
setupAudioSpinner();
|
2017-05-15 05:57:57 +02:00
|
|
|
break;
|
|
|
|
case R.id.video_button:
|
2018-04-08 13:08:19 +02:00
|
|
|
setupVideoSpinner();
|
2017-05-15 05:57:57 +02:00
|
|
|
break;
|
2018-09-23 20:12:23 +02:00
|
|
|
case R.id.subtitle_button:
|
|
|
|
setupSubtitleSpinner();
|
|
|
|
flag = false;
|
|
|
|
break;
|
2017-05-15 05:57:57 +02:00
|
|
|
}
|
2018-09-23 20:12:23 +02:00
|
|
|
|
|
|
|
threadsSeekBar.setEnabled(flag);
|
2017-05-15 05:57:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onItemSelected(final AdapterView<?> parent, final View view,
|
|
|
|
final int position, final long id) {
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "onItemSelected() called with: "
|
|
|
|
+ "parent = [" + parent + "], view = [" + view + "], "
|
|
|
|
+ "position = [" + position + "], id = [" + id + "]");
|
|
|
|
}
|
2019-04-05 19:45:39 +02:00
|
|
|
switch (radioStreamsGroup.getCheckedRadioButtonId()) {
|
2017-05-15 05:57:57 +02:00
|
|
|
case R.id.audio_button:
|
|
|
|
selectedAudioIndex = position;
|
|
|
|
break;
|
|
|
|
case R.id.video_button:
|
|
|
|
selectedVideoIndex = position;
|
|
|
|
break;
|
2018-09-23 20:12:23 +02:00
|
|
|
case R.id.subtitle_button:
|
|
|
|
selectedSubtitleIndex = position;
|
|
|
|
break;
|
2017-05-15 05:57:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onNothingSelected(final AdapterView<?> parent) {
|
2017-05-15 05:57:57 +02:00
|
|
|
}
|
|
|
|
|
2018-04-08 13:08:19 +02:00
|
|
|
protected void setupDownloadOptions() {
|
|
|
|
setRadioButtonsState(false);
|
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
final RadioButton audioButton = radioStreamsGroup.findViewById(R.id.audio_button);
|
|
|
|
final RadioButton videoButton = radioStreamsGroup.findViewById(R.id.video_button);
|
|
|
|
final RadioButton subtitleButton = radioStreamsGroup.findViewById(R.id.subtitle_button);
|
2018-04-08 13:08:19 +02:00
|
|
|
final boolean isVideoStreamsAvailable = videoStreamsAdapter.getCount() > 0;
|
|
|
|
final boolean isAudioStreamsAvailable = audioStreamsAdapter.getCount() > 0;
|
2018-09-23 20:12:23 +02:00
|
|
|
final boolean isSubtitleStreamsAvailable = subtitleStreamsAdapter.getCount() > 0;
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2018-04-08 13:08:19 +02:00
|
|
|
audioButton.setVisibility(isAudioStreamsAvailable ? View.VISIBLE : View.GONE);
|
|
|
|
videoButton.setVisibility(isVideoStreamsAvailable ? View.VISIBLE : View.GONE);
|
2018-09-23 20:12:23 +02:00
|
|
|
subtitleButton.setVisibility(isSubtitleStreamsAvailable ? View.VISIBLE : View.GONE);
|
2018-04-08 13:08:19 +02:00
|
|
|
|
|
|
|
if (isVideoStreamsAvailable) {
|
2016-09-26 20:18:32 +02:00
|
|
|
videoButton.setChecked(true);
|
2018-04-08 13:08:19 +02:00
|
|
|
setupVideoSpinner();
|
|
|
|
} else if (isAudioStreamsAvailable) {
|
2016-09-26 20:18:32 +02:00
|
|
|
audioButton.setChecked(true);
|
2018-04-08 13:08:19 +02:00
|
|
|
setupAudioSpinner();
|
2018-09-23 20:12:23 +02:00
|
|
|
} else if (isSubtitleStreamsAvailable) {
|
|
|
|
subtitleButton.setChecked(true);
|
|
|
|
setupSubtitleSpinner();
|
2018-04-08 13:08:19 +02:00
|
|
|
} else {
|
2020-03-31 19:20:15 +02:00
|
|
|
Toast.makeText(getContext(), R.string.no_streams_available_download,
|
|
|
|
Toast.LENGTH_SHORT).show();
|
2018-04-08 13:08:19 +02:00
|
|
|
getDialog().dismiss();
|
2016-02-17 21:39:41 +01:00
|
|
|
}
|
2015-09-21 21:12:48 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private void setRadioButtonsState(final boolean enabled) {
|
2019-04-05 19:45:39 +02:00
|
|
|
radioStreamsGroup.findViewById(R.id.audio_button).setEnabled(enabled);
|
|
|
|
radioStreamsGroup.findViewById(R.id.video_button).setEnabled(enabled);
|
|
|
|
radioStreamsGroup.findViewById(R.id.subtitle_button).setEnabled(enabled);
|
2018-04-08 13:08:19 +02:00
|
|
|
}
|
2016-04-29 12:40:03 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private int getSubtitleIndexBy(final List<SubtitlesStream> streams) {
|
2019-10-28 03:35:51 +01:00
|
|
|
final Localization preferredLocalization = NewPipe.getPreferredLocalization();
|
2018-11-24 04:14:37 +01:00
|
|
|
|
2019-10-28 03:35:51 +01:00
|
|
|
int candidate = 0;
|
2018-11-24 04:14:37 +01:00
|
|
|
for (int i = 0; i < streams.size(); i++) {
|
2019-10-28 03:35:51 +01:00
|
|
|
final Locale streamLocale = streams.get(i).getLocale();
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
final boolean languageEquals = streamLocale.getLanguage() != null
|
|
|
|
&& preferredLocalization.getLanguageCode() != null
|
|
|
|
&& streamLocale.getLanguage()
|
|
|
|
.equals(new Locale(preferredLocalization.getLanguageCode()).getLanguage());
|
|
|
|
final boolean countryEquals = streamLocale.getCountry() != null
|
|
|
|
&& streamLocale.getCountry().equals(preferredLocalization.getCountryCode());
|
2019-10-28 03:35:51 +01:00
|
|
|
|
|
|
|
if (languageEquals) {
|
2020-03-31 19:20:15 +02:00
|
|
|
if (countryEquals) {
|
|
|
|
return i;
|
|
|
|
}
|
2018-11-24 04:14:37 +01:00
|
|
|
|
2019-10-28 03:35:51 +01:00
|
|
|
candidate = i;
|
2018-09-23 20:12:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-28 03:35:51 +01:00
|
|
|
return candidate;
|
2018-09-23 20:12:23 +02:00
|
|
|
}
|
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
private String getNameEditText() {
|
2019-04-09 23:38:34 +02:00
|
|
|
String str = nameEditText.getText().toString().trim();
|
|
|
|
|
|
|
|
return FilenameUtils.createFilename(context, str.isEmpty() ? currentInfo.getName() : str);
|
2019-04-05 19:45:39 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private void showFailedDialog(@StringRes final int msg) {
|
2020-01-31 22:49:43 +01:00
|
|
|
assureCorrectAppLanguage(getContext());
|
2019-04-09 23:38:34 +02:00
|
|
|
new AlertDialog.Builder(context)
|
2019-06-14 17:19:50 +02:00
|
|
|
.setTitle(R.string.general_error)
|
2019-04-05 19:45:39 +02:00
|
|
|
.setMessage(msg)
|
2020-01-31 22:49:43 +01:00
|
|
|
.setNegativeButton(getString(R.string.finish), null)
|
2019-04-05 19:45:39 +02:00
|
|
|
.create()
|
|
|
|
.show();
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private void showErrorActivity(final Exception e) {
|
2019-04-05 19:45:39 +02:00
|
|
|
ErrorActivity.reportError(
|
2019-04-09 23:38:34 +02:00
|
|
|
context,
|
2019-04-05 19:45:39 +02:00
|
|
|
Collections.singletonList(e),
|
|
|
|
null,
|
|
|
|
null,
|
2020-03-31 19:20:15 +02:00
|
|
|
ErrorActivity.ErrorInfo
|
|
|
|
.make(UserAction.SOMETHING_ELSE, "-", "-", R.string.general_error)
|
2019-04-05 19:45:39 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-09-23 20:12:23 +02:00
|
|
|
private void prepareSelectedDownload() {
|
2019-04-05 19:45:39 +02:00
|
|
|
StoredDirectoryHelper mainStorage;
|
|
|
|
MediaFormat format;
|
|
|
|
String mime;
|
2016-02-17 21:39:41 +01:00
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
// first, build the filename and get the output folder (if possible)
|
2019-04-09 23:38:34 +02:00
|
|
|
// later, run a very very very large file checking logic
|
2019-04-05 19:45:39 +02:00
|
|
|
|
2019-04-09 23:38:34 +02:00
|
|
|
String filename = getNameEditText().concat(".");
|
2018-09-23 20:12:23 +02:00
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
switch (radioStreamsGroup.getCheckedRadioButtonId()) {
|
2018-09-23 20:12:23 +02:00
|
|
|
case R.id.audio_button:
|
2019-04-05 19:45:39 +02:00
|
|
|
mainStorage = mainStorageAudio;
|
|
|
|
format = audioStreamsAdapter.getItem(selectedAudioIndex).getFormat();
|
2020-03-31 19:20:15 +02:00
|
|
|
switch (format) {
|
2019-12-29 21:56:32 +01:00
|
|
|
case WEBMA_OPUS:
|
|
|
|
mime = "audio/ogg";
|
|
|
|
filename += "opus";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
mime = format.mimeType;
|
|
|
|
filename += format.suffix;
|
|
|
|
break;
|
|
|
|
}
|
2018-09-23 20:12:23 +02:00
|
|
|
break;
|
|
|
|
case R.id.video_button:
|
2019-04-05 19:45:39 +02:00
|
|
|
mainStorage = mainStorageVideo;
|
|
|
|
format = videoStreamsAdapter.getItem(selectedVideoIndex).getFormat();
|
|
|
|
mime = format.mimeType;
|
2019-10-02 18:31:45 +02:00
|
|
|
filename += format.suffix;
|
2018-09-23 20:12:23 +02:00
|
|
|
break;
|
|
|
|
case R.id.subtitle_button:
|
2020-03-31 19:20:15 +02:00
|
|
|
mainStorage = mainStorageVideo; // subtitle & video files go together
|
2019-04-05 19:45:39 +02:00
|
|
|
format = subtitleStreamsAdapter.getItem(selectedSubtitleIndex).getFormat();
|
|
|
|
mime = format.mimeType;
|
|
|
|
filename += format == MediaFormat.TTML ? MediaFormat.SRT.suffix : format.suffix;
|
2018-09-23 20:12:23 +02:00
|
|
|
break;
|
|
|
|
default:
|
2019-04-05 19:45:39 +02:00
|
|
|
throw new RuntimeException("No stream selected");
|
2018-09-23 20:12:23 +02:00
|
|
|
}
|
|
|
|
|
2019-04-19 21:18:19 +02:00
|
|
|
if (mainStorage == null || askForSavePath) {
|
2019-04-09 23:38:34 +02:00
|
|
|
// This part is called if with SAF preferred:
|
|
|
|
// * older android version running
|
|
|
|
// * save path not defined (via download settings)
|
2019-08-14 20:30:34 +02:00
|
|
|
// * the user checked the "ask where to download" option
|
2018-09-23 20:12:23 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
if (!askForSavePath) {
|
|
|
|
Toast.makeText(context, getString(R.string.no_available_dir),
|
|
|
|
Toast.LENGTH_LONG).show();
|
|
|
|
}
|
2019-08-02 06:07:37 +02:00
|
|
|
|
2019-08-17 18:38:33 +02:00
|
|
|
if (NewPipeSettings.useStorageAccessFramework(context)) {
|
2020-03-31 19:20:15 +02:00
|
|
|
StoredFileHelper.requestSafWithFileCreation(this, REQUEST_DOWNLOAD_SAVE_AS,
|
|
|
|
filename, mime);
|
2019-08-15 04:00:11 +02:00
|
|
|
} else {
|
|
|
|
File initialSavePath;
|
2020-03-31 19:20:15 +02:00
|
|
|
if (radioStreamsGroup.getCheckedRadioButtonId() == R.id.audio_button) {
|
2019-08-15 04:00:11 +02:00
|
|
|
initialSavePath = NewPipeSettings.getDir(Environment.DIRECTORY_MUSIC);
|
2020-03-31 19:20:15 +02:00
|
|
|
} else {
|
2019-08-15 04:00:11 +02:00
|
|
|
initialSavePath = NewPipeSettings.getDir(Environment.DIRECTORY_MOVIES);
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
2019-08-15 04:00:11 +02:00
|
|
|
|
|
|
|
initialSavePath = new File(initialSavePath, filename);
|
2020-03-31 19:20:15 +02:00
|
|
|
startActivityForResult(FilePickerActivityHelper.chooseFileToSave(context,
|
|
|
|
initialSavePath.getAbsolutePath()), REQUEST_DOWNLOAD_SAVE_AS);
|
2019-08-15 04:00:11 +02:00
|
|
|
}
|
2019-08-15 03:15:42 +02:00
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
return;
|
2018-09-23 20:12:23 +02:00
|
|
|
}
|
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
// check for existing file with the same name
|
2019-04-09 23:38:34 +02:00
|
|
|
checkSelectedDownload(mainStorage, mainStorage.findFile(filename), filename, mime);
|
|
|
|
}
|
2019-04-05 19:45:39 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private void checkSelectedDownload(final StoredDirectoryHelper mainStorage,
|
|
|
|
final Uri targetFile, final String filename,
|
|
|
|
final String mime) {
|
2019-04-05 19:45:39 +02:00
|
|
|
StoredFileHelper storage;
|
2019-04-09 23:38:34 +02:00
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
try {
|
2019-04-09 23:38:34 +02:00
|
|
|
if (mainStorage == null) {
|
|
|
|
// using SAF on older android version
|
|
|
|
storage = new StoredFileHelper(context, null, targetFile, "");
|
|
|
|
} else if (targetFile == null) {
|
|
|
|
// the file does not exist, but it is probably used in a pending download
|
2020-03-31 19:20:15 +02:00
|
|
|
storage = new StoredFileHelper(mainStorage.getUri(), filename, mime,
|
|
|
|
mainStorage.getTag());
|
2019-04-09 23:38:34 +02:00
|
|
|
} else {
|
|
|
|
// the target filename is already use, attempt to use it
|
2020-03-31 19:20:15 +02:00
|
|
|
storage = new StoredFileHelper(context, mainStorage.getUri(), targetFile,
|
|
|
|
mainStorage.getTag());
|
2019-04-09 23:38:34 +02:00
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
2019-04-05 19:45:39 +02:00
|
|
|
showErrorActivity(e);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if is our file
|
|
|
|
MissionState state = downloadManager.checkForExistingMission(storage);
|
|
|
|
@StringRes int msgBtn;
|
|
|
|
@StringRes int msgBody;
|
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
case Finished:
|
|
|
|
msgBtn = R.string.overwrite;
|
|
|
|
msgBody = R.string.overwrite_finished_warning;
|
|
|
|
break;
|
|
|
|
case Pending:
|
|
|
|
msgBtn = R.string.overwrite;
|
|
|
|
msgBody = R.string.download_already_pending;
|
|
|
|
break;
|
|
|
|
case PendingRunning:
|
|
|
|
msgBtn = R.string.generate_unique_name;
|
|
|
|
msgBody = R.string.download_already_running;
|
|
|
|
break;
|
|
|
|
case None:
|
2019-04-09 23:38:34 +02:00
|
|
|
if (mainStorage == null) {
|
|
|
|
// This part is called if:
|
|
|
|
// * using SAF on older android version
|
|
|
|
// * save path not defined
|
2019-08-15 04:00:11 +02:00
|
|
|
// * if the file exists overwrite it, is not necessary ask
|
|
|
|
if (!storage.existsAsFile() && !storage.create()) {
|
|
|
|
showFailedDialog(R.string.error_file_creation);
|
|
|
|
return;
|
|
|
|
}
|
2019-04-09 23:38:34 +02:00
|
|
|
continueSelectedDownload(storage);
|
|
|
|
return;
|
|
|
|
} else if (targetFile == null) {
|
|
|
|
// This part is called if:
|
|
|
|
// * the filename is not used in a pending/finished download
|
|
|
|
// * the file does not exists, create
|
2019-06-14 17:19:50 +02:00
|
|
|
|
|
|
|
if (!mainStorage.mkdirs()) {
|
|
|
|
showFailedDialog(R.string.error_path_creation);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-09 23:38:34 +02:00
|
|
|
storage = mainStorage.createFile(filename, mime);
|
|
|
|
if (storage == null || !storage.canWrite()) {
|
|
|
|
showFailedDialog(R.string.error_file_creation);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
continueSelectedDownload(storage);
|
|
|
|
return;
|
|
|
|
}
|
2019-04-05 19:45:39 +02:00
|
|
|
msgBtn = R.string.overwrite;
|
|
|
|
msgBody = R.string.overwrite_unrelated_warning;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-09 23:38:34 +02:00
|
|
|
|
|
|
|
AlertDialog.Builder askDialog = new AlertDialog.Builder(context)
|
|
|
|
.setTitle(R.string.download_dialog_title)
|
2019-04-05 19:45:39 +02:00
|
|
|
.setMessage(msgBody)
|
2019-04-09 23:38:34 +02:00
|
|
|
.setNegativeButton(android.R.string.cancel, null);
|
|
|
|
final StoredFileHelper finalStorage = storage;
|
|
|
|
|
|
|
|
|
|
|
|
if (mainStorage == null) {
|
|
|
|
// This part is called if:
|
|
|
|
// * using SAF on older android version
|
|
|
|
// * save path not defined
|
|
|
|
switch (state) {
|
|
|
|
case Pending:
|
|
|
|
case Finished:
|
|
|
|
askDialog.setPositiveButton(msgBtn, (dialog, which) -> {
|
|
|
|
dialog.dismiss();
|
|
|
|
downloadManager.forgetMission(finalStorage);
|
|
|
|
continueSelectedDownload(finalStorage);
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
askDialog.create().show();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
askDialog.setPositiveButton(msgBtn, (dialog, which) -> {
|
|
|
|
dialog.dismiss();
|
|
|
|
|
|
|
|
StoredFileHelper storageNew;
|
|
|
|
switch (state) {
|
|
|
|
case Finished:
|
|
|
|
case Pending:
|
|
|
|
downloadManager.forgetMission(finalStorage);
|
|
|
|
case None:
|
|
|
|
if (targetFile == null) {
|
|
|
|
storageNew = mainStorage.createFile(filename, mime);
|
|
|
|
} else {
|
|
|
|
try {
|
|
|
|
// try take (or steal) the file
|
2020-03-31 19:20:15 +02:00
|
|
|
storageNew = new StoredFileHelper(context, mainStorage.getUri(),
|
|
|
|
targetFile, mainStorage.getTag());
|
2019-04-09 23:38:34 +02:00
|
|
|
} catch (IOException e) {
|
2020-03-31 19:20:15 +02:00
|
|
|
Log.e(TAG, "Failed to take (or steal) the file in "
|
|
|
|
+ targetFile.toString());
|
2019-04-09 23:38:34 +02:00
|
|
|
storageNew = null;
|
|
|
|
}
|
2019-04-05 19:45:39 +02:00
|
|
|
}
|
2019-04-09 23:38:34 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
if (storageNew != null && storageNew.canWrite()) {
|
2019-04-09 23:38:34 +02:00
|
|
|
continueSelectedDownload(storageNew);
|
2020-03-31 19:20:15 +02:00
|
|
|
} else {
|
2019-04-09 23:38:34 +02:00
|
|
|
showFailedDialog(R.string.error_file_creation);
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
2019-04-09 23:38:34 +02:00
|
|
|
break;
|
|
|
|
case PendingRunning:
|
|
|
|
storageNew = mainStorage.createUniqueFile(filename, mime);
|
2020-03-31 19:20:15 +02:00
|
|
|
if (storageNew == null) {
|
2019-04-09 23:38:34 +02:00
|
|
|
showFailedDialog(R.string.error_file_creation);
|
2020-03-31 19:20:15 +02:00
|
|
|
} else {
|
2019-04-09 23:38:34 +02:00
|
|
|
continueSelectedDownload(storageNew);
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
2019-04-09 23:38:34 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
askDialog.create().show();
|
2018-09-23 20:12:23 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private void continueSelectedDownload(@NonNull final StoredFileHelper storage) {
|
2019-04-05 19:45:39 +02:00
|
|
|
if (!storage.canWrite()) {
|
|
|
|
showFailedDialog(R.string.permission_denied);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if the selected file has to be overwritten, by simply checking its length
|
|
|
|
try {
|
2020-03-31 19:20:15 +02:00
|
|
|
if (storage.length() > 0) {
|
|
|
|
storage.truncate();
|
|
|
|
}
|
2019-04-05 19:45:39 +02:00
|
|
|
} catch (IOException e) {
|
2019-08-14 20:30:34 +02:00
|
|
|
Log.e(TAG, "failed to truncate the file: " + storage.getUri().toString(), e);
|
2019-04-05 19:45:39 +02:00
|
|
|
showFailedDialog(R.string.overwrite_failed);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Stream selectedStream;
|
2019-09-28 23:11:05 +02:00
|
|
|
Stream secondaryStream = null;
|
2019-04-05 19:45:39 +02:00
|
|
|
char kind;
|
|
|
|
int threads = threadsSeekBar.getProgress() + 1;
|
2018-09-23 20:12:23 +02:00
|
|
|
String[] urls;
|
2019-09-28 23:11:05 +02:00
|
|
|
MissionRecoveryInfo[] recoveryInfo;
|
2018-09-23 20:12:23 +02:00
|
|
|
String psName = null;
|
|
|
|
String[] psArgs = null;
|
2018-11-20 23:10:50 +01:00
|
|
|
long nearLength = 0;
|
2018-09-23 20:12:23 +02:00
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
// more download logic: select muxer, subtitle converter, etc.
|
|
|
|
switch (radioStreamsGroup.getCheckedRadioButtonId()) {
|
|
|
|
case R.id.audio_button:
|
|
|
|
kind = 'a';
|
|
|
|
selectedStream = audioStreamsAdapter.getItem(selectedAudioIndex);
|
|
|
|
|
|
|
|
if (selectedStream.getFormat() == MediaFormat.M4A) {
|
|
|
|
psName = Postprocessing.ALGORITHM_M4A_NO_DASH;
|
2019-11-26 17:41:16 +01:00
|
|
|
} else if (selectedStream.getFormat() == MediaFormat.WEBMA_OPUS) {
|
2019-09-24 02:38:29 +02:00
|
|
|
psName = Postprocessing.ALGORITHM_OGG_FROM_WEBM_DEMUXER;
|
2018-09-23 20:12:23 +02:00
|
|
|
}
|
2019-04-05 19:45:39 +02:00
|
|
|
break;
|
|
|
|
case R.id.video_button:
|
|
|
|
kind = 'v';
|
|
|
|
selectedStream = videoStreamsAdapter.getItem(selectedVideoIndex);
|
|
|
|
|
2019-09-28 23:11:05 +02:00
|
|
|
SecondaryStreamHelper<AudioStream> secondary = videoStreamsAdapter
|
2019-04-05 19:45:39 +02:00
|
|
|
.getAllSecondary()
|
|
|
|
.get(wrappedVideoStreams.getStreamsList().indexOf(selectedStream));
|
|
|
|
|
2019-09-28 23:11:05 +02:00
|
|
|
if (secondary != null) {
|
|
|
|
secondaryStream = secondary.getStream();
|
2019-04-05 19:45:39 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
if (selectedStream.getFormat() == MediaFormat.MPEG_4) {
|
2019-04-05 19:45:39 +02:00
|
|
|
psName = Postprocessing.ALGORITHM_MP4_FROM_DASH_MUXER;
|
2020-03-31 19:20:15 +02:00
|
|
|
} else {
|
2019-04-05 19:45:39 +02:00
|
|
|
psName = Postprocessing.ALGORITHM_WEBM_MUXER;
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
2019-04-05 19:45:39 +02:00
|
|
|
|
|
|
|
psArgs = null;
|
2020-03-31 19:20:15 +02:00
|
|
|
long videoSize = wrappedVideoStreams
|
|
|
|
.getSizeInBytes((VideoStream) selectedStream);
|
2019-04-05 19:45:39 +02:00
|
|
|
|
2019-04-25 05:34:29 +02:00
|
|
|
// set nearLength, only, if both sizes are fetched or known. This probably
|
|
|
|
// does not work on slow networks but is later updated in the downloader
|
2019-09-28 23:11:05 +02:00
|
|
|
if (secondary.getSizeInBytes() > 0 && videoSize > 0) {
|
|
|
|
nearLength = secondary.getSizeInBytes() + videoSize;
|
2019-04-05 19:45:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case R.id.subtitle_button:
|
2020-03-31 19:20:15 +02:00
|
|
|
threads = 1; // use unique thread for subtitles due small file size
|
2019-04-05 19:45:39 +02:00
|
|
|
kind = 's';
|
|
|
|
selectedStream = subtitleStreamsAdapter.getItem(selectedSubtitleIndex);
|
|
|
|
|
|
|
|
if (selectedStream.getFormat() == MediaFormat.TTML) {
|
|
|
|
psName = Postprocessing.ALGORITHM_TTML_CONVERTER;
|
|
|
|
psArgs = new String[]{
|
|
|
|
selectedStream.getFormat().getSuffix(),
|
2020-03-31 19:20:15 +02:00
|
|
|
"false" // ignore empty frames
|
2019-04-05 19:45:39 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
2018-09-23 20:12:23 +02:00
|
|
|
}
|
2016-02-17 21:39:41 +01:00
|
|
|
|
2019-09-28 23:11:05 +02:00
|
|
|
if (secondaryStream == null) {
|
|
|
|
urls = new String[]{
|
|
|
|
selectedStream.getUrl()
|
|
|
|
};
|
|
|
|
recoveryInfo = new MissionRecoveryInfo[]{
|
|
|
|
new MissionRecoveryInfo(selectedStream)
|
|
|
|
};
|
2017-12-08 15:05:08 +01:00
|
|
|
} else {
|
2019-09-28 23:11:05 +02:00
|
|
|
urls = new String[]{
|
|
|
|
selectedStream.getUrl(), secondaryStream.getUrl()
|
|
|
|
};
|
2020-03-31 19:20:15 +02:00
|
|
|
recoveryInfo = new MissionRecoveryInfo[]{new MissionRecoveryInfo(selectedStream),
|
|
|
|
new MissionRecoveryInfo(secondaryStream)};
|
2017-12-08 15:05:08 +01:00
|
|
|
}
|
2016-03-25 19:01:22 +01:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
DownloadManagerService.startMission(context, urls, storage, kind, threads,
|
|
|
|
currentInfo.getUrl(), psName, psArgs, nearLength, recoveryInfo);
|
2018-04-08 13:08:19 +02:00
|
|
|
|
2019-04-05 19:45:39 +02:00
|
|
|
dismiss();
|
2016-02-17 21:39:41 +01:00
|
|
|
}
|
2015-09-21 21:12:48 +02:00
|
|
|
}
|