diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java
index 4902b63f2..84770ac68 100644
--- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java
+++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java
@@ -1,113 +1,135 @@
package org.schabi.newpipe.download;
-import android.Manifest;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.net.Uri;
import android.os.Bundle;
+import android.support.annotation.IdRes;
import android.support.annotation.Nullable;
-import android.support.v4.app.ActivityCompat;
import android.support.v4.app.DialogFragment;
-import android.support.v4.content.ContextCompat;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.RadioButton;
+import android.widget.RadioGroup;
import android.widget.SeekBar;
+import android.widget.Spinner;
import android.widget.TextView;
-import org.schabi.newpipe.App;
+import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
+import org.schabi.newpipe.extractor.MediaFormat;
+import org.schabi.newpipe.extractor.stream_info.AudioStream;
+import org.schabi.newpipe.extractor.stream_info.StreamInfo;
+import org.schabi.newpipe.extractor.stream_info.VideoStream;
+import org.schabi.newpipe.fragments.detail.SpinnerToolbarAdapter;
import org.schabi.newpipe.settings.NewPipeSettings;
+import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.ThemeHelper;
+import org.schabi.newpipe.util.Utils;
-import java.io.File;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import us.shandian.giga.service.DownloadManagerService;
+public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheckedChangeListener, AdapterView.OnItemSelectedListener {
+ private static final String TAG = "DialogFragment";
+ private static final boolean DEBUG = MainActivity.DEBUG;
-/**
- * Created by Christian Schabesberger on 21.09.15.
- *
- * Copyright (C) Christian Schabesberger 2015
- * DownloadDialog.java is part of NewPipe.
- *
- * NewPipe is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * NewPipe is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with NewPipe. If not, see .
- */
+ private static final String INFO_KEY = "info_key";
+ private static final String SORTED_VIDEOS_LIST_KEY = "sorted_videos_list_key";
+ private static final String SELECTED_VIDEO_KEY = "selected_video_key";
+ private static final String SELECTED_AUDIO_KEY = "selected_audio_key";
-public class DownloadDialog extends DialogFragment {
- private static final String TAG = DialogFragment.class.getName();
+ private StreamInfo currentInfo;
+ private ArrayList sortedStreamVideosList;
+ private int selectedVideoIndex;
+ private int selectedAudioIndex;
- public static final String TITLE = "name";
- public static final String FILE_SUFFIX_AUDIO = "file_suffix_audio";
- public static final String FILE_SUFFIX_VIDEO = "file_suffix_video";
- public static final String AUDIO_URL = "audio_url";
- public static final String VIDEO_URL = "video_url";
+ private EditText nameEditText;
+ private Spinner streamsSpinner;
+ private RadioGroup radioVideoAudioGroup;
+ private TextView threadsCountTextView;
+ private SeekBar threadsSeekBar;
- public DownloadDialog() {
-
- }
-
- public static DownloadDialog newInstance(Bundle args) {
+ public static DownloadDialog newInstance(StreamInfo info, ArrayList sortedStreamVideosList, int selectedVideoIndex) {
DownloadDialog dialog = new DownloadDialog();
- dialog.setArguments(args);
+ dialog.setInfo(info, sortedStreamVideosList, selectedVideoIndex);
dialog.setStyle(DialogFragment.STYLE_NO_TITLE, 0);
return dialog;
}
+ private void setInfo(StreamInfo info, ArrayList sortedStreamVideosList, int selectedVideoIndex) {
+ this.currentInfo = info;
+ this.selectedVideoIndex = selectedVideoIndex;
+ this.sortedStreamVideosList = sortedStreamVideosList;
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // LifeCycle
+ //////////////////////////////////////////////////////////////////////////*/
+
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (DEBUG) Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
+ if (!PermissionHelper.checkStoragePermissions(getActivity())) {
+ getDialog().dismiss();
+ return;
+ }
- if(ContextCompat.checkSelfPermission(this.getContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
- ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0);
+ if (savedInstanceState != null) {
+ Serializable serial = savedInstanceState.getSerializable(INFO_KEY);
+ if (serial instanceof StreamInfo) currentInfo = (StreamInfo) serial;
+ serial = savedInstanceState.getSerializable(SORTED_VIDEOS_LIST_KEY);
+ if (serial instanceof ArrayList) { //noinspection unchecked
+ sortedStreamVideosList = (ArrayList) serial;
+ }
+
+ selectedVideoIndex = savedInstanceState.getInt(SELECTED_VIDEO_KEY, 0);
+ selectedAudioIndex = savedInstanceState.getInt(SELECTED_AUDIO_KEY, 0);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ if (DEBUG) Log.d(TAG, "onCreateView() called with: inflater = [" + inflater + "], container = [" + container + "], savedInstanceState = [" + savedInstanceState + "]");
return inflater.inflate(R.layout.dialog_url, container);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
+ nameEditText = ((EditText) view.findViewById(R.id.file_name));
+ nameEditText.setText(createFileName(currentInfo.title));
+ selectedAudioIndex = Utils.getPreferredAudioFormat(getContext(), currentInfo.audio_streams);
- Bundle arguments = getArguments();
- final Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
- final EditText name = (EditText) view.findViewById(R.id.file_name);
- final TextView tCount = (TextView) view.findViewById(R.id.threads_count);
- final SeekBar threads = (SeekBar) view.findViewById(R.id.threads);
+ streamsSpinner = (Spinner) view.findViewById(R.id.quality_spinner);
+ streamsSpinner.setOnItemSelectedListener(this);
- toolbar.setTitle(R.string.download_dialog_title);
- toolbar.setNavigationIcon(ThemeHelper.isLightThemeSelected(getActivity()) ? R.drawable.ic_arrow_back_black_24dp : R.drawable.ic_arrow_back_white_24dp);
- toolbar.inflateMenu(R.menu.dialog_url);
- toolbar.setNavigationOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getDialog().dismiss();
- }
- });
+ threadsCountTextView = (TextView) view.findViewById(R.id.threads_count);
+ threadsSeekBar = (SeekBar) view.findViewById(R.id.threads);
+ radioVideoAudioGroup = (RadioGroup) view.findViewById(R.id.video_audio_group);
+ radioVideoAudioGroup.setOnCheckedChangeListener(this);
- threads.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ initToolbar((Toolbar) view.findViewById(R.id.toolbar));
+ checkDownloadOptions(view);
+ setupVideoSpinner(sortedStreamVideosList, streamsSpinner);
+
+ int def = 3;
+ threadsCountTextView.setText(String.valueOf(def));
+ threadsSeekBar.setProgress(def - 1);
+ threadsSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
- tCount.setText(String.valueOf(progress + 1));
+ threadsCountTextView.setText(String.valueOf(progress + 1));
}
@Override
@@ -120,41 +142,111 @@ public class DownloadDialog extends DialogFragment {
}
});
+ }
- checkDownloadOptions();
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putSerializable(INFO_KEY, currentInfo);
+ outState.putSerializable(SORTED_VIDEOS_LIST_KEY, sortedStreamVideosList);
+ outState.putInt(SELECTED_VIDEO_KEY, selectedVideoIndex);
+ outState.putInt(SELECTED_AUDIO_KEY, selectedAudioIndex);
+ }
- //int def = mPrefs.getInt("threads", 4);
- int def = 3;
- threads.setProgress(def - 1);
- tCount.setText(String.valueOf(def));
-
- name.setText(createFileName(arguments.getString(TITLE)));
+ /*//////////////////////////////////////////////////////////////////////////
+ // Inits
+ //////////////////////////////////////////////////////////////////////////*/
+ private void initToolbar(Toolbar toolbar) {
+ if (DEBUG) Log.d(TAG, "initToolbar() called with: toolbar = [" + toolbar + "]");
+ toolbar.setTitle(R.string.download_dialog_title);
+ toolbar.setNavigationIcon(ThemeHelper.isLightThemeSelected(getActivity()) ? R.drawable.ic_arrow_back_black_24dp : R.drawable.ic_arrow_back_white_24dp);
+ toolbar.inflateMenu(R.menu.dialog_url);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getDialog().dismiss();
+ }
+ });
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.okay) {
- download();
+ downloadSelected();
return true;
- } else {
- return false;
- }
+ } else return false;
}
});
-
}
- protected void checkDownloadOptions() {
- View view = getView();
- Bundle arguments = getArguments();
+ public void setupAudioSpinner(final List audioStreams, Spinner spinner) {
+ String[] items = new String[audioStreams.size()];
+ for (int i = 0; i < audioStreams.size(); i++) {
+ AudioStream audioStream = audioStreams.get(i);
+ items[i] = MediaFormat.getNameById(audioStream.format) + " " + audioStream.avgBitrate + "kbps";
+ }
+
+ ArrayAdapter itemAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_dropdown_item, items);
+ spinner.setAdapter(itemAdapter);
+ spinner.setSelection(selectedAudioIndex);
+ }
+
+ public void setupVideoSpinner(final List videoStreams, Spinner spinner) {
+ spinner.setAdapter(new SpinnerToolbarAdapter(getContext(), videoStreams, true));
+ spinner.setSelection(selectedVideoIndex);
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Radio group Video&Audio options - Listener
+ //////////////////////////////////////////////////////////////////////////*/
+
+ @Override
+ public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
+ if (DEBUG) Log.d(TAG, "onCheckedChanged() called with: group = [" + group + "], checkedId = [" + checkedId + "]");
+ switch (checkedId) {
+ case R.id.audio_button:
+ setupAudioSpinner(currentInfo.audio_streams, streamsSpinner);
+ break;
+ case R.id.video_button:
+ setupVideoSpinner(sortedStreamVideosList, streamsSpinner);
+ break;
+ }
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Streams Spinner Listener
+ //////////////////////////////////////////////////////////////////////////*/
+
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ if (DEBUG) Log.d(TAG, "onItemSelected() called with: parent = [" + parent + "], view = [" + view + "], position = [" + position + "], id = [" + id + "]");
+ switch (radioVideoAudioGroup.getCheckedRadioButtonId()) {
+ case R.id.audio_button:
+ selectedAudioIndex = position;
+ break;
+ case R.id.video_button:
+ selectedVideoIndex = position;
+ break;
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Utils
+ //////////////////////////////////////////////////////////////////////////*/
+
+ protected void checkDownloadOptions(View view) {
RadioButton audioButton = (RadioButton) view.findViewById(R.id.audio_button);
RadioButton videoButton = (RadioButton) view.findViewById(R.id.video_button);
- if (arguments.getString(AUDIO_URL) == null) {
+ if (currentInfo.audio_streams == null || currentInfo.audio_streams.size() == 0) {
audioButton.setVisibility(View.GONE);
videoButton.setChecked(true);
- } else if (arguments.getString(VIDEO_URL) == null) {
+ } else if (sortedStreamVideosList == null || sortedStreamVideosList.size() == 0) {
videoButton.setVisibility(View.GONE);
audioButton.setChecked(true);
}
@@ -164,14 +256,14 @@ public class DownloadDialog extends DialogFragment {
* #143 #44 #42 #22: make shure that the filename does not contain illegal chars.
* This should fix some of the "cannot download" problems.
*/
- private String createFileName(String fName) {
+ private String createFileName(String fileName) {
// from http://eng-przemelek.blogspot.de/2009/07/how-to-create-valid-file-name.html
List forbiddenCharsPatterns = new ArrayList<>();
forbiddenCharsPatterns.add("[:]+"); // Mac OS, but it looks that also Windows XP
forbiddenCharsPatterns.add("[\\*\"/\\\\\\[\\]\\:\\;\\|\\=\\,]+"); // Windows
forbiddenCharsPatterns.add("[^\\w\\d\\.]+"); // last chance... only latin letters and digits
- String nameToTest = fName;
+ String nameToTest = fileName;
for (String pattern : forbiddenCharsPatterns) {
nameToTest = nameToTest.replaceAll(pattern, "_");
}
@@ -179,55 +271,20 @@ public class DownloadDialog extends DialogFragment {
}
- //download audio, video or both?
- private void download() {
- View view = getView();
- Bundle arguments = getArguments();
- final EditText name = (EditText) view.findViewById(R.id.file_name);
- final SeekBar threads = (SeekBar) view.findViewById(R.id.threads);
- RadioButton audioButton = (RadioButton) view.findViewById(R.id.audio_button);
- RadioButton videoButton = (RadioButton) view.findViewById(R.id.video_button);
+ private void downloadSelected() {
+ String url, location;
- String fName = name.getText().toString().trim();
+ String fileName = nameEditText.getText().toString().trim();
+ if (fileName.isEmpty()) fileName = createFileName(currentInfo.title);
- boolean isAudio = audioButton.isChecked();
- String url, location, filename;
- if (isAudio) {
- url = arguments.getString(AUDIO_URL);
- location = NewPipeSettings.getAudioDownloadPath(getContext());
- filename = fName + arguments.getString(FILE_SUFFIX_AUDIO);
- } else {
- url = arguments.getString(VIDEO_URL);
- location = NewPipeSettings.getVideoDownloadPath(getContext());
- filename = fName + arguments.getString(FILE_SUFFIX_VIDEO);
- }
+ boolean isAudio = radioVideoAudioGroup.getCheckedRadioButtonId() == R.id.audio_button;
+ url = isAudio ? currentInfo.audio_streams.get(selectedAudioIndex).url : sortedStreamVideosList.get(selectedVideoIndex).url;
+ location = isAudio ? NewPipeSettings.getAudioDownloadPath(getContext()) : NewPipeSettings.getVideoDownloadPath(getContext());
- DownloadManagerService.startMission(getContext(), url, location, filename, isAudio,
- threads.getProgress() + 1);
+ if (isAudio) fileName += "." + MediaFormat.getSuffixById(currentInfo.audio_streams.get(selectedAudioIndex).format);
+ else fileName += "." + MediaFormat.getSuffixById(sortedStreamVideosList.get(selectedVideoIndex).format);
+ DownloadManagerService.startMission(getContext(), url, location, fileName, isAudio, threadsSeekBar.getProgress() + 1);
getDialog().dismiss();
}
-
- private void download(String url, String title,
- String fileSuffix, File downloadDir, Context context) {
-
- File saveFilePath = new File(downloadDir, createFileName(title) + fileSuffix);
-
- long id = 0;
-
- Log.i(TAG, "Started downloading '" + url +
- "' => '" + saveFilePath + "' #" + id);
-
- if (App.isUsingTor()) {
- //if using Tor, do not use DownloadManager because the proxy cannot be set
- //we'll see later
- FileDownloader.downloadFile(getContext(), url, saveFilePath, title);
- } else {
- Intent intent = new Intent(getContext(), DownloadActivity.class);
- intent.setAction(DownloadActivity.INTENT_DOWNLOAD);
- intent.setData(Uri.parse(url));
- intent.putExtra("fileName", createFileName(title) + fileSuffix);
- startActivity(intent);
- }
- }
}
diff --git a/app/src/main/java/org/schabi/newpipe/download/FileDownloader.java b/app/src/main/java/org/schabi/newpipe/download/FileDownloader.java
deleted file mode 100644
index b097a035a..000000000
--- a/app/src/main/java/org/schabi/newpipe/download/FileDownloader.java
+++ /dev/null
@@ -1,165 +0,0 @@
-package org.schabi.newpipe.download;
-
-import android.app.NotificationManager;
-import android.content.Context;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
-import android.support.v4.app.NotificationCompat;
-import android.util.Log;
-
-import org.schabi.newpipe.R;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-
-import javax.net.ssl.HttpsURLConnection;
-
-import info.guardianproject.netcipher.NetCipher;
-
-/**
- * Created by Christian Schabesberger on 14.08.15.
- *
- * Copyright (C) Christian Schabesberger 2015
- * FileDownloader.java is part of NewPipe.
- *
- * NewPipe is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * NewPipe is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with NewPipe. If not, see .
- */
-
-
-// TODO: FOR HEAVEN SAKE !!! DO NOT SIMPLY USE ASYNCTASK. MAKE THIS A PROPER SERVICE !!!
-public class FileDownloader extends AsyncTask {
- public static final String TAG = "FileDownloader";
-
-
- private NotificationManager nm;
- private NotificationCompat.Builder builder;
- private int notifyId = 0x1234;
- private int fileSize = 0xffffffff;
-
- private final Context context;
- private final String fileURL;
- private final File saveFilePath;
- private final String title;
-
- private final String debugContext;
-
- public FileDownloader(Context context, String fileURL, File saveFilePath, String title) {
- this.context = context;
- this.fileURL = fileURL;
- this.saveFilePath = saveFilePath;
- this.title = title;
-
- this.debugContext = "'" + fileURL +
- "' => '" + saveFilePath + "'";
- }
-
- /**
- * Downloads a file from a URL in the background using an {@link AsyncTask}.
- *
- * @param fileURL HTTP URL of the file to be downloaded
- * @param saveFilePath path of the directory to save the file
- * @param title
- * @throws IOException
- */
- public static void downloadFile(final Context context, final String fileURL, final File saveFilePath, String title) {
- new FileDownloader(context, fileURL, saveFilePath, title).execute();
- }
-
- /** AsyncTask impl: executed in gui thread */
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
- Drawable icon = context.getResources().getDrawable(R.mipmap.ic_launcher);
- builder = new NotificationCompat.Builder(context)
- .setSmallIcon(android.R.drawable.stat_sys_download)
- .setLargeIcon(((BitmapDrawable) icon).getBitmap())
- .setContentTitle(saveFilePath.getName())
- .setContentText(saveFilePath.getAbsolutePath())
- .setProgress(fileSize, 0, false);
- nm.notify(notifyId, builder.build());
- }
-
- /** AsyncTask impl: executed in background thread does the download */
- @Override
- protected Void doInBackground(Void... voids) {
- HttpsURLConnection con = null;
- InputStream inputStream = null;
- FileOutputStream outputStream = null;
- try {
- con = NetCipher.getHttpsURLConnection(fileURL);
- int responseCode = con.getResponseCode();
-
- // always check HTTP response code first
- if (responseCode == HttpURLConnection.HTTP_OK) {
- fileSize = con.getContentLength();
- inputStream = new BufferedInputStream(con.getInputStream());
- outputStream = new FileOutputStream(saveFilePath);
-
- int bufferSize = 8192;
- int downloaded = 0;
-
- int bytesRead = -1;
- byte[] buffer = new byte[bufferSize];
- while ((bytesRead = inputStream.read(buffer)) != -1) {
- outputStream.write(buffer, 0, bytesRead);
- downloaded += bytesRead;
- if (downloaded % 50000 < bufferSize) {
- publishProgress(downloaded);
- }
- }
-
- publishProgress(bufferSize);
-
- } else {
- Log.i(TAG, "No file to download. Server replied HTTP code: " + responseCode);
- }
- } catch (IOException e) {
- Log.e(TAG, "No file to download. Server replied HTTP code: ", e);
- e.printStackTrace();
- } finally {
- try {
- if (outputStream != null) {
- outputStream.close();
- }
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- if (con != null) {
- con.disconnect();
- }
- }
- return null;
- }
-
- @Override
- protected void onProgressUpdate(Integer... progress) {
- builder.setProgress(fileSize, progress[0], false);
- nm.notify(notifyId, builder.build());
- }
-
- @Override
- protected void onPostExecute(Void aVoid) {
- super.onPostExecute(aVoid);
- nm.cancel(notifyId);
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/ActionBarHandler.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/ActionBarHandler.java
index 41a927d16..73f2551b0 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/detail/ActionBarHandler.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/ActionBarHandler.java
@@ -9,11 +9,9 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
import android.widget.Spinner;
import org.schabi.newpipe.R;
-import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.stream_info.VideoStream;
import org.schabi.newpipe.util.Utils;
@@ -71,16 +69,9 @@ class ActionBarHandler {
if (activity == null) return;
selectedVideoStream = 0;
- // this array will be shown in the dropdown menu for selecting the stream/resolution.
- String[] itemArray = new String[videoStreams.size()];
- for (int i = 0; i < videoStreams.size(); i++) {
- VideoStream item = videoStreams.get(i);
- itemArray[i] = MediaFormat.getNameById(item.format) + " " + item.resolution;
- }
-
int defaultResolutionIndex = Utils.getDefaultResolution(activity, videoStreams);
- ArrayAdapter itemAdapter = new ArrayAdapter<>(activity.getBaseContext(), android.R.layout.simple_spinner_dropdown_item, itemArray);
- toolbarSpinner.setAdapter(itemAdapter);
+ boolean isExternalPlayerEnabled = PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(activity.getString(R.string.use_external_video_player_key), false);
+ toolbarSpinner.setAdapter(new SpinnerToolbarAdapter(activity, videoStreams, isExternalPlayerEnabled));
toolbarSpinner.setSelection(defaultResolutionIndex);
toolbarSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/SpinnerToolbarAdapter.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/SpinnerToolbarAdapter.java
new file mode 100644
index 000000000..f93512fc7
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/SpinnerToolbarAdapter.java
@@ -0,0 +1,74 @@
+package org.schabi.newpipe.fragments.detail;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import org.schabi.newpipe.R;
+import org.schabi.newpipe.extractor.MediaFormat;
+import org.schabi.newpipe.extractor.stream_info.VideoStream;
+
+import java.util.List;
+
+public class SpinnerToolbarAdapter extends BaseAdapter {
+ private final List videoStreams;
+ private final boolean showIconNoAudio;
+
+ private final Context context;
+
+ public SpinnerToolbarAdapter(Context context, List videoStreams, boolean showIconNoAudio) {
+ this.context = context;
+ this.videoStreams = videoStreams;
+ this.showIconNoAudio = showIconNoAudio;
+ }
+
+ @Override
+ public int getCount() {
+ return videoStreams.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return videoStreams.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ return getCustomView(position, convertView, parent, true);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return getCustomView(((Spinner) parent).getSelectedItemPosition(), convertView, parent, false);
+ }
+
+ private View getCustomView(int position, View convertView, ViewGroup parent, boolean isDropdownItem) {
+ if (convertView == null) {
+ convertView = LayoutInflater.from(context).inflate(R.layout.resolutions_spinner_item, parent, false);
+ }
+
+ ImageView woSoundIcon = (ImageView) convertView.findViewById(R.id.wo_sound_icon);
+ TextView text = (TextView) convertView.findViewById(android.R.id.text1);
+ VideoStream item = (VideoStream) getItem(position);
+ text.setText(MediaFormat.getNameById(item.format) + " " + item.resolution);
+
+ int visibility = !showIconNoAudio ? View.GONE
+ : item.isVideoOnly ? View.VISIBLE
+ : isDropdownItem ? View.INVISIBLE
+ : View.GONE;
+ woSoundIcon.setVisibility(visibility);
+
+ return convertView;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
index 030028d64..6eb070ae6 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
@@ -330,7 +330,8 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
updateFlags |= RELATED_STREAMS_UPDATE_FLAG;
} else if (key.equals(getString(R.string.preferred_video_format_key))
|| key.equals(getString(R.string.default_resolution_key))
- || key.equals(getString(R.string.show_higher_resolutions_key))) {
+ || key.equals(getString(R.string.show_higher_resolutions_key))
+ || key.equals(getString(R.string.use_external_video_player_key))) {
updateFlags |= RESOLUTIONS_MENU_UPDATE_FLAG;
} else if (key.equals(getString(R.string.show_play_with_kodi_key))) {
updateFlags |= TOOLBAR_ITEMS_UPDATE_FLAG;
@@ -682,33 +683,10 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
}
try {
- Bundle args = new Bundle();
-
- // Sometimes it may be that some information is not available due to changes fo the
- // website which was crawled. Then the ui has to understand this and act right.
-
- if (info.audio_streams != null) {
- AudioStream audioStream =
- info.audio_streams.get(Utils.getPreferredAudioFormat(activity, info.audio_streams));
-
- String audioSuffix = "." + MediaFormat.getSuffixById(audioStream.format);
- args.putString(DownloadDialog.AUDIO_URL, audioStream.url);
- args.putString(DownloadDialog.FILE_SUFFIX_AUDIO, audioSuffix);
- }
-
- if (sortedStreamVideosList != null) {
- VideoStream selectedStreamItem = sortedStreamVideosList.get(selectedStreamId);
- String videoSuffix = "." + MediaFormat.getSuffixById(selectedStreamItem.format);
- args.putString(DownloadDialog.FILE_SUFFIX_VIDEO, videoSuffix);
- args.putString(DownloadDialog.VIDEO_URL, selectedStreamItem.url);
- }
-
- args.putString(DownloadDialog.TITLE, info.title);
- DownloadDialog downloadDialog = DownloadDialog.newInstance(args);
+ DownloadDialog downloadDialog = DownloadDialog.newInstance(info, sortedStreamVideosList, selectedStreamId);
downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog");
} catch (Exception e) {
- Toast.makeText(activity,
- R.string.could_not_setup_download_menu, Toast.LENGTH_LONG).show();
+ Toast.makeText(activity, R.string.could_not_setup_download_menu, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}