1
0
mirror of https://github.com/TeamNewPipe/NewPipe.git synced 2024-11-21 18:42:35 +01:00

- changed icon again

- made ActionBarHandler not be a singelton anymore
 - fixed go back bug for the "Next Video" thing
 - fixed opening youtube mobile links
This commit is contained in:
Christian Schabesberger 2015-10-29 17:56:35 +01:00
parent ab4d626ea9
commit c22c2009d4
14 changed files with 682 additions and 96 deletions

View File

@ -1,6 +1,5 @@
package org.schabi.newpipe;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
@ -41,9 +40,6 @@ public class ActionBarHandler {
private static final String TAG = ActionBarHandler.class.toString();
private static final String KORE_PACKET = "org.xbmc.kore";
private static ActionBarHandler handler = null;
private Context context = null;
private String websiteUrl = "";
private AppCompatActivity activity;
private VideoInfo.VideoStream[] videoStreams = null;
@ -53,13 +49,6 @@ public class ActionBarHandler {
SharedPreferences defaultPreferences = null;
public static ActionBarHandler getHandler() {
if(handler == null) {
handler = new ActionBarHandler();
}
return handler;
}
class FormatItemSelectListener implements ActionBar.OnNavigationListener {
@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
@ -68,6 +57,10 @@ public class ActionBarHandler {
}
}
public ActionBarHandler(AppCompatActivity activity) {
this.activity = activity;
}
public void setupNavMenu(AppCompatActivity activity) {
this.activity = activity;
activity.getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
@ -78,8 +71,8 @@ public class ActionBarHandler {
selectedStream = 0;
String[] itemArray = new String[videoStreams.length];
String defaultResolution = defaultPreferences
.getString(context.getString(R.string.defaultResolutionPreference),
context.getString(R.string.defaultResolutionListItem));
.getString(activity.getString(R.string.defaultResolutionPreference),
activity.getString(R.string.defaultResolutionListItem));
int defaultResolutionPos = 0;
for(int i = 0; i < videoStreams.length; i++) {
@ -100,8 +93,8 @@ public class ActionBarHandler {
// set audioStream
audioStream = null;
String preferedFormat = PreferenceManager.getDefaultSharedPreferences(context)
.getString(context.getString(R.string.defaultAudioFormatPreference), "webm");
String preferedFormat = PreferenceManager.getDefaultSharedPreferences(activity)
.getString(activity.getString(R.string.defaultAudioFormatPreference), "webm");
if(preferedFormat.equals("webm")) {
for(VideoInfo.AudioStream s : audioStreams) {
if(s.format == VideoInfo.I_WEBMA) {
@ -124,12 +117,11 @@ public class ActionBarHandler {
selectedStream = i;
}
public boolean setupMenu(Menu menu, MenuInflater inflater, Context context) {
this.context = context;
public boolean setupMenu(Menu menu, MenuInflater inflater) {
// CAUTION set item properties programmatically otherwise it would not be accepted by
// appcompat itemsinflater.inflate(R.menu.videoitem_detail, menu);
defaultPreferences = PreferenceManager.getDefaultSharedPreferences(context);
defaultPreferences = PreferenceManager.getDefaultSharedPreferences(activity);
inflater.inflate(R.menu.videoitem_detail, menu);
MenuItem playItem = menu.findItem(R.id.menu_item_play);
@ -142,49 +134,48 @@ public class ActionBarHandler {
| MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
castItem.setVisible(defaultPreferences
.getBoolean(context.getString(R.string.showPlayWidthKodiPreference), false));
.getBoolean(activity.getString(R.string.showPlayWidthKodiPreference), false));
return true;
}
public boolean onItemSelected(MenuItem item, Context context) {
this.context = context;
public boolean onItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id) {
case R.id.menu_item_play:
playVideo();
break;
return true;
case R.id.menu_item_share:
if(!videoTitle.isEmpty()) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, websiteUrl);
intent.setType("text/plain");
context.startActivity(Intent.createChooser(intent, context.getString(R.string.shareDialogTitle)));
activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.shareDialogTitle)));
}
break;
return true;
case R.id.menu_item_openInBrowser: {
openInBrowser();
}
break;
return true;
case R.id.menu_item_download:
downloadVideo();
break;
return true;
case R.id.action_settings: {
Intent intent = new Intent(context, SettingsActivity.class);
context.startActivity(intent);
Intent intent = new Intent(activity, SettingsActivity.class);
activity.startActivity(intent);
}
break;
case R.id.action_play_with_kodi:
playWithKodi();
break;
return true;
case R.id.menu_item_play_audio:
playAudio();
break;
return true;
default:
Log.e(TAG, "Menu Item not known");
}
return true;
return false;
}
public void setVideoInfo(String websiteUrl, String videoTitle) {
@ -195,8 +186,8 @@ public class ActionBarHandler {
public void playVideo() {
// ----------- THE MAGIC MOMENT ---------------
if(!videoTitle.isEmpty()) {
if (PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.useExternalPlayer), false)) {
if (PreferenceManager.getDefaultSharedPreferences(activity)
.getBoolean(activity.getString(R.string.useExternalPlayer), false)) {
// External Player
Intent intent = new Intent();
@ -208,18 +199,18 @@ public class ActionBarHandler {
intent.putExtra(Intent.EXTRA_TITLE, videoTitle);
intent.putExtra("title", videoTitle);
context.startActivity(intent); // HERE !!!
activity.startActivity(intent); // HERE !!!
} catch (Exception e) {
e.printStackTrace();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(R.string.noPlayerFound)
.setPositiveButton(R.string.installStreamPlayer, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(context.getString(R.string.fdroidVLCurl)));
context.startActivity(intent);
intent.setData(Uri.parse(activity.getString(R.string.fdroidVLCurl)));
activity.startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@ -232,11 +223,11 @@ public class ActionBarHandler {
}
} else {
// Internal Player
Intent intent = new Intent(context, PlayVideoActivity.class);
Intent intent = new Intent(activity, PlayVideoActivity.class);
intent.putExtra(PlayVideoActivity.VIDEO_TITLE, videoTitle);
intent.putExtra(PlayVideoActivity.STREAM_URL, videoStreams[selectedStream].url);
intent.putExtra(PlayVideoActivity.VIDEO_URL, websiteUrl);
context.startActivity(intent);
activity.startActivity(intent);
}
}
// --------------------------------------------
@ -265,7 +256,7 @@ public class ActionBarHandler {
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(websiteUrl));
context.startActivity(Intent.createChooser(intent, context.getString(R.string.chooseBrowser)));
activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.chooseBrowser)));
}
}
@ -275,18 +266,18 @@ public class ActionBarHandler {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setPackage(KORE_PACKET);
intent.setData(Uri.parse(websiteUrl.replace("https", "http")));
context.startActivity(intent);
activity.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(R.string.koreNotFound)
.setPositiveButton(R.string.installeKore, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(context.getString(R.string.fdroidKoreUrl)));
context.startActivity(intent);
intent.setData(Uri.parse(activity.getString(R.string.fdroidKoreUrl)));
activity.startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@ -308,18 +299,18 @@ public class ActionBarHandler {
VideoInfo.getMimeById(audioStream.format));
intent.putExtra(Intent.EXTRA_TITLE, videoTitle);
intent.putExtra("title", videoTitle);
context.startActivity(intent); // HERE !!!
activity.startActivity(intent); // HERE !!!
} catch (Exception e) {
e.printStackTrace();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(R.string.noPlayerFound)
.setPositiveButton(R.string.installStreamPlayer, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(context.getString(R.string.fdroidVLCurl)));
context.startActivity(intent);
intent.setData(Uri.parse(activity.getString(R.string.fdroidVLCurl)));
activity.startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {

View File

@ -33,9 +33,11 @@ public class VideoItemDetailActivity extends AppCompatActivity {
private static final String TAG = VideoItemDetailActivity.class.toString();
VideoItemDetailFragment fragment;
private String videoUrl;
private int currentStreamingService = -1;
private boolean isLandscape;
private Menu menu = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -43,7 +45,6 @@ public class VideoItemDetailActivity extends AppCompatActivity {
// Show the Up button in the action bar.
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ActionBarHandler.getHandler().setupNavMenu(this);
// savedInstanceState is non-null when there is fragment state
// saved from previous configurations of this activity
@ -91,14 +92,27 @@ public class VideoItemDetailActivity extends AppCompatActivity {
arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingService);
arguments.putBoolean(VideoItemDetailFragment.AUTO_PLAY, false);
}
} else {
videoUrl = savedInstanceState.getString(VideoItemDetailFragment.VIDEO_URL);
currentStreamingService = savedInstanceState.getInt(VideoItemDetailFragment.STREAMING_SERVICE);
arguments = savedInstanceState;
}
// Create the detail fragment and add it to the activity
// using a fragment transaction.
VideoItemDetailFragment fragment = new VideoItemDetailFragment();
fragment = new VideoItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.add(R.id.videoitem_detail_container, fragment)
.commit();
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
outState.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingService);
outState.putBoolean(VideoItemDetailFragment.AUTO_PLAY, false);
}
@Override
@ -117,17 +131,15 @@ public class VideoItemDetailActivity extends AppCompatActivity {
NavUtils.navigateUpTo(this, intent);
return true;
} else {
ActionBarHandler.getHandler().onItemSelected(item, this);
return fragment.onOptionsItemSelected(item) ||
super.onOptionsItemSelected(item);
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onCreatePanelMenu(int featured, Menu menu) {
super.onCreatePanelMenu(featured, menu);
MenuInflater inflater = getMenuInflater();
ActionBarHandler.getHandler().setupMenu(menu, inflater, this);
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
fragment.onCreateOptionsMenu(menu, getMenuInflater());
return true;
}
}

View File

@ -9,11 +9,14 @@ import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
@ -23,7 +26,7 @@ import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.content.Context;
import android.view.MenuItem;
import java.net.URL;
import java.util.Vector;
@ -60,12 +63,20 @@ public class VideoItemDetailFragment extends Fragment {
public static final String STREAMING_SERVICE = "streaming_service";
public static final String AUTO_PLAY = "auto_play";
private AppCompatActivity activity;
private ActionBarHandler actionBarHandler;
private boolean autoPlayEnabled = false;
private Thread extractorThread = null;
private VideoInfo currentVideoInfo = null;
private boolean showNextVideoItem = false;
public interface OnInvokeCreateOptionsMenuListener {
void createOptionsMenu();
}
private OnInvokeCreateOptionsMenuListener onInvokeCreateOptionsMenuListener = null;
private class ExtractorRunnable implements Runnable {
private Handler h = new Handler();
private Class extractorClass;
@ -206,7 +217,7 @@ public class VideoItemDetailFragment extends Fragment {
descriptionView.setText(Html.fromHtml(info.description));
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
ActionBarHandler.getHandler().setVideoInfo(info.webpage_url, info.title);
actionBarHandler.setVideoInfo(info.webpage_url, info.title);
// parse streams
Vector<VideoInfo.VideoStream> streamsToUse = new Vector<>();
@ -219,7 +230,7 @@ public class VideoItemDetailFragment extends Fragment {
for (int i = 0; i < streamList.length; i++) {
streamList[i] = streamsToUse.get(i);
}
ActionBarHandler.getHandler().setStreams(streamList, info.audioStreams);
actionBarHandler.setStreams(streamList, info.audioStreams);
}
nextVideoButton.setOnClickListener(new View.OnClickListener() {
@ -245,7 +256,7 @@ public class VideoItemDetailFragment extends Fragment {
}
if(autoPlayEnabled) {
ActionBarHandler.getHandler().playVideo();
actionBarHandler.playVideo();
}
} catch (java.lang.NullPointerException e) {
Log.w(TAG, "updateInfo(): Fragment closed before thread ended work... or else");
@ -272,15 +283,21 @@ public class VideoItemDetailFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getActivity();
activity = (AppCompatActivity) getActivity();
showNextVideoItem = PreferenceManager.getDefaultSharedPreferences(getActivity())
.getBoolean(context.getString(R.string.showNextVideo), true);
.getBoolean(activity.getString(R.string.showNextVideo), true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_videoitem_detail, container, false);
actionBarHandler = new ActionBarHandler(activity);
actionBarHandler.setupNavMenu(activity);
if(onInvokeCreateOptionsMenuListener != null) {
onInvokeCreateOptionsMenuListener.createOptionsMenu();
}
return rootView;
}
@ -317,7 +334,7 @@ public class VideoItemDetailFragment extends Fragment {
playVideoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ActionBarHandler.getHandler().playVideo();
actionBarHandler.playVideo();
}
});
}
@ -328,4 +345,18 @@ public class VideoItemDetailFragment extends Fragment {
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels < displayMetrics.widthPixels;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
actionBarHandler.setupMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return actionBarHandler.onItemSelected(item);
}
public void setOnInvokeCreateOptionsMenuListener(OnInvokeCreateOptionsMenuListener listener) {
this.onInvokeCreateOptionsMenuListener = listener;
}
}

View File

@ -41,6 +41,8 @@ public class VideoItemListActivity extends AppCompatActivity
private String searchQuery = "";
private VideoItemListFragment listFragment;
private VideoItemDetailFragment videoFragment = null;
Menu menu = null;
public class SearchVideoQueryListener implements SearchView.OnQueryTextListener {
@ -132,9 +134,6 @@ public class VideoItemListActivity extends AppCompatActivity
searchView.setIconifiedByDefault(false);
searchView.setIconified(false);
searchView.setOnQueryTextListener(new SearchVideoQueryListener());
ActionBarHandler.getHandler().setupNavMenu(this);
}
SettingsActivity.initSettings(this);
@ -160,10 +159,17 @@ public class VideoItemListActivity extends AppCompatActivity
arguments.putString(VideoItemDetailFragment.ARG_ITEM_ID, id);
arguments.putString(VideoItemDetailFragment.VIDEO_URL, webpage_url);
arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingServiceId);
VideoItemDetailFragment fragment = new VideoItemDetailFragment();
fragment.setArguments(arguments);
videoFragment = new VideoItemDetailFragment();
videoFragment.setArguments(arguments);
videoFragment.setOnInvokeCreateOptionsMenuListener(new VideoItemDetailFragment.OnInvokeCreateOptionsMenuListener() {
@Override
public void createOptionsMenu() {
menu.clear();
onCreateOptionsMenu(menu);
}
});
getSupportFragmentManager().beginTransaction()
.replace(R.id.videoitem_detail_container, fragment)
.replace(R.id.videoitem_detail_container, videoFragment)
.commit();
} else {
// In single-pane mode, simply start the detail activity
@ -177,10 +183,11 @@ public class VideoItemListActivity extends AppCompatActivity
}
public boolean onCreatePanelMenu(int featured, Menu menu) {
super.onCreatePanelMenu(featured, menu);
if(findViewById(R.id.videoitem_detail_container) == null) {
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
this.menu = menu;
MenuInflater inflater = getMenuInflater();
if(findViewById(R.id.videoitem_detail_container) == null) {
inflater.inflate(R.menu.videoitem_list, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
@ -188,9 +195,10 @@ public class VideoItemListActivity extends AppCompatActivity
searchView.setOnQueryTextListener(
new SearchVideoQueryListener());
} else if (videoFragment != null){
videoFragment.onCreateOptionsMenu(menu, inflater);
} else {
MenuInflater inflater = getMenuInflater();
ActionBarHandler.getHandler().setupMenu(menu, inflater, this);
inflater.inflate(R.menu.videoitem_two_pannel, menu);
}
return true;
@ -203,8 +211,8 @@ public class VideoItemListActivity extends AppCompatActivity
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
} else {
ActionBarHandler.getHandler().onItemSelected(item, this);
return super.onOptionsItemSelected(item);
return videoFragment.onOptionsItemSelected(item) ||
super.onOptionsItemSelected(item);
}
return true;
}

View File

@ -98,9 +98,13 @@ public class YoutubeExtractor implements Extractor {
try {
URI uri = new URI(videoUrl);
if(uri.getHost().contains("youtube")) {
String fragment = uri.getFragment();
fragment = fragment.replace("/watch?", "");
String queryElements[] = fragment.split("&");
String query = uri.getFragment();
if(query == null) {
query = uri.getQuery();
} else {
query = query.replace("/watch?", "");
}
String queryElements[] = query.split("&");
Map<String, String> queryArguments = new HashMap<>();
for (String e : queryElements) {
String[] s = e.split("=");
@ -181,8 +185,6 @@ public class YoutubeExtractor implements Extractor {
videoInfo.thumbnail_url = playerArgs.getString("thumbnail_url");
videoInfo.duration = playerArgs.getInt("length_seconds");
videoInfo.average_rating = playerArgs.getString("avg_rating");
// View Count will be extracted from html
dashManifest = playerArgs.getString("dashmpd");
String playerUrl = ytAssets.getString("js");
if(playerUrl.startsWith("//")) {
playerUrl = "https:" + playerUrl;
@ -192,7 +194,14 @@ public class YoutubeExtractor implements Extractor {
}
// extract audio
try {
dashManifest = playerArgs.getString("dashmpd");
videoInfo.audioStreams = parseDashManifest(dashManifest, decryptionCode);
} catch (Exception e) {
//todo: check if the following statement is true
Log.e(TAG, "Dash manifest seems not to bee available.");
e.printStackTrace();
}
//------------------------------------
// extract video stream url

View File

@ -190,8 +190,8 @@
<View
android:layout_width="match_parent"
android:layout_height="100dip"
android:layout_below="@id/detailNextVideoSeperationLineEnd"/>
android:layout_height="70dip"
android:layout_below="@id/detailNextVideoRootLayout"/>
</RelativeLayout>
</ScrollView>

View File

@ -190,8 +190,8 @@
<View
android:layout_width="match_parent"
android:layout_height="100dip"
android:layout_below="@id/detailNextVideoSeperationLineEnd"/>
android:layout_height="70dip"
android:layout_below="@id/detailNextVideoRootLayout"/>
</RelativeLayout>
</ScrollView>

View File

@ -187,7 +187,7 @@
<View
android:layout_width="match_parent"
android:layout_height="100dip"
android:layout_height="70dip"
android:layout_below="@id/detailNextVideoRootLayout"/>
</RelativeLayout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_settings"
app:showAsAction="never"
android:title="@string/settings"/>
</menu>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

526
assets/new_pipe_icon_4.svg Normal file
View File

@ -0,0 +1,526 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
viewBox="0 0 192 192"
height="192"
width="192"
inkscape:version="0.91 r13725"
sodipodi:docname="new_pipe_icon_4.svg"
inkscape:export-filename="/home/the-scrabi/Projects/NewPipe/app/src/main/res/mipmap-xxhdpi/ic_launcher.png"
inkscape:export-xdpi="67.5"
inkscape:export-ydpi="67.5">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1016"
id="namedview4149"
showgrid="false"
inkscape:zoom="2.2793069"
inkscape:cx="74.912287"
inkscape:cy="82.673449"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient4447">
<stop
style="stop-color:#ffffff;stop-opacity:0.1"
offset="0"
id="stop4449" />
<stop
style="stop-color:#ffffff;stop-opacity:0"
offset="1"
id="stop4451" />
</linearGradient>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter4454"
width="1.4"
height="1.4"
x="-0.2"
y="-0.2">
<feFlood
flood-opacity="0.427451"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4456" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4458" />
<feGaussianBlur
in="composite1"
stdDeviation="10.9"
result="blur"
id="feGaussianBlur4460" />
<feOffset
dx="0"
dy="7"
result="offset"
id="feOffset4462" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4464" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter4777">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4779" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4781" />
<feGaussianBlur
in="composite1"
stdDeviation="5.82011"
result="blur"
id="feGaussianBlur4783" />
<feOffset
dx="0"
dy="5.6"
result="offset"
id="feOffset4785" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="fbSourceGraphic"
id="feComposite4787" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix4789" />
<feFlood
id="feFlood4791"
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
in="fbSourceGraphic" />
<feComposite
id="feComposite4793"
in2="fbSourceGraphic"
in="flood"
operator="in"
result="composite1" />
<feGaussianBlur
id="feGaussianBlur4795"
in="composite1"
stdDeviation="5.8"
result="blur" />
<feOffset
id="feOffset4797"
dx="0"
dy="5.6"
result="offset" />
<feComposite
id="feComposite4799"
in2="offset"
in="fbSourceGraphic"
operator="over"
result="composite2" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter4885">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4887" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4889" />
<feGaussianBlur
in="composite1"
stdDeviation="7.9"
result="blur"
id="feGaussianBlur4891" />
<feOffset
dx="0"
dy="2.54709"
result="offset"
id="feOffset4893" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="fbSourceGraphic"
id="feComposite4895" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix4897" />
<feFlood
id="feFlood4899"
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
in="fbSourceGraphic" />
<feComposite
id="feComposite4901"
in2="fbSourceGraphic"
in="flood"
operator="in"
result="composite1" />
<feGaussianBlur
id="feGaussianBlur4903"
in="composite1"
stdDeviation="7.9"
result="blur" />
<feOffset
id="feOffset4905"
dx="0"
dy="2.5"
result="offset" />
<feComposite
id="feComposite4907"
in2="offset"
in="fbSourceGraphic"
operator="over"
result="composite2" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter4257">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4259" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4261" />
<feGaussianBlur
in="composite1"
stdDeviation="7.9"
result="blur"
id="feGaussianBlur4263" />
<feOffset
dx="0"
dy="5.02645"
result="offset"
id="feOffset4265" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="fbSourceGraphic"
id="feComposite4267" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix4269" />
<feFlood
id="feFlood4271"
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
in="fbSourceGraphic" />
<feComposite
id="feComposite4273"
in2="fbSourceGraphic"
in="flood"
operator="in"
result="composite1" />
<feGaussianBlur
id="feGaussianBlur4275"
in="composite1"
stdDeviation="7.9"
result="blur" />
<feOffset
id="feOffset4277"
dx="0"
dy="5"
result="offset" />
<feComposite
id="feComposite4279"
in2="offset"
in="fbSourceGraphic"
operator="over"
result="composite2" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter4192">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4194" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4196" />
<feGaussianBlur
in="composite1"
stdDeviation="7.7"
result="blur"
id="feGaussianBlur4198" />
<feOffset
dx="0"
dy="5"
result="offset"
id="feOffset4200" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4202" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter4349">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4351" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4353" />
<feGaussianBlur
in="composite1"
stdDeviation="7.2"
result="blur"
id="feGaussianBlur4355" />
<feOffset
dx="0"
dy="5"
result="offset"
id="feOffset4357" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4359" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter4361">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4363" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4365" />
<feGaussianBlur
in="composite1"
stdDeviation="5.3"
result="blur"
id="feGaussianBlur4367" />
<feOffset
dx="0"
dy="5"
result="offset"
id="feOffset4369" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4371" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter4481">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4483" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4485" />
<feGaussianBlur
in="composite1"
stdDeviation="5"
result="blur"
id="feGaussianBlur4487" />
<feOffset
dx="0"
dy="5"
result="offset"
id="feOffset4489" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4491" />
</filter>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter4433">
<feFlood
flood-opacity="0.2"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4435" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4437" />
<feGaussianBlur
in="composite1"
stdDeviation="4"
result="blur"
id="feGaussianBlur4439" />
<feOffset
dx="0"
dy="4"
result="offset"
id="feOffset4441" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4443" />
</filter>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4447"
id="radialGradient4453"
cx="0.56012386"
cy="0.35701406"
fx="0.56012386"
fy="0.35701406"
r="88"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.00132321,2.1587518,-2.1815784,0.00133718,1.1350038,-0.41402508)" />
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<path
style="opacity:1;fill:#ff7575;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4144-9"
r="88"
cy="104"
cx="88" />
<circle
style="fill:#ff5252;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4144-6"
cx="88"
cy="104"
r="0" />
<g
id="g4455">
<g
style="filter:url(#filter4433)"
transform="translate(8,-8)"
id="g4416">
<circle
style="opacity:1;fill:#ff7575;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4144-67"
cx="88"
cy="104"
r="88" />
<path
style="opacity:1;fill:#cc4242;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4144-5"
sodipodi:type="arc"
sodipodi:cx="88"
sodipodi:cy="104"
sodipodi:rx="88"
sodipodi:ry="88"
sodipodi:start="0"
sodipodi:end="3.1387981"
sodipodi:open="true"
d="M 176,104 A 88,88 0 0 1 88.12296,191.99991 88,88 0 0 1 3.4361909e-4,104.24592" />
<ellipse
style="fill:#ff5252;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4144"
cx="88"
cy="104"
rx="88"
ry="87" />
<path
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4140"
d="M 137.53637,104.0664 96.33516,127.80966 55.133958,151.5529 55.17235,104 55.210742,56.447076 96.37361,80.256739 Z" />
</g>
<circle
r="88"
cy="96"
cx="96"
id="path4445"
style="opacity:1;fill:url(#radialGradient4453);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB