From 8b67f1358d302c86d9c96abb33ea2ed85f0613f4 Mon Sep 17 00:00:00 2001 From: Mauricio Colli Date: Mon, 15 May 2017 00:57:57 -0300 Subject: [PATCH] Implement no-audio icon --- .../newpipe/download/DownloadDialog.java | 307 +++++++++++------- .../newpipe/download/FileDownloader.java | 165 ---------- .../fragments/detail/ActionBarHandler.java | 13 +- .../detail/SpinnerToolbarAdapter.java | 74 +++++ .../fragments/detail/VideoDetailFragment.java | 30 +- 5 files changed, 262 insertions(+), 327 deletions(-) delete mode 100644 app/src/main/java/org/schabi/newpipe/download/FileDownloader.java create mode 100644 app/src/main/java/org/schabi/newpipe/fragments/detail/SpinnerToolbarAdapter.java 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(); } }