1
0
mirror of https://github.com/TeamNewPipe/NewPipe.git synced 2024-11-22 02:53:09 +01:00

made the ui more accommodating for not available audio streams

This commit is contained in:
Christian Schabesberger 2016-02-17 21:39:41 +01:00
parent b15a0b92f9
commit 648b9b5d02
5 changed files with 253 additions and 160 deletions

View File

@ -51,13 +51,16 @@ class ActionBarHandler {
private SharedPreferences defaultPreferences = null; private SharedPreferences defaultPreferences = null;
private Menu menu;
// Only callbacks are listed here, there are more actions which don't need a callback. // Only callbacks are listed here, there are more actions which don't need a callback.
// those are edited directly. Typically VideoItemDetailFragment will implement those callbacks. // those are edited directly. Typically VideoItemDetailFragment will implement those callbacks.
private OnActionListener onShareListener; private OnActionListener onShareListener = null;
private OnActionListener onOpenInBrowserListener; private OnActionListener onOpenInBrowserListener = null;
private OnActionListener onDownloadListener; private OnActionListener onDownloadListener = null;
private OnActionListener onPlayWithKodiListener; private OnActionListener onPlayWithKodiListener = null;
private OnActionListener onPlayAudioListener; private OnActionListener onPlayAudioListener = null;
// Triggered when a stream related action is triggered. // Triggered when a stream related action is triggered.
public interface OnActionListener { public interface OnActionListener {
@ -128,15 +131,15 @@ class ActionBarHandler {
} }
public void setupMenu(Menu menu, MenuInflater inflater) { public void setupMenu(Menu menu, MenuInflater inflater) {
this.menu = menu;
// CAUTION set item properties programmatically otherwise it would not be accepted by // CAUTION set item properties programmatically otherwise it would not be accepted by
// appcompat itemsinflater.inflate(R.menu.videoitem_detail, menu); // appcompat itemsinflater.inflate(R.menu.videoitem_detail, menu);
defaultPreferences = PreferenceManager.getDefaultSharedPreferences(activity); defaultPreferences = PreferenceManager.getDefaultSharedPreferences(activity);
inflater.inflate(R.menu.videoitem_detail, menu); inflater.inflate(R.menu.videoitem_detail, menu);
MenuItem castItem = menu.findItem(R.id.action_play_with_kodi);
castItem.setVisible(defaultPreferences showPlayWithKodiAction(defaultPreferences
.getBoolean(activity.getString(R.string.show_play_with_kodi_key), false)); .getBoolean(activity.getString(R.string.show_play_with_kodi_key), false));
} }
@ -151,15 +154,21 @@ class ActionBarHandler {
intent.setType("text/plain"); intent.setType("text/plain");
activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.share_dialog_title))); activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.share_dialog_title)));
*/ */
onShareListener.onActionSelected(selectedVideoStream); if(onShareListener != null) {
onShareListener.onActionSelected(selectedVideoStream);
}
return true; return true;
} }
case R.id.menu_item_openInBrowser: { case R.id.menu_item_openInBrowser: {
onOpenInBrowserListener.onActionSelected(selectedVideoStream); if(onOpenInBrowserListener != null) {
onOpenInBrowserListener.onActionSelected(selectedVideoStream);
}
} }
return true; return true;
case R.id.menu_item_download: case R.id.menu_item_download:
onDownloadListener.onActionSelected(selectedVideoStream); if(onDownloadListener != null) {
onDownloadListener.onActionSelected(selectedVideoStream);
}
return true; return true;
case R.id.action_settings: { case R.id.action_settings: {
Intent intent = new Intent(activity, SettingsActivity.class); Intent intent = new Intent(activity, SettingsActivity.class);
@ -167,10 +176,14 @@ class ActionBarHandler {
return true; return true;
} }
case R.id.action_play_with_kodi: case R.id.action_play_with_kodi:
onPlayWithKodiListener.onActionSelected(selectedVideoStream); if(onPlayWithKodiListener != null) {
onPlayWithKodiListener.onActionSelected(selectedVideoStream);
}
return true; return true;
case R.id.menu_item_play_audio: case R.id.menu_item_play_audio:
onPlayAudioListener.onActionSelected(selectedVideoStream); if(onPlayAudioListener != null) {
onPlayAudioListener.onActionSelected(selectedVideoStream);
}
return true; return true;
default: default:
Log.e(TAG, "Menu Item not known"); Log.e(TAG, "Menu Item not known");
@ -201,4 +214,16 @@ class ActionBarHandler {
public void setOnPlayAudioListener(OnActionListener listener) { public void setOnPlayAudioListener(OnActionListener listener) {
onPlayAudioListener = listener; onPlayAudioListener = listener;
} }
public void showAudioAction(boolean visible) {
menu.findItem(R.id.menu_item_play_audio).setVisible(visible);
}
public void showDownloadAction(boolean visible) {
menu.findItem(R.id.menu_item_download).setVisible(visible);
}
public void showPlayWithKodiAction(boolean visible) {
menu.findItem(R.id.action_play_with_kodi).setVisible(visible);
}
} }

View File

@ -1,18 +1,13 @@
package org.schabi.newpipe; package org.schabi.newpipe;
import android.Manifest; import android.Manifest;
import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
import android.app.DownloadManager; import android.app.DownloadManager;
import android.app.Notification;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
@ -63,74 +58,68 @@ public class DownloadDialog extends DialogFragment {
if(ContextCompat.checkSelfPermission(this.getContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) if(ContextCompat.checkSelfPermission(this.getContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0); ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.download_dialog_title) builder.setTitle(R.string.download_dialog_title);
.setItems(R.array.download_options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Context context = getActivity();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String suffix = "";
String title = arguments.getString(TITLE);
String url = "";
File downloadDir = NewPipeSettings.getDownloadFolder();
switch(which) {
case 0: // Video
suffix = arguments.getString(FILE_SUFFIX_VIDEO);
url = arguments.getString(VIDEO_URL);
downloadDir = NewPipeSettings.getVideoDownloadFolder(context);
break;
case 1:
suffix = arguments.getString(FILE_SUFFIX_AUDIO);
url = arguments.getString(AUDIO_URL);
downloadDir = NewPipeSettings.getAudioDownloadFolder(context);
break;
default:
Log.d(TAG, "lolz");
}
if(!downloadDir.exists()) {
//attempt to create directory
boolean mkdir = downloadDir.mkdirs();
if(!mkdir && !downloadDir.isDirectory()) {
String message = context.getString(R.string.err_dir_create,downloadDir.toString());
Log.e(TAG, message);
Toast.makeText(context,message , Toast.LENGTH_LONG).show();
return; // If no audio stream available
} if(arguments.getString(AUDIO_URL) == null) {
String message = context.getString(R.string.info_dir_created,downloadDir.toString()); builder.setItems(R.array.download_options_no_audio, new DialogInterface.OnClickListener() {
Log.e(TAG, message); @Override
Toast.makeText(context,message , Toast.LENGTH_LONG).show(); public void onClick(DialogInterface dialog, int which) {
} Context context = getActivity();
String title = arguments.getString(TITLE);
File saveFilePath = new File(downloadDir,createFileName(title) + suffix); switch (which) {
case 0: // Video
long id = 0; download(arguments.getString(VIDEO_URL),
if (App.isUsingTor()) { title,
// if using Tor, do not use DownloadManager because the proxy cannot be set arguments.getString(FILE_SUFFIX_VIDEO), context);
FileDownloader.downloadFile(getContext(), url, saveFilePath, title); break;
} else { default:
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); Log.d(TAG, "lolz");
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(url));
request.setDestinationUri(Uri.fromFile(saveFilePath));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(title);
request.setDescription("'" + url +
"' => '" + saveFilePath + "'");
request.allowScanningByMediaScanner();
try {
id = dm.enqueue(request);
} catch (Exception e) {
e.printStackTrace();
}
}
Log.i(TAG,"Started downloading '" + url +
"' => '" + saveFilePath + "' #" + id);
} }
}); }
});
// If no video stream available
} else if(arguments.getString(VIDEO_URL) == null) {
builder.setItems(R.array.download_options_no_video, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Context context = getActivity();
String title = arguments.getString(TITLE);
switch (which) {
case 0: // Audio
download(arguments.getString(AUDIO_URL),
title,
arguments.getString(FILE_SUFFIX_AUDIO), context);
break;
default:
Log.d(TAG, "lolz");
}
}
});
//if both streams ar available
} else {
builder.setItems(R.array.download_options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Context context = getActivity();
String title = arguments.getString(TITLE);
switch (which) {
case 0: // Video
download(arguments.getString(VIDEO_URL),
title,
arguments.getString(FILE_SUFFIX_VIDEO), context);
break;
case 1:
download(arguments.getString(AUDIO_URL),
title,
arguments.getString(FILE_SUFFIX_AUDIO), context);
break;
default:
Log.d(TAG, "lolz");
}
}
});
}
return builder.create(); return builder.create();
} }
@ -151,4 +140,51 @@ public class DownloadDialog extends DialogFragment {
} }
return nameToTest; return nameToTest;
} }
private void download(String url, String title, String fileSuffix, Context context) {
File downloadDir = NewPipeSettings.getDownloadFolder();
if(!downloadDir.exists()) {
//attempt to create directory
boolean mkdir = downloadDir.mkdirs();
if(!mkdir && !downloadDir.isDirectory()) {
String message = context.getString(R.string.err_dir_create,downloadDir.toString());
Log.e(TAG, message);
Toast.makeText(context,message , Toast.LENGTH_LONG).show();
return;
}
String message = context.getString(R.string.info_dir_created,downloadDir.toString());
Log.e(TAG, message);
Toast.makeText(context,message , Toast.LENGTH_LONG).show();
}
File saveFilePath = new File(downloadDir,createFileName(title) + fileSuffix);
long id = 0;
if (App.isUsingTor()) {
// if using Tor, do not use DownloadManager because the proxy cannot be set
FileDownloader.downloadFile(getContext(), url, saveFilePath, title);
} else {
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(url));
request.setDestinationUri(Uri.fromFile(saveFilePath));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(title);
request.setDescription("'" + url +
"' => '" + saveFilePath + "'");
request.allowScanningByMediaScanner();
try {
id = dm.enqueue(request);
} catch (Exception e) {
e.printStackTrace();
}
}
Log.i(TAG,"Started downloading '" + url +
"' => '" + saveFilePath + "' #" + id);
}
} }

View File

@ -414,86 +414,106 @@ public class VideoItemDetailFragment extends Fragment {
actionBarHandler.setOnDownloadListener(new ActionBarHandler.OnActionListener() { actionBarHandler.setOnDownloadListener(new ActionBarHandler.OnActionListener() {
@Override @Override
public void onActionSelected(int selectedStreamId) { public void onActionSelected(int selectedStreamId) {
//VideoInfo.VideoStream selectedStreamItem = videoStreams.get(selectedStream); try {
VideoInfo.AudioStream audioStream = Bundle args = new Bundle();
info.audio_streams.get(getPreferredAudioStreamId(info));
VideoInfo.VideoStream selectedStreamItem = info.video_streams.get(selectedStreamId);
String videoSuffix = "." + MediaFormat.getSuffixById(selectedStreamItem.format);
String audioSuffix = "." + MediaFormat.getSuffixById(audioStream.format);
Bundle args = new Bundle();
args.putString(DownloadDialog.FILE_SUFFIX_VIDEO, videoSuffix);
args.putString(DownloadDialog.FILE_SUFFIX_AUDIO, audioSuffix);
args.putString(DownloadDialog.TITLE, info.title);
args.putString(DownloadDialog.VIDEO_URL, selectedStreamItem.url);
args.putString(DownloadDialog.AUDIO_URL, audioStream.url);
DownloadDialog downloadDialog = new DownloadDialog();
downloadDialog.setArguments(args);
downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog");
}
});
actionBarHandler.setOnPlayAudioListener(new ActionBarHandler.OnActionListener() { // Sometimes it may be that some information is not available due to changes fo the
@Override // website which was crawled. Then the ui has to understand this and act right.
public void onActionSelected(int selectedStreamId) {
boolean useExternalAudioPlayer = PreferenceManager.getDefaultSharedPreferences(activity)
.getBoolean(activity.getString(R.string.use_external_audio_player_key), false);
Intent intent;
VideoInfo.AudioStream audioStream =
info.audio_streams.get(getPreferredAudioStreamId(info));
if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 18) {
//internal music player: explicit intent
if (!BackgroundPlayer.isRunning && videoThumbnail != null) {
ActivityCommunicator.getCommunicator()
.backgroundPlayerThumbnail = videoThumbnail;
intent = new Intent(activity, BackgroundPlayer.class);
intent.setAction(Intent.ACTION_VIEW); if (info.audio_streams != null) {
Log.i(TAG, "audioStream is null:" + (audioStream == null)); VideoInfo.AudioStream audioStream =
Log.i(TAG, "audioStream.url is null:" + (audioStream.url == null)); info.audio_streams.get(getPreferredAudioStreamId(info));
intent.setDataAndType(Uri.parse(audioStream.url),
MediaFormat.getMimeById(audioStream.format)); String audioSuffix = "." + MediaFormat.getSuffixById(audioStream.format);
intent.putExtra(BackgroundPlayer.TITLE, info.title); args.putString(DownloadDialog.AUDIO_URL, audioStream.url);
intent.putExtra(BackgroundPlayer.WEB_URL, info.webpage_url); args.putString(DownloadDialog.FILE_SUFFIX_AUDIO, audioSuffix);
intent.putExtra(BackgroundPlayer.SERVICE_ID, streamingServiceId);
intent.putExtra(BackgroundPlayer.CHANNEL_NAME, info.uploader);
activity.startService(intent);
} }
} else {
intent = new Intent(); if (info.video_streams != null) {
try { VideoInfo.VideoStream selectedStreamItem = info.video_streams.get(selectedStreamId);
intent.setAction(Intent.ACTION_VIEW); String videoSuffix = "." + MediaFormat.getSuffixById(selectedStreamItem.format);
intent.setDataAndType(Uri.parse(audioStream.url), args.putString(DownloadDialog.FILE_SUFFIX_VIDEO, videoSuffix);
MediaFormat.getMimeById(audioStream.format)); args.putString(DownloadDialog.VIDEO_URL, selectedStreamItem.url);
intent.putExtra(Intent.EXTRA_TITLE, info.title);
intent.putExtra("title", info.title);
// HERE !!!
activity.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(R.string.no_player_found)
.setPositiveButton(R.string.install, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(activity.getString(R.string.fdroid_vlc_url)));
activity.startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.i(TAG, "You unlocked a secret unicorn.");
}
});
builder.create().show();
Log.e(TAG, "Either no Streaming player for audio was installed, or something important crashed:");
e.printStackTrace();
} }
args.putString(DownloadDialog.TITLE, info.title);
DownloadDialog downloadDialog = new DownloadDialog();
downloadDialog.setArguments(args);
downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog");
} catch(Exception e) {
Toast.makeText(VideoItemDetailFragment.this.getActivity(),
R.string.could_not_setup_download_menu, Toast.LENGTH_LONG).show();
e.printStackTrace();
} }
} }
}); });
if(info.audio_streams == null) {
actionBarHandler.showAudioAction(false);
} else {
actionBarHandler.setOnPlayAudioListener(new ActionBarHandler.OnActionListener() {
@Override
public void onActionSelected(int selectedStreamId) {
boolean useExternalAudioPlayer = PreferenceManager.getDefaultSharedPreferences(activity)
.getBoolean(activity.getString(R.string.use_external_audio_player_key), false);
Intent intent;
VideoInfo.AudioStream audioStream =
info.audio_streams.get(getPreferredAudioStreamId(info));
if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 18) {
//internal music player: explicit intent
if (!BackgroundPlayer.isRunning && videoThumbnail != null) {
ActivityCommunicator.getCommunicator()
.backgroundPlayerThumbnail = videoThumbnail;
intent = new Intent(activity, BackgroundPlayer.class);
intent.setAction(Intent.ACTION_VIEW);
Log.i(TAG, "audioStream is null:" + (audioStream == null));
Log.i(TAG, "audioStream.url is null:" + (audioStream.url == null));
intent.setDataAndType(Uri.parse(audioStream.url),
MediaFormat.getMimeById(audioStream.format));
intent.putExtra(BackgroundPlayer.TITLE, info.title);
intent.putExtra(BackgroundPlayer.WEB_URL, info.webpage_url);
intent.putExtra(BackgroundPlayer.SERVICE_ID, streamingServiceId);
intent.putExtra(BackgroundPlayer.CHANNEL_NAME, info.uploader);
activity.startService(intent);
}
} else {
intent = new Intent();
try {
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(audioStream.url),
MediaFormat.getMimeById(audioStream.format));
intent.putExtra(Intent.EXTRA_TITLE, info.title);
intent.putExtra("title", info.title);
// HERE !!!
activity.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(R.string.no_player_found)
.setPositiveButton(R.string.install, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(activity.getString(R.string.fdroid_vlc_url)));
activity.startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.i(TAG, "You unlocked a secret unicorn.");
}
});
builder.create().show();
Log.e(TAG, "Either no Streaming player for audio was installed, or something important crashed:");
e.printStackTrace();
}
}
}
});
}
} }
private int getPreferredAudioStreamId(final VideoInfo info) { private int getPreferredAudioStreamId(final VideoInfo info) {

View File

@ -55,8 +55,10 @@ public class VideoInfo extends AbstractVideoInfo {
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
/** Load and extract audio*/ /** Load and extract audio*/
videoInfo.audio_streams = extractor.getAudioStreams(); videoInfo.audio_streams = extractor.getAudioStreams();
// also try to get streams from the dashMpd
if(videoInfo.dashMpdUrl != null && !videoInfo.dashMpdUrl.isEmpty()) { if(videoInfo.dashMpdUrl != null && !videoInfo.dashMpdUrl.isEmpty()) {
if(videoInfo.audio_streams == null) { if(videoInfo.audio_streams == null) {
videoInfo.audio_streams = new Vector<AudioStream>(); videoInfo.audio_streams = new Vector<AudioStream>();
@ -82,9 +84,6 @@ public class VideoInfo extends AbstractVideoInfo {
videoInfo.next_video = extractor.getNextVideo(); videoInfo.next_video = extractor.getNextVideo();
videoInfo.related_videos = extractor.getRelatedVideos(); videoInfo.related_videos = extractor.getRelatedVideos();
//Bitmap thumbnail = null;
//Bitmap uploader_thumbnail = null;
//int videoAvailableStatus = VIDEO_AVAILABLE;
return videoInfo; return videoInfo;
} }

View File

@ -53,6 +53,15 @@
<item>Video</item> <item>Video</item>
<item>Audio</item> <item>Audio</item>
</string-array> </string-array>
<string-array name="download_options_no_audio">
<item>Video</item>
</string-array>
<string-array name="download_options_no_video">
<item>Audio</item>
</string-array>
<string name="next_video_title">Next video</string> <string name="next_video_title">Next video</string>
<string name="show_next_and_similar_title">Show next and similar videos</string> <string name="show_next_and_similar_title">Show next and similar videos</string>
<string name="url_not_supported_toast">URL not supported</string> <string name="url_not_supported_toast">URL not supported</string>
@ -65,6 +74,8 @@
<string name="background_player_playing_toast">Playing in background</string> <string name="background_player_playing_toast">Playing in background</string>
<string name="c3s_url" translatable="false">https://www.c3s.cc/</string> <string name="c3s_url" translatable="false">https://www.c3s.cc/</string>
<string name="play_btn_text">Play</string> <string name="play_btn_text">Play</string>
<!-- error strings -->
<string name="general_error">Error</string> <string name="general_error">Error</string>
<string name="network_error">Network error</string> <string name="network_error">Network error</string>
<string name="could_not_load_thumbnails">Could not load all Thumbnails</string> <string name="could_not_load_thumbnails">Could not load all Thumbnails</string>
@ -72,6 +83,8 @@
<string name="parsing_error">Could not parse website.</string> <string name="parsing_error">Could not parse website.</string>
<string name="content_not_available">Content not available.</string> <string name="content_not_available">Content not available.</string>
<string name="blocked_by_gema">Blocked by GEMA.</string> <string name="blocked_by_gema">Blocked by GEMA.</string>
<string name="could_not_setup_download_menu">Could not setup download menu.</string>
<!-- Content descriptions (for better accessibility) --> <!-- Content descriptions (for better accessibility) -->
<string name="list_thumbnail_view_description">Video preview thumbnail</string> <string name="list_thumbnail_view_description">Video preview thumbnail</string>