1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2026-01-13 18:22:41 +00:00

Compare commits

..

56 Commits

Author SHA1 Message Date
Christian Schabesberger
f67158a2a7 Fixed:
- made "could not find a streamingplayer" thing inside ActionBarHandler yield stacktraces
- remove watermark
- fixed fab layout
- changed version number to 0.5.0
2015-10-29 18:37:32 +01:00
Christian Schabesberger
c22c2009d4 - changed icon again
- made ActionBarHandler not be a singelton anymore
 - fixed go back bug for the "Next Video" thing
 - fixed opening youtube mobile links
2015-10-29 17:56:35 +01:00
Christian Schabesberger
ab4d626ea9 fixed opening videos via firefox/fenec 2015-10-28 20:48:03 +01:00
Christian Schabesberger
96709d22e9 Merge pull request #61 from Natureshadow/patch-1
Add missing patterns as described in isue #50
2015-10-28 19:39:06 +01:00
Christian Schabesberger
f0bd171eee small layout changed in README.md 2015-10-28 19:08:58 +01:00
Dominik George
c4191077f3 Add missing patterns as described in isue #50 2015-10-28 15:24:46 +01:00
Christian Schabesberger
321d090052 - added dracon5's website to README.md
- added halcyonest icon (with smal modifications)
2015-10-27 21:35:08 +01:00
Christian Schabesberger
32dcb4d281 improved README file 2015-10-27 20:01:56 +01:00
Christian Schabesberger
080159849e - added preference for "next video" item
- display if a url is supported or nod
2015-10-27 18:13:04 +01:00
Christian Schabesberger
d9e690f62c added NextVideo support 2015-10-25 19:14:29 +01:00
Christian Schabesberger
8c0156dea3 fixed broken commit 2015-10-24 16:05:23 +02:00
Christian Schabesberger
038c59ce66 fiexed some smaller displaying errors 2015-10-24 16:04:27 +02:00
Christian Schabesberger
72e08c0447 fixed some layout bugs 2015-10-23 23:08:01 +02:00
Christian Schabesberger
173eaa8cf8 Merge pull request #51 from Soofe/master
Fixed some typos and removed unused imports.
2015-10-17 17:22:21 +02:00
Christian Schabesberger
a04cd24e5e Merge pull request #53 from pejakm/srupd
Update Serbian translation
2015-10-17 17:15:53 +02:00
Mladen Pejaković
0e11404b3b Update Serbian translation 2015-10-17 17:13:21 +02:00
Soofe
342807e26a Update VideoItemListFragment.java 2015-10-15 23:58:14 +02:00
Soofe
c068f08ff8 Fixed some typos and removed unused imports. 2015-10-15 23:25:53 +02:00
Christian Schabesberger
b7c0a77edc Merge pull request #45 from ata2001/master
Update hungarian translation
2015-09-25 23:33:01 +02:00
ata2001
aab0f45890 Update hungarian translation 2015-09-26 00:05:54 +02:00
Christian Schabesberger
c62ad66f11 New:
- Show video title instead of stream url in vlc/MXPlayer
 - remember rotation
Fix:
 - sensore controlled landscape rotation in the player
2015-09-25 14:17:43 +02:00
Christian Schabesberger
d8bdada9db Merge pull request #43 from epitron/master
Set the title for external video players
2015-09-25 07:43:46 +02:00
Christian Schabesberger
1b9f7a7654 Merge pull request #40 from ata2001/master
Update hungarian translation
2015-09-25 07:42:41 +02:00
Chris Gahan
ac710fff08 Set the title for external video players. 2015-09-23 21:58:41 -04:00
ata2001
2e09492eef Update hungarian translation 2015-09-23 19:01:09 +02:00
Christian Schabesberger
4f24d61c4b put the play video button into the horizontal center 2015-09-21 23:53:10 +02:00
Christian Schabesberger
d24c87c9c9 added autio streaming & jumped to version 0.4.0 2015-09-21 21:12:48 +02:00
Christian Schabesberger
1ab5872857 made player pause when screen is locked. started creating audiosupport 2015-09-21 13:32:11 +02:00
=
2489c6c329 Some smaller UI changes and else:
- added play video button for better lefthand support
 - wrote codepart to darkon5s listitem improvements
 - set minimum api level to 15 (Android 4.0.3 support)
 - updated to sdk level 23 including the new support libs
2015-09-21 01:10:11 +02:00
Christian Schabesberger
30dcd3eef0 Merge pull request #36 from darkon5/dev
3 Line Search List
2015-09-20 22:30:41 +02:00
Christian Schabesberger
b20ae45280 Merge pull request #34 from darkon5/master
Duration now shown on top of the thumbnail.
2015-09-20 19:36:40 +02:00
darkon5
049a42a72d Changes in dummy text 2015-09-20 18:29:17 +02:00
darkon5
f8c110edb5 Different lines for author and upload date 2015-09-20 18:02:33 +02:00
darkon5
21580a07ee Merge pull request #4 from darkon5/dev
Changed duration box stroke color to grey (like in the official app)
2015-09-20 17:49:28 +02:00
darkon5
231cbacd5b Changed duration box stroke color to grey (like in the official app) 2015-09-20 17:46:23 +02:00
darkon5
39db33d80d Merge pull request #3 from darkon5/dev
Add Spanish translation
2015-09-20 16:02:56 +02:00
darkon5
39228453a2 Add Spanish translation 2015-09-20 16:01:46 +02:00
darkon5
670a1e4f74 Merge pull request #2 from darkon5/dev
Duration now with the thumbnail, more space for upload date
2015-09-20 15:03:45 +02:00
darkon5
5d77d25d34 Duration now with the thumbnail, more space for upload date 2015-09-20 14:52:11 +02:00
Christian Schabesberger
8ebdcccce1 Merge branch 'master' of github.com:theScrabi/NewPipe 2015-09-20 13:20:53 +02:00
Christian Schabesberger
1b0753a466 Merge pull request #25 from ata2001/master
Add hungarian translation
2015-09-20 13:20:47 +02:00
Christian Schabesberger
25fe45ab8c Merge pull request #26 from Soofe/master
Add French translation
2015-09-20 13:20:42 +02:00
Christian Schabesberger
ff30b7dc4b Merge pull request #30 from darkon5/master
Update video search list
2015-09-20 13:20:34 +02:00
Christian Schabesberger
26211591bb Merge branch 'master' of github.com:theScrabi/NewPipe 2015-09-20 13:19:42 +02:00
Christian Schabesberger
c59754499f new app icon & made player fullscreen work better 2015-09-20 13:19:28 +02:00
darkon5
fc7f5c4254 Merge pull request #1 from darkon5/dev
Delete encodings.xml
2015-09-19 22:33:04 +02:00
darkon5
f915291396 Delete encodings.xml 2015-09-19 22:31:43 +02:00
darkon5
41351baf27 Original .idea 2015-09-19 16:54:29 +02:00
darkon5
fd1153993b Updated dimentxt and video_item 2015-09-19 16:22:36 +02:00
darkon5
7e5ec247de Prueba inicial y dimentxt 2015-09-19 15:47:00 +02:00
Soofe
7c7cb2c26c Add French translation 2015-09-18 22:26:21 +02:00
ata2001
25f44aca37 Add hungarian translation 2015-09-18 19:16:32 +02:00
Christian Schabesberger
4be3b54edb Merge pull request #20 from TheLastProject/dutchTranslation
Add Dutch translation
2015-09-16 23:37:01 +02:00
TheLastProject
bc00746047 Add Dutch translation 2015-09-16 17:01:24 +02:00
Christian Schabesberger
d3cc518529 fiexed the very mesed up version number 2015-09-15 22:48:47 +02:00
Christian Schabesberger
08648caaff fixed landscape layout problem & added watch with kodi function 2015-09-15 20:11:42 +02:00
57 changed files with 3028 additions and 607 deletions

View File

@@ -1,9 +1,45 @@
NewPipe
-------
# NewPipe
version 0.3
[![Translation Status](https://hosted.weblate.org/widgets/NewPipe/-/svg-badge.svg)](https://hosted.weblate.org/engage/NewPipe/)
[![NewPipe](https://f-droid.org/repo/icons/org.schabi.newpipe.4.png)](http://dasochan.nl/newpipe/)
NewPipe: A free lightweight Youtube fronted for Android.
NewPipe is a lightweight youtube frontend for android. It's supposed to be used without the youtube-api and without any google play services. NewPipe only parses the youtube website in order to gain the information it needs.
[![F-Droid](https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png)](https://f-droid.org/repository/browse/?fdfilter=newpipe&fdid=org.schabi.newpipe)
This a very early version of the app, so not all functionality is implemented, and there may still be a lot of bugs. But all in all it's doing what it is supposed to do. It makes it possible to watch youtube videos. So don't be cruel to this app. It will improve...
## Description
NewPipe does not use any Google framework libraries, or the Youtube api. It only parses the website in order to gain the information it needs. Therefore this app can be used on devices without g-services installed. Also NewPipe does not store data on the Youtube website (no login), and it's free software.
## Features
* Search videos
* Display general information about a video
* Watch Youtube videos
* Listen to Youtube videos (audio only streaming)
* Select the streaming player to watch the video with
* Download videos (working, but it could be better)
* Download audio only (working but, but it could be better)
* Open a video in Kodi
## Coming Features
* Shows Next/Related videos
* Improved Downloading
* Bookmarks
* View history
* Search history
* Search channels
* Display general information about channels
* Subscribe to channels
* Watch videos from a channel
* Search/Watch Playlists
* ... and many more
### Multi service support
Generally NewPipe is designed to not only support YouTube, but many more streaming services. How ever, right now NewPipe is not stable enough to support more than only youtube. But if all works as plant, NewPipe will get such support by the version 2.0.
# Help is always welcome !!!
Whether its about ideas, translation, design changes, code cleaning, or real heavy code changes. Help is always welcome.
The more is done the better it gets!

View File

@@ -36,13 +36,13 @@
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
@@ -71,8 +71,10 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.1.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/23.1.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/23.1.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.1.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
@@ -88,12 +90,14 @@
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="recyclerview-v7-23.1.0" level="project" />
<orderEntry type="library" exported="" name="jsoup-1.8.3" level="project" />
<orderEntry type="library" exported="" name="support-v4-22.2.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.2.1" level="project" />
<orderEntry type="library" exported="" name="support-v4-23.1.0" level="project" />
<orderEntry type="library" exported="" name="rhino-1.7.7" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-22.2.1" level="project" />
<orderEntry type="library" exported="" name="design-23.1.0" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-23.1.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.1.0" level="project" />
</component>
</module>

View File

@@ -1,15 +1,15 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "org.schabi.newpipe"
minSdkVersion 16
targetSdkVersion 22
versionCode 1
versionName "0.3"
minSdkVersion 15
targetSdkVersion 23
versionCode 5
versionName "0.5.0"
}
buildTypes {
release {
@@ -21,8 +21,9 @@ android {
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:support-v4:22.2.1'
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:support-v4:23.1.0'
compile 'org.jsoup:jsoup:1.8.3'
compile 'org.mozilla:rhino:1.7.7'
compile 'com.android.support:design:23.1.0'
}

View File

@@ -34,27 +34,27 @@
<data
android:host="youtube.com"
android:scheme="http"
android:pathPrefix="/watch"/>
android:pathPattern="/?*#*/*watch"/>
<data
android:host="youtube.com"
android:scheme="https"
android:pathPrefix="/watch"/>
android:pathPattern="/?*#*/*watch"/>
<data
android:host="www.youtube.com"
android:scheme="http"
android:pathPrefix="/watch"/>
android:pathPattern="/?*#*/*watch"/>
<data
android:host="www.youtube.com"
android:scheme="https"
android:pathPrefix="/watch"/>
android:pathPattern="/?*#*/*watch"/>
<data
android:host="m.youtube.com"
android:scheme="http"
android:pathPrefix="/watch"/>
android:pathPattern="/?*#*/*watch"/>
<data
android:host="m.youtube.com"
android:scheme="https"
android:pathPrefix="/watch"/>
android:pathPattern="/?*#*/*watch"/>
<data
android:host="youtu.be"
android:scheme="https"

View File

@@ -1,10 +1,10 @@
package org.schabi.newpipe;
import android.app.DownloadManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
@@ -16,8 +16,6 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import java.io.File;
/**
* Created by Christian Schabesberger on 18.08.15.
*
@@ -40,23 +38,18 @@ import java.io.File;
public class ActionBarHandler {
private static final String TAG = ActionBarHandler.class.toString();
private static ActionBarHandler handler = null;
private static final String KORE_PACKET = "org.xbmc.kore";
private Context context = null;
private String webisteUrl = "";
private String websiteUrl = "";
private AppCompatActivity activity;
private VideoInfo.Stream[] streams = null;
private VideoInfo.VideoStream[] videoStreams = null;
private VideoInfo.AudioStream audioStream = null;
private int selectedStream = -1;
private String videoTitle = "";
public static ActionBarHandler getHandler() {
if(handler == null) {
handler = new ActionBarHandler();
}
return handler;
}
SharedPreferences defaultPreferences = null;
class ForamatItemSelectListener implements ActionBar.OnNavigationListener {
class FormatItemSelectListener implements ActionBar.OnNavigationListener {
@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
selectFormatItem((int)itemId);
@@ -64,23 +57,27 @@ 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);
}
public void setStreams(VideoInfo.Stream[] streams) {
this.streams = streams;
public void setStreams(VideoInfo.VideoStream[] videoStreams, VideoInfo.AudioStream[] audioStreams) {
this.videoStreams = videoStreams;
selectedStream = 0;
String[] itemArray = new String[streams.length];
String defaultResolution = PreferenceManager.getDefaultSharedPreferences(context)
.getString(context.getString(R.string.defaultResolutionPreference),
context.getString(R.string.defaultResolutionListItem));
String[] itemArray = new String[videoStreams.length];
String defaultResolution = defaultPreferences
.getString(activity.getString(R.string.defaultResolutionPreference),
activity.getString(R.string.defaultResolutionListItem));
int defaultResolutionPos = 0;
for(int i = 0; i < streams.length; i++) {
itemArray[i] = streams[i].format + " " + streams[i].resolution;
if(defaultResolution.equals(streams[i].resolution)) {
for(int i = 0; i < videoStreams.length; i++) {
itemArray[i] = VideoInfo.getNameById(videoStreams[i].format) + " " + videoStreams[i].resolution;
if(defaultResolution.equals(videoStreams[i].resolution)) {
defaultResolutionPos = i;
}
}
@@ -90,92 +87,130 @@ public class ActionBarHandler {
if(activity != null) {
ActionBar ab = activity.getSupportActionBar();
ab.setListNavigationCallbacks(itemAdapter
,new ForamatItemSelectListener());
,new FormatItemSelectListener());
ab.setSelectedNavigationItem(defaultResolutionPos);
}
// set audioStream
audioStream = null;
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) {
audioStream = s;
}
}
} else if(preferedFormat.equals("m4a")){
for(VideoInfo.AudioStream s : audioStreams) {
Log.d(TAG, VideoInfo.getMimeById(s.format) + " : " + Integer.toString(s.bandwidth));
if(s.format == VideoInfo.I_M4A &&
(audioStream == null || audioStream.bandwidth > s.bandwidth)) {
audioStream = s;
Log.d(TAG, "last choosen");
}
}
}
}
private void selectFormatItem(int i) {
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(activity);
inflater.inflate(R.menu.videoitem_detail, menu);
MenuItem playItem = menu.findItem(R.id.menu_item_play);
MenuItem shareItem = menu.findItem(R.id.menu_item_share);
MenuItem castItem = menu.findItem(R.id.action_play_with_kodi);
MenuItemCompat.setShowAsAction(playItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS
| MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
MenuItemCompat.setShowAsAction(shareItem, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM
| MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
castItem.setVisible(defaultPreferences
.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, webisteUrl);
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();
return true;
case R.id.menu_item_play_audio:
playAudio();
return true;
default:
Log.e(TAG, "Menu Item not known");
}
return true;
return false;
}
public void setVideoInfo(String websiteUrl, String videoTitle) {
this.webisteUrl = websiteUrl;
this.websiteUrl = websiteUrl;
this.videoTitle = videoTitle;
}
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();
try {
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(streams[selectedStream].url),
"video/" + streams[selectedStream].format);
context.startActivity(intent); // HERE !!!
intent.setDataAndType(Uri.parse(videoStreams[selectedStream].url),
VideoInfo.getMimeById(videoStreams[selectedStream].format));
intent.putExtra(Intent.EXTRA_TITLE, videoTitle);
intent.putExtra("title", videoTitle);
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() {
@@ -187,11 +222,12 @@ public class ActionBarHandler {
builder.create().show();
}
} else {
Intent intent = new Intent(context, PlayVideoActivity.class);
// Internal Player
Intent intent = new Intent(activity, PlayVideoActivity.class);
intent.putExtra(PlayVideoActivity.VIDEO_TITLE, videoTitle);
intent.putExtra(PlayVideoActivity.STREAM_URL, streams[selectedStream].url);
intent.putExtra(PlayVideoActivity.VIDEO_URL, webisteUrl);
context.startActivity(intent);
intent.putExtra(PlayVideoActivity.STREAM_URL, videoStreams[selectedStream].url);
intent.putExtra(PlayVideoActivity.VIDEO_URL, websiteUrl);
activity.startActivity(intent);
}
}
// --------------------------------------------
@@ -200,30 +236,17 @@ public class ActionBarHandler {
public void downloadVideo() {
Log.d(TAG, "bla");
if(!videoTitle.isEmpty()) {
String suffix = "";
switch (streams[selectedStream].format) {
case VideoInfo.F_WEBM:
suffix = ".webm";
break;
case VideoInfo.F_MPEG_4:
suffix = ".mp4";
break;
case VideoInfo.F_3GPP:
suffix = ".3gp";
break;
}
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(streams[selectedStream].url));
request.setDestinationUri(Uri.fromFile(new File(
PreferenceManager.getDefaultSharedPreferences(context)
.getString("download_path_preference", "/storage/emulated/0/NewPipe")
+ "/" + videoTitle + suffix)));
try {
dm.enqueue(request);
} catch (Exception e) {
e.printStackTrace();
}
String videoSuffix = "." + VideoInfo.getSuffixById(videoStreams[selectedStream].format);
String audioSuffix = "." + VideoInfo.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, videoTitle);
args.putString(DownloadDialog.VIDEO_URL, videoStreams[selectedStream].url);
args.putString(DownloadDialog.AUDIO_URL, audioStream.url);
DownloadDialog downloadDialog = new DownloadDialog();
downloadDialog.setArguments(args);
downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog");
}
}
@@ -231,9 +254,74 @@ public class ActionBarHandler {
if(!videoTitle.isEmpty()) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(webisteUrl));
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)));
}
}
public void playWithKodi() {
if(!videoTitle.isEmpty()) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setPackage(KORE_PACKET);
intent.setData(Uri.parse(websiteUrl.replace("https", "http")));
activity.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
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(activity.getString(R.string.fdroidKoreUrl)));
activity.startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.create().show();
}
}
}
public void playAudio() {
Intent intent = new Intent();
try {
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(audioStream.url),
VideoInfo.getMimeById(audioStream.format));
intent.putExtra(Intent.EXTRA_TITLE, videoTitle);
intent.putExtra("title", videoTitle);
activity.startActivity(intent); // HERE !!!
} catch (Exception e) {
e.printStackTrace();
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(activity.getString(R.string.fdroidVLCurl)));
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.d(TAG, "Either no Streaming player for audio was installed, or something importand crashed:");
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,89 @@
package org.schabi.newpipe;
import android.app.Dialog;
import android.app.DownloadManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import java.io.File;
/**
* Created by Christian Schabesberger on 21.09.15.
*
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* 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 <http://www.gnu.org/licenses/>.
*/
public class DownloadDialog extends DialogFragment {
private static final String TAG = DialogFragment.class.getName();
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";
Bundle arguments;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
arguments = getArguments();
super.onCreateDialog(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.downloadDialogTitle)
.setItems(R.array.downloadOptions, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Context context = getActivity();
SharedPreferences defaultPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String suffix = "";
String title = arguments.getString(TITLE);
String url = "";
switch(which) {
case 0: // Video
suffix = arguments.getString(FILE_SUFFIX_VIDEO);
url = arguments.getString(VIDEO_URL);
break;
case 1:
suffix = arguments.getString(FILE_SUFFIX_AUDIO);
url = arguments.getString(AUDIO_URL);
break;
default:
Log.d(TAG, "lolz");
}
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(url));
request.setDestinationUri(Uri.fromFile(new File(
defaultPreferences.getString("download_path_preference", "/storage/emulated/0/NewPipe")
+ "/" + title + suffix)));
try {
dm.enqueue(request);
} catch (Exception e) {
e.printStackTrace();
}
}
});
return builder.create();
}
}

View File

@@ -1,7 +1,5 @@
package org.schabi.newpipe;
import android.graphics.Bitmap;
/**
* Created by Christian Schabesberger on 10.08.15.
*

View File

@@ -1,19 +1,23 @@
package org.schabi.newpipe;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
@@ -50,6 +54,7 @@ public class PlayVideoActivity extends AppCompatActivity {
private static final String POSITION = "position";
private static final long HIDING_DELAY = 3000;
private static final long TAB_HIDING_DELAY = 100;
private String videoUrl = "";
@@ -61,6 +66,11 @@ public class PlayVideoActivity extends AppCompatActivity {
private View decorView;
private boolean uiIsHidden = false;
private static long lastUiShowTime = 0;
private boolean isLandscape = true;
private boolean hasSoftKeys = false;
private SharedPreferences prefs;
private static final String PREF_IS_LANDSCAPE = "is_landscape";
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -68,6 +78,9 @@ public class PlayVideoActivity extends AppCompatActivity {
setContentView(R.layout.activity_play_video);
isLandscape = checkIfLandscape();
hasSoftKeys = checkIfHasSoftKeys();
actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
Intent intent = getIntent();
@@ -91,6 +104,7 @@ public class PlayVideoActivity extends AppCompatActivity {
videoView.seekTo(position);
if (position == 0) {
videoView.start();
showUi();
} else {
videoView.pause();
}
@@ -113,16 +127,27 @@ public class PlayVideoActivity extends AppCompatActivity {
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
uiIsHidden = false;
if (visibility == View.VISIBLE && uiIsHidden) {
showUi();
} else {
uiIsHidden = true;
hideUi();
}
}
});
showUi();
if (android.os.Build.VERSION.SDK_INT >= 17) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
prefs = getPreferences(Context.MODE_PRIVATE);
if(prefs.getBoolean(PREF_IS_LANDSCAPE, false) && !isLandscape) {
toggleOrientation();
}
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
}
@Override
@@ -134,6 +159,17 @@ public class PlayVideoActivity extends AppCompatActivity {
return true;
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
videoView.pause();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
@@ -149,14 +185,7 @@ public class PlayVideoActivity extends AppCompatActivity {
startActivity(Intent.createChooser(intent, getString(R.string.shareDialogTitle)));
break;
case R.id.menu_item_screen_rotation:
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if(display.getRotation() == Surface.ROTATION_0
|| display.getRotation() == Surface.ROTATION_180) {
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else if(display.getRotation() == Surface.ROTATION_90
|| display.getRotation() == Surface.ROTATION_270) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
toggleOrientation();
break;
default:
Log.e(TAG, "Error: MenuItem not known");
@@ -166,8 +195,16 @@ public class PlayVideoActivity extends AppCompatActivity {
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
isLandscape = true;
adjustMediaControlMetrics();
} else if (config.orientation == Configuration.ORIENTATION_PORTRAIT){
isLandscape = false;
adjustMediaControlMetrics();
}
}
@Override
@@ -187,15 +224,15 @@ public class PlayVideoActivity extends AppCompatActivity {
private void showUi() {
try {
uiIsHidden = false;
mediaController.show();
mediaController.show(100000);
actionBar.show();
//decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
//| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
adjustMediaControlMetrics();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if ((System.currentTimeMillis() - lastUiShowTime) > HIDING_DELAY) {
if ((System.currentTimeMillis() - lastUiShowTime) >= HIDING_DELAY) {
hideUi();
}
}
@@ -210,8 +247,90 @@ public class PlayVideoActivity extends AppCompatActivity {
uiIsHidden = true;
actionBar.hide();
mediaController.hide();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
//decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
//| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
if (android.os.Build.VERSION.SDK_INT >= 17) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
private void adjustMediaControlMetrics() {
MediaController.LayoutParams mediaControllerLayout
= new MediaController.LayoutParams(MediaController.LayoutParams.MATCH_PARENT,
MediaController.LayoutParams.WRAP_CONTENT);
if(!hasSoftKeys) {
mediaControllerLayout.setMargins(20, 0, 20, 20);
} else {
int width = getNavigationBarWidth();
int height = getNavigationBarHeight();
mediaControllerLayout.setMargins(width + 20, 0, width + 20, height + 20);
}
mediaController.setLayoutParams(mediaControllerLayout);
}
private boolean checkIfHasSoftKeys(){
if(Build.VERSION.SDK_INT >= 17) {
return getNavigationBarHeight() != 0 || getNavigationBarWidth() != 0;
} else {
return true;
}
}
private int getNavigationBarHeight() {
if(Build.VERSION.SDK_INT >= 17) {
Display d = getWindowManager().getDefaultDisplay();
DisplayMetrics realDisplayMetrics = new DisplayMetrics();
d.getRealMetrics(realDisplayMetrics);
DisplayMetrics displayMetrics = new DisplayMetrics();
d.getMetrics(displayMetrics);
int realHeight = realDisplayMetrics.heightPixels;
int displayHeight = displayMetrics.heightPixels;
return (realHeight - displayHeight);
} else {
return 50;
}
}
private int getNavigationBarWidth() {
if(Build.VERSION.SDK_INT >= 17) {
Display d = getWindowManager().getDefaultDisplay();
DisplayMetrics realDisplayMetrics = new DisplayMetrics();
d.getRealMetrics(realDisplayMetrics);
DisplayMetrics displayMetrics = new DisplayMetrics();
d.getMetrics(displayMetrics);
int realWidth = realDisplayMetrics.widthPixels;
int displayWidth = displayMetrics.widthPixels;
return (realWidth - displayWidth);
} else {
return 50;
}
}
public boolean checkIfLandscape() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels < displayMetrics.widthPixels;
}
private void toggleOrientation() {
if(isLandscape) {
isLandscape = false;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
isLandscape = true;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(PREF_IS_LANDSCAPE, isLandscape);
editor.commit();
}
}

View File

@@ -1,7 +1,5 @@
package org.schabi.newpipe;
import android.graphics.Bitmap;
import java.util.Vector;
/**

View File

@@ -21,28 +21,106 @@ package org.schabi.newpipe;
*/
import android.graphics.Bitmap;
import android.util.Log;
import java.util.Vector;
public class VideoInfo {
private static final String TAG = VideoInfo.class.toString();
// format identifier
public static final int I_MPEG_4 = 0x0;
public static final int I_3GPP = 0x1;
public static final int I_WEBM = 0x2;
public static final int I_M4A = 0x3;
public static final int I_WEBMA = 0x4;
// format name
public static final String F_MPEG_4 = "MPEG-4";
public static final String F_3GPP = "3GPP";
public static final String F_WEBM = "WebM";
public static final String F_M4A = "m4a";
public static final String F_WEBMA = "WebM";
// file suffix
public static final String C_MPEG_4 = "mp4";
public static final String C_3GPP = "3gp";
public static final String C_WEBM = "webm";
public static final String C_M4A = "m4a";
public static final String C_WEBMA = "webm";
// mimeType
public static final String M_MPEG_4 = "video/mp4";
public static final String M_3GPP = "video/3gpp";
public static final String M_WEBM = "video/webm";
public static final String M_M4A = "audio/mp4";
public static final String M_WEBMA = "audio/webm";
public static final int VIDEO_AVAILABLE = 0x00;
public static final int VIDEO_UNAVAILABLE = 0x01;
public static final int VIDEO_UNAVAILABLE_GEMA = 0x02;
public static class Stream {
public Stream(String u, String f, String r) {
url = u; format = f; resolution = r;
public static String getNameById(int id) {
switch(id) {
case I_MPEG_4: return F_MPEG_4;
case I_3GPP: return F_3GPP;
case I_WEBM: return F_WEBM;
case I_M4A: return F_M4A;
case I_WEBMA: return F_WEBMA;
default: Log.e(TAG, "format not known: " +
Integer.toString(id) + "call the programmer he messed it up.");
}
return "";
}
public static String getSuffixById(int id) {
switch(id) {
case I_MPEG_4: return C_MPEG_4;
case I_3GPP: return C_3GPP;
case I_WEBM: return C_WEBM;
case I_M4A: return C_M4A;
case I_WEBMA: return C_WEBMA;
default: Log.e(TAG, "format not known: " +
Integer.toString(id) + "call the programmer he messed it up.");
}
return "";
}
public static String getMimeById(int id) {
switch(id) {
case I_MPEG_4: return M_MPEG_4;
case I_3GPP: return M_3GPP;
case I_WEBM: return M_WEBM;
case I_M4A: return M_M4A;
case I_WEBMA: return M_WEBMA;
default: Log.e(TAG, "format not known: " +
Integer.toString(id) + "call the programmer he messed it up.");
}
return "";
}
public static class VideoStream {
public VideoStream(String url, int format, String res) {
this.url = url; this.format = format; resolution = res;
}
public String url = ""; //url of the stream
public String format = "";
public int format = -1;
public String resolution = "";
}
public static class AudioStream {
public AudioStream(String url, int format, int bandwidth, int samplingRate) {
this.url = url; this.format = format;
this.bandwidth = bandwidth; this.samplingRate = samplingRate;
}
public String url = "";
public int format = -1;
public int bandwidth = -1;
public int samplingRate = -1;
}
public String id = "";
public String uploader = "";
public String upload_date = "";
@@ -59,7 +137,8 @@ public class VideoInfo {
public String like_count = "";
public String dislike_count = "";
public String average_rating = "";
public Stream[] streams = null;
public VideoStream[] videoStreams = null;
public AudioStream[] audioStreams = null;
public VideoInfoItem nextVideo = null;
public Vector<VideoInfoItem> relatedVideos = null;
public int videoAvailableStatus = VIDEO_AVAILABLE;

View File

@@ -30,4 +30,6 @@ public class VideoInfoItem {
public String thumbnail_url = "";
public Bitmap thumbnail = null;
public String webpage_url = "";
public String upload_date = "";
public String view_count = "";
}

View File

@@ -0,0 +1,76 @@
package org.schabi.newpipe;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
/**
* Created by Christian Schabesberger on 24.10.15.
*
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* VideoInfoItemViewCreator.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 <http://www.gnu.org/licenses/>.
*/
public class VideoInfoItemViewCreator {
private static final String TAG = VideoInfoItemViewCreator.class.toString();
LayoutInflater inflater;
public VideoInfoItemViewCreator(LayoutInflater inflater) {
this.inflater = inflater;
}
public View getViewByVideoInfoItem(View convertView, ViewGroup parent, VideoInfoItem info) {
ViewHolder holder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.video_item, parent, false);
holder = new ViewHolder();
holder.itemThumbnailView = (ImageView) convertView.findViewById(R.id.itemThumbnailView);
holder.itemVideoTitleView = (TextView) convertView.findViewById(R.id.itemVideoTitleView);
holder.itemUploaderView = (TextView) convertView.findViewById(R.id.itemUploaderView);
holder.itemDurationView = (TextView) convertView.findViewById(R.id.itemDurationView);
holder.itemUploadDateView = (TextView) convertView.findViewById(R.id.itemUploadDateView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(info.thumbnail == null) {
holder.itemThumbnailView.setImageResource(R.drawable.dummi_thumbnail);
} else {
holder.itemThumbnailView.setImageBitmap(info.thumbnail);
}
holder.itemVideoTitleView.setText(info.title);
holder.itemUploaderView.setText(info.uploader);
holder.itemDurationView.setText(info.duration);
if(!info.upload_date.isEmpty()) {
holder.itemUploadDateView.setText(info.upload_date);
} else {
//tewak if nececeary: This is a hack preventing to have a white space in the layout :P
holder.itemUploadDateView.setText(info.view_count);
}
return convertView;
}
private class ViewHolder {
public ImageView itemThumbnailView;
public TextView itemVideoTitleView, itemUploaderView, itemDurationView, itemUploadDateView;
}
}

View File

@@ -1,18 +1,14 @@
package org.schabi.newpipe;
import android.content.ContentProviderOperation;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.util.Log;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import org.schabi.newpipe.youtube.YoutubeExtractor;
import android.widget.Toast;
/**
@@ -37,17 +33,18 @@ public class VideoItemDetailActivity extends AppCompatActivity {
private static final String TAG = VideoItemDetailActivity.class.toString();
VideoItemDetailFragment fragment;
private String videoUrl;
private int currentStreamingService = -1;
private Menu menu = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_videoitem_detail);
// 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
@@ -79,6 +76,10 @@ public class VideoItemDetailActivity extends AppCompatActivity {
break;
}
}
if(extractor == null) {
Toast.makeText(this, R.string.urlNotSupportedText, Toast.LENGTH_LONG)
.show();
}
arguments.putString(VideoItemDetailFragment.VIDEO_URL,
extractor.getVideoUrl(extractor.getVideoId(videoUrl)));
arguments.putBoolean(VideoItemDetailFragment.AUTO_PLAY,
@@ -91,14 +92,27 @@ public class VideoItemDetailActivity extends AppCompatActivity {
arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingService);
arguments.putBoolean(VideoItemDetailFragment.AUTO_PLAY, false);
}
// Create the detail fragment and add it to the activity
// using a fragment transaction.
VideoItemDetailFragment fragment = new VideoItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.add(R.id.videoitem_detail_container, fragment)
.commit();
} 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.
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

@@ -1,23 +1,32 @@
package org.schabi.newpipe;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.Image;
import android.os.Bundle;
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.ActionBar;
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;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.view.MenuItem;
import java.net.URL;
import java.util.Vector;
@@ -54,8 +63,19 @@ 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();
@@ -82,6 +102,13 @@ public class VideoItemDetailFragment extends Fragment {
new URL(videoInfo.uploader_thumbnail_url)
.openConnection()
.getInputStream()), SetThumbnailRunnable.CHANNEL_THUMBNAIL));
if(showNextVideoItem) {
h.post(new SetThumbnailRunnable(
BitmapFactory.decodeStream(
new URL(videoInfo.nextVideo.thumbnail_url)
.openConnection()
.getInputStream()), SetThumbnailRunnable.NEXT_VIDEO_THUMBNAIL));
}
}
} catch (Exception e) {
e.printStackTrace();
@@ -102,8 +129,9 @@ public class VideoItemDetailFragment extends Fragment {
}
private class SetThumbnailRunnable implements Runnable {
public static final int CHANNEL_THUMBNAIL = 2;
public static final int VIDEO_THUMBNAIL = 1;
public static final int CHANNEL_THUMBNAIL = 2;
public static final int NEXT_VIDEO_THUMBNAIL = 3;
private Bitmap thumbnail;
private int thumbnailId;
public SetThumbnailRunnable(Bitmap thumbnail, int id) {
@@ -122,19 +150,25 @@ public class VideoItemDetailFragment extends Fragment {
try {
switch (id) {
case SetThumbnailRunnable.VIDEO_THUMBNAIL:
thumbnailView = (ImageView) a.findViewById(R.id.detailThumbnailView);
break;
case SetThumbnailRunnable.CHANNEL_THUMBNAIL:
thumbnailView = (ImageView) a.findViewById(R.id.detailUploaderThumbnailView);
break;
case SetThumbnailRunnable.NEXT_VIDEO_THUMBNAIL:
FrameLayout nextVideoFrame = (FrameLayout) a.findViewById(R.id.detailNextVideoFrame);
thumbnailView = (ImageView) nextVideoFrame.findViewById(R.id.itemThumbnailView);
currentVideoInfo.nextVideo.thumbnail = thumbnail;
break;
default:
Log.d(TAG, "Error: Thumbnail id not known");
return;
}
if (thumbnailView != null) {
thumbnailView.setImageBitmap(thumbnail);
}
} catch (java.lang.NullPointerException e) {
// No god programm design i know. :/
Log.w(TAG, "updateThumbnail(): Fragment closed before thread ended work");
@@ -143,7 +177,12 @@ public class VideoItemDetailFragment extends Fragment {
public void updateInfo(VideoInfo info) {
Activity a = getActivity();
currentVideoInfo = info;
try {
VideoInfoItemViewCreator videoItemViewCreator =
new VideoInfoItemViewCreator(LayoutInflater.from(getActivity()));
ScrollView contentMainView = (ScrollView) a.findViewById(R.id.detailMainContent);
ProgressBar progressBar = (ProgressBar) a.findViewById(R.id.detailProgressBar);
TextView videoTitleView = (TextView) a.findViewById(R.id.detailVideoTitleView);
TextView uploaderView = (TextView) a.findViewById(R.id.detailUploaderView);
@@ -153,23 +192,19 @@ public class VideoItemDetailFragment extends Fragment {
TextView uploadDateView = (TextView) a.findViewById(R.id.detailUploadDateView);
TextView descriptionView = (TextView) a.findViewById(R.id.detailDescriptionView);
ImageView thumbnailView = (ImageView) a.findViewById(R.id.detailThumbnailView);
ImageView uploaderThumbnailView = (ImageView) a.findViewById(R.id.detailUploaderThumbnailView);
ImageView thumbsUpPic = (ImageView) a.findViewById(R.id.detailThumbsUpImgView);
ImageView thumbsDownPic = (ImageView) a.findViewById(R.id.detailThumbsDownImgView);
FrameLayout nextVideoFrame = (FrameLayout) a.findViewById(R.id.detailNextVideoFrame);
RelativeLayout nextVideoRootFrame =
(RelativeLayout) a.findViewById(R.id.detailNextVideoRootLayout);
View nextVideoView = videoItemViewCreator
.getViewByVideoInfoItem(null, nextVideoFrame, info.nextVideo);
nextVideoFrame.addView(nextVideoView);
Button nextVideoButton = (Button) a.findViewById(R.id.detailNextVideoButton);
contentMainView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
videoTitleView.setVisibility(View.VISIBLE);
uploaderView.setVisibility(View.VISIBLE);
uploadDateView.setVisibility(View.VISIBLE);
viewCountView.setVisibility(View.VISIBLE);
thumbsUpView.setVisibility(View.VISIBLE);
thumbsDownView.setVisibility(View.VISIBLE);
uploadDateView.setVisibility(View.VISIBLE);
descriptionView.setVisibility(View.VISIBLE);
thumbnailView.setVisibility(View.VISIBLE);
uploaderThumbnailView.setVisibility(View.VISIBLE);
thumbsUpPic.setVisibility(View.VISIBLE);
thumbsDownPic.setVisibility(View.VISIBLE);
if(!showNextVideoItem) {
nextVideoRootFrame.setVisibility(View.GONE);
}
switch (info.videoAvailableStatus) {
case VideoInfo.VIDEO_AVAILABLE: {
@@ -182,22 +217,34 @@ 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.Stream> streamsToUse = new Vector<>();
for (VideoInfo.Stream i : info.streams) {
Vector<VideoInfo.VideoStream> streamsToUse = new Vector<>();
for (VideoInfo.VideoStream i : info.videoStreams) {
if (useStream(i, streamsToUse)) {
streamsToUse.add(i);
}
}
VideoInfo.Stream[] streamList = new VideoInfo.Stream[streamsToUse.size()];
VideoInfo.VideoStream[] streamList = new VideoInfo.VideoStream[streamsToUse.size()];
for (int i = 0; i < streamList.length; i++) {
streamList[i] = streamsToUse.get(i);
}
ActionBarHandler.getHandler().setStreams(streamList);
actionBarHandler.setStreams(streamList, info.audioStreams);
}
break;
nextVideoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent detailIntent = new Intent(getActivity(), VideoItemDetailActivity.class);
detailIntent.putExtra(VideoItemDetailFragment.ARG_ITEM_ID, currentVideoInfo.nextVideo.id);
detailIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, currentVideoInfo.nextVideo.webpage_url);
//todo: make id dynamic the following line is crap
detailIntent.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, 0);
startActivity(detailIntent);
}
});
break;
case VideoInfo.VIDEO_UNAVAILABLE_GEMA:
thumbnailView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.gruese_die_gema_unangebracht));
break;
@@ -205,11 +252,11 @@ public class VideoItemDetailFragment extends Fragment {
thumbnailView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.not_available_monkey));
break;
default:
Log.e(TAG, "Video Availeble Status not known.");
Log.e(TAG, "Video Available Status not known.");
}
if(autoPlayEnabled) {
ActionBarHandler.getHandler().playVideo();
actionBarHandler.playVideo();
}
} catch (java.lang.NullPointerException e) {
Log.w(TAG, "updateInfo(): Fragment closed before thread ended work... or else");
@@ -217,8 +264,8 @@ public class VideoItemDetailFragment extends Fragment {
}
}
private boolean useStream(VideoInfo.Stream stream, Vector<VideoInfo.Stream> streams) {
for(VideoInfo.Stream i : streams) {
private boolean useStream(VideoInfo.VideoStream stream, Vector<VideoInfo.VideoStream> streams) {
for(VideoInfo.VideoStream i : streams) {
if(i.resolution.equals(stream.resolution)) {
return false;
}
@@ -236,23 +283,80 @@ public class VideoItemDetailFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
StreamingService streamingService = ServiceList.getService(
getArguments().getInt(STREAMING_SERVICE));
extractorThread = new Thread(new ExtractorRunnable(
getArguments().getString(VIDEO_URL), streamingService.getExtractorClass(), this));
autoPlayEnabled = getArguments().getBoolean(AUTO_PLAY);
extractorThread.start();
} catch (Exception e) {
e.printStackTrace();
}
activity = (AppCompatActivity) getActivity();
showNextVideoItem = PreferenceManager.getDefaultSharedPreferences(getActivity())
.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;
}
}
@Override
public void onActivityCreated(Bundle savedInstanceBundle) {
super.onActivityCreated(savedInstanceBundle);
FloatingActionButton playVideoButton = (FloatingActionButton) getActivity().findViewById(R.id.playVideoButton);
if(playVideoButton != null) {
try {
StreamingService streamingService = ServiceList.getService(
getArguments().getInt(STREAMING_SERVICE));
extractorThread = new Thread(new ExtractorRunnable(
getArguments().getString(VIDEO_URL), streamingService.getExtractorClass(), this));
autoPlayEnabled = getArguments().getBoolean(AUTO_PLAY);
extractorThread.start();
} catch (Exception e) {
e.printStackTrace();
}
if (PreferenceManager.getDefaultSharedPreferences(getActivity())
.getBoolean(getString(R.string.leftHandLayout), false) && checkIfLandscape()) {
RelativeLayout.LayoutParams oldLayout = (RelativeLayout.LayoutParams) playVideoButton.getLayoutParams();
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
layoutParams.setMargins(oldLayout.leftMargin, oldLayout.topMargin, oldLayout.rightMargin, oldLayout.bottomMargin);
playVideoButton.setLayoutParams(layoutParams);
}
playVideoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
actionBarHandler.playVideo();
}
});
}
}
public boolean checkIfLandscape() {
DisplayMetrics displayMetrics = new DisplayMetrics();
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

@@ -3,16 +3,13 @@ package org.schabi.newpipe;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.support.v7.widget.SearchView;
import android.widget.ImageView;
/**
@@ -44,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 {
@@ -64,7 +63,6 @@ public class VideoItemListActivity extends AppCompatActivity
// onQueryTextSubmit to trigger twice when focus is not cleared.
// See: http://stackoverflow.com/questions/17874951/searchview-onquerytextsubmit-runs-twice-while-i-pressed-once
getCurrentFocus().clearFocus();
hideWatermark();
} catch(Exception e) {
e.printStackTrace();
}
@@ -78,13 +76,6 @@ public class VideoItemListActivity extends AppCompatActivity
}
private void hideWatermark() {
ImageView waterMark = (ImageView) findViewById(R.id.list_view_watermark);
if(waterMark != null) {
waterMark.setVisibility(View.GONE);
}
}
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
@@ -110,7 +101,6 @@ public class VideoItemListActivity extends AppCompatActivity
searchQuery = savedInstanceState.getString(QUERY);
currentStreamingServiceId = savedInstanceState.getInt(STREAMING_SERVICE);
if(!searchQuery.isEmpty()) {
hideWatermark();
listFragment.search(searchQuery);
}
}
@@ -135,14 +125,10 @@ public class VideoItemListActivity extends AppCompatActivity
searchView.setIconifiedByDefault(false);
searchView.setIconified(false);
searchView.setOnQueryTextListener(new SearchVideoQueryListener());
ActionBarHandler.getHandler().setupNavMenu(this);
}
SettingsActivity.initSettings(this);
// TODO: If exposing deep links into your app, handle intents here.
}
/**
@@ -164,10 +150,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
@@ -181,10 +174,11 @@ public class VideoItemListActivity extends AppCompatActivity
}
public boolean onCreatePanelMenu(int featured, Menu menu) {
super.onCreatePanelMenu(featured, menu);
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
this.menu = menu;
MenuInflater inflater = getMenuInflater();
if(findViewById(R.id.videoitem_detail_container) == null) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.videoitem_list, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
@@ -192,9 +186,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;
@@ -207,8 +202,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

@@ -53,14 +53,14 @@ public class VideoItemListFragment extends ListFragment {
private class ResultRunnable implements Runnable {
private SearchEngine.Result result;
private int reuqestId;
private int requestId;
public ResultRunnable(SearchEngine.Result result, int requestId) {
this.result = result;
this.reuqestId = requestId;
this.requestId = requestId;
}
@Override
public void run() {
updateListOnResult(result, reuqestId);
updateListOnResult(result, requestId);
}
}
@@ -212,7 +212,7 @@ public class VideoItemListFragment extends ListFragment {
loadThumbsThread = new Thread(loadThumbsRunnable);
loadThumbsThread.start();
} catch(java.lang.IllegalStateException e) {
Log.w(TAG, "Trying to set value while activity is not existing anymore.");
Log.w(TAG, "Trying to set value while activity doesn't exist anymore.");
} catch(Exception e) {
e.printStackTrace();
}
@@ -229,7 +229,7 @@ public class VideoItemListFragment extends ListFragment {
}
if(searchThread != null) {
searchRunnable.terminate();
// No need to join, since we don't realy terminate the thread. We just demand
// No need to join, since we don't really terminate the thread. We just demand
// it to post its result runnable into the gui main loop.
}
}

View File

@@ -6,14 +6,12 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.Vector;
/**
* Created by the-scrabi on 11.08.15.
* Created by Christian Schabesberger on 11.08.15.
*
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* VideoListAdapter.java is part of NewPipe.
@@ -33,18 +31,20 @@ import java.util.Vector;
*/
public class VideoListAdapter extends BaseAdapter {
private static final String TAG = VideoListAdapter.class.toString();
private LayoutInflater inflater;
private Context context;
private VideoInfoItemViewCreator viewCreator;
private Vector<VideoInfoItem> videoList = new Vector<>();
private Vector<Boolean> downloadedThumbnailList = new Vector<>();
VideoItemListFragment videoListFragment;
ListView listView;
public VideoListAdapter(Context context, VideoItemListFragment videoListFragment) {
inflater = LayoutInflater.from(context);
viewCreator = new VideoInfoItemViewCreator(LayoutInflater.from(context));
this.videoListFragment = videoListFragment;
this.listView = videoListFragment.getListView();
this.context = context;
}
public void addVideoList(Vector<VideoInfoItem> videos) {
@@ -96,28 +96,7 @@ public class VideoListAdapter extends BaseAdapter {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.video_item, parent, false);
holder = new ViewHolder();
holder.itemThumbnailView = (ImageView) convertView.findViewById(R.id.itemThumbnailView);
holder.itemVideoTitleView = (TextView) convertView.findViewById(R.id.itemVideoTitleView);
holder.itemUploaderView = (TextView) convertView.findViewById(R.id.itemUploaderView);
holder.itemDurationView = (TextView) convertView.findViewById(R.id.itemDurationView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final Context context = parent.getContext();
if(videoList.get(position).thumbnail == null) {
holder.itemThumbnailView.setImageResource(R.drawable.dummi_thumbnail);
} else {
holder.itemThumbnailView.setImageBitmap(videoList.get(position).thumbnail);
}
holder.itemVideoTitleView.setText(videoList.get(position).title);
holder.itemUploaderView.setText(videoList.get(position).uploader);
holder.itemDurationView.setText(videoList.get(position).duration);
convertView = viewCreator.getViewByVideoInfoItem(convertView, parent, videoList.get(position));
if(listView.isItemChecked(position)) {
convertView.setBackgroundColor(context.getResources().getColor(R.color.primaryColorYoutube));
@@ -127,9 +106,4 @@ public class VideoListAdapter extends BaseAdapter {
return convertView;
}
private class ViewHolder {
public ImageView itemThumbnailView;
public TextView itemVideoTitleView, itemUploaderView, itemDurationView;
}
}
}

View File

@@ -1,27 +1,29 @@
package org.schabi.newpipe.youtube;
import android.util.Log;
import android.util.Xml;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.ScriptableObject;
import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.Extractor;
import org.schabi.newpipe.VideoInfo;
import org.schabi.newpipe.VideoInfoItem;
import org.xmlpull.v1.XmlPullParser;
import android.util.Log;
import java.io.StringReader;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.parser.Parser;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.ScriptableObject;
import org.schabi.newpipe.VideoInfoItem;
import java.util.regex.Pattern;
/**
* Created by Christian Schabesberger on 06.08.15.
@@ -45,29 +47,28 @@ import org.schabi.newpipe.VideoInfoItem;
public class YoutubeExtractor implements Extractor {
private static final String TAG = YoutubeExtractor.class.toString();
// These lists only contain itag formats that are supported by the common Android Video player.
// How ever if you are heading for a list showing all itag formats lock at
// https://github.com/rg3/youtube-dl/issues/1687
public static String resolveFormat(int itag) {
public static int resolveFormat(int itag) {
switch(itag) {
case 17: return VideoInfo.F_3GPP;
case 18: return VideoInfo.F_MPEG_4;
case 22: return VideoInfo.F_MPEG_4;
case 36: return VideoInfo.F_3GPP;
case 37: return VideoInfo.F_MPEG_4;
case 38: return VideoInfo.F_MPEG_4;
case 43: return VideoInfo.F_WEBM;
case 44: return VideoInfo.F_WEBM;
case 45: return VideoInfo.F_WEBM;
case 46: return VideoInfo.F_WEBM;
// video
case 17: return VideoInfo.I_3GPP;
case 18: return VideoInfo.I_MPEG_4;
case 22: return VideoInfo.I_MPEG_4;
case 36: return VideoInfo.I_3GPP;
case 37: return VideoInfo.I_MPEG_4;
case 38: return VideoInfo.I_MPEG_4;
case 43: return VideoInfo.I_WEBM;
case 44: return VideoInfo.I_WEBM;
case 45: return VideoInfo.I_WEBM;
case 46: return VideoInfo.I_WEBM;
default:
//Log.i(TAG, "Itag " + Integer.toString(itag) + " not known or not supported.");
return null;
return -1;
}
}
@@ -89,7 +90,7 @@ public class YoutubeExtractor implements Extractor {
}
}
private String decryptoinCode = "";
private String decryptionCode = "";
private static final String DECRYPTION_FUNC_NAME="decrypt";
@Override
@@ -97,7 +98,12 @@ public class YoutubeExtractor implements Extractor {
try {
URI uri = new URI(videoUrl);
if(uri.getHost().contains("youtube")) {
String query = uri.getQuery();
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) {
@@ -152,6 +158,7 @@ public class YoutubeExtractor implements Extractor {
//-------------------------------------
JSONObject playerArgs = null;
JSONObject ytAssets = null;
String dashManifest;
{
Pattern p = Pattern.compile("ytplayer.config\\s*=\\s*(\\{.*?\\});");
Matcher m = p.matcher(site);
@@ -178,14 +185,29 @@ 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
//videoInfo.view_count = playerArgs.getString("view_count");
String playerUrl = ytAssets.getString("js");
if(playerUrl.startsWith("//")) {
playerUrl = "https:" + playerUrl;
}
if(decryptionCode.isEmpty()) {
decryptionCode = loadDecryptionCode(playerUrl);
}
// 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 stream url
// extract video stream url
//------------------------------------
String encoded_url_map = playerArgs.getString("url_encoded_fmt_stream_map");
Vector<VideoInfo.Stream> streams = new Vector<>();
Vector<VideoInfo.VideoStream> videoStreams = new Vector<>();
for(String url_data_str : encoded_url_map.split(",")) {
Map<String, String> tags = new HashMap<>();
for(String raw_tag : Parser.unescapeEntities(url_data_str, true).split("&")) {
@@ -196,28 +218,24 @@ public class YoutubeExtractor implements Extractor {
int itag = Integer.parseInt(tags.get("itag"));
String streamUrl = terrible_unescape_workaround_fuck(tags.get("url"));
// if video has a signature decrypt it and add it to the url
// if video has a signature: decrypt it and add it to the url
if(tags.get("s") != null) {
String playerUrl = ytAssets.getString("js");
if(playerUrl.startsWith("//")) {
playerUrl = "https:" + playerUrl;
if(decryptionCode.isEmpty()) {
decryptionCode = loadDecryptionCode(playerUrl);
}
if(decryptoinCode.isEmpty()) {
decryptoinCode = loadDecryptioinCode(playerUrl);
}
streamUrl = streamUrl + "&signature=" + decriptSignature(tags.get("s"), decryptoinCode);
streamUrl = streamUrl + "&signature=" + decryptSignature(tags.get("s"), decryptionCode);
}
if(resolveFormat(itag) != null) {
streams.add(new VideoInfo.Stream(
streamUrl, //sometimes i have no idea what im programming -.-
if(resolveFormat(itag) != -1) {
videoStreams.add(new VideoInfo.VideoStream(
streamUrl,
resolveFormat(itag),
resolveResolutionString(itag)));
}
}
videoInfo.streams = new VideoInfo.Stream[streams.size()];
for(int i = 0; i < streams.size(); i++) {
videoInfo.streams[i] = streams.get(i);
videoInfo.videoStreams = new VideoInfo.VideoStream[videoStreams.size()];
for(int i = 0; i < videoStreams.size(); i++) {
videoInfo.videoStreams[i] = videoStreams.get(i);
}
} catch (Exception e) {
@@ -225,7 +243,7 @@ public class YoutubeExtractor implements Extractor {
}
//-------------------------------
// extrating from html page
// extracting from html page
//-------------------------------
@@ -286,28 +304,99 @@ public class YoutubeExtractor implements Extractor {
// view count
videoInfo.view_count = doc.select("div[class=\"watch-view-count\"]").first().text();
/* todo finish this code
// next video
videoInfo.nextVideo = extractVideoInfoItem(doc.select("div[class=\"watch-sidebar-section\"]").first()
.select("li").first());
int i = 0;
// related videos
videoInfo.relatedVideos = new Vector<>();
for(Element li : doc.select("ul[id=\"watch-related\"]").first().children()) {
// first check if we have a playlist. If so leave them out
if(li.select("a[class*=\"content-link\"]").first() != null) {
//videoInfo.relatedVideos.add(extractVideoInfoItem(li));
//i++;
//Log.d(TAG, Integer.toString(i));
videoInfo.relatedVideos.add(extractVideoInfoItem(li));
i++;
}
}
*/
return videoInfo;
}
private VideoInfo.AudioStream[] parseDashManifest(String dashManifest, String decryptoinCode) {
if(!dashManifest.contains("/signature/")) {
String encryptedSig = "";
String decryptedSig;
try {
Pattern p = Pattern.compile("/s/([a-fA-F0-9\\.]+)");
Matcher m = p.matcher(dashManifest);
m.find();
encryptedSig = m.group(1);
} catch (Exception e) {
e.printStackTrace();
}
decryptedSig = decryptSignature(encryptedSig, decryptoinCode);
dashManifest = dashManifest.replace("/s/" + encryptedSig, "/signature/" + decryptedSig);
}
String dashDoc = Downloader.download(dashManifest);
Vector<VideoInfo.AudioStream> audioStreams = new Vector<>();
try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new StringReader(dashDoc));
int eventType = parser.getEventType();
String tagName = "";
String currentMimeType = "";
int currentBandwidth = -1;
int currentSamplingRate = -1;
boolean currentTagIsBaseUrl = false;
while(eventType != XmlPullParser.END_DOCUMENT) {
switch(eventType) {
case XmlPullParser.START_TAG:
tagName = parser.getName();
if(tagName.equals("AdaptationSet")) {
currentMimeType = parser.getAttributeValue(XmlPullParser.NO_NAMESPACE, "mimeType");
} else if(tagName.equals("Representation") && currentMimeType.contains("audio")) {
currentBandwidth = Integer.parseInt(
parser.getAttributeValue(XmlPullParser.NO_NAMESPACE, "bandwidth"));
currentSamplingRate = Integer.parseInt(
parser.getAttributeValue(XmlPullParser.NO_NAMESPACE, "audioSamplingRate"));
} else if(tagName.equals("BaseURL")) {
currentTagIsBaseUrl = true;
}
break;
case XmlPullParser.TEXT:
if(currentTagIsBaseUrl &&
(currentMimeType.contains("audio"))) {
int format = -1;
if(currentMimeType.equals(VideoInfo.M_WEBMA)) {
format = VideoInfo.I_WEBMA;
} else if(currentMimeType.equals(VideoInfo.M_M4A)) {
format = VideoInfo.I_M4A;
}
audioStreams.add(new VideoInfo.AudioStream(parser.getText(),
format, currentBandwidth, currentSamplingRate));
}
case XmlPullParser.END_TAG:
if(tagName.equals("AdaptationSet")) {
currentMimeType = "";
} else if(tagName.equals("BaseURL")) {
currentTagIsBaseUrl = false;
}
break;
default:
}
eventType = parser.next();
}
} catch(Exception e) {
e.printStackTrace();
}
VideoInfo.AudioStream[] output = new VideoInfo.AudioStream[audioStreams.size()];
for(int i = 0; i < output.length; i++) {
output[i] = audioStreams.get(i);
}
return output;
}
private VideoInfoItem extractVideoInfoItem(Element li) {
VideoInfoItem info = new VideoInfoItem();
info.webpage_url = li.select("a[class*=\"content-link\"]").first()
@@ -320,11 +409,10 @@ public class YoutubeExtractor implements Extractor {
} catch (Exception e) {
e.printStackTrace();
}
info.title = li.select("span[class=\"title\"]").first()
.text();
info.title = li.select("span[class=\"title\"]").first().text();
info.view_count = li.select("span[class*=\"view-count\"]").first().text();
info.uploader = li.select("span[class=\"g-hovercard\"]").first().text();
info.duration = li.select("span[class=\"video-time\"]").first().text();
Element img = li.select("img").first();
@@ -335,7 +423,9 @@ public class YoutubeExtractor implements Extractor {
if(info.thumbnail_url.contains(".gif")) {
info.thumbnail_url = img.attr("data-thumb");
}
if(info.thumbnail_url.startsWith("//")) {
info.thumbnail_url = "https:" + info.thumbnail_url;
}
return info;
}
@@ -352,7 +442,7 @@ public class YoutubeExtractor implements Extractor {
return retval;
}
private String loadDecryptioinCode(String playerUrl) {
private String loadDecryptionCode(String playerUrl) {
String playerCode = Downloader.download(playerUrl);
String decryptionFuncName = "";
String decryptionFunc = "";
@@ -394,7 +484,7 @@ public class YoutubeExtractor implements Extractor {
return decryptionCode;
}
private String decriptSignature(String encryptedSig, String decryptoinCode) {
private String decryptSignature(String encryptedSig, String decryptoinCode) {
Context context = Context.enter();
context.setOptimizationLevel(-1);
Object result = null;

View File

@@ -1,18 +1,17 @@
package org.schabi.newpipe.youtube;
import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.SearchEngine;
import org.schabi.newpipe.VideoInfoItem;
import android.net.Uri;
import android.util.Log;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.SearchEngine;
import org.schabi.newpipe.VideoInfoItem;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by Christian Schabesberger on 09.08.15.
@@ -97,6 +96,9 @@ public class YoutubeSearchEngine implements SearchEngine {
resultItem.uploader = item.select("div[class=\"yt-lockup-byline\"]").first()
.select("a").first()
.text();
resultItem.upload_date = item.select("div[class=\"yt-lockup-meta\"]").first()
.select("li").first()
.text();
Element te = item.select("div[class=\"yt-thumb video-thumb\"]").first()
.select("img").first();
resultItem.thumbnail_url = te.attr("abs:src");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#000000" />
<stroke android:width="1dip" android:color="#888"/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

View File

@@ -0,0 +1,208 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="?android:attr/textAppearanceLarge"
tools:context=".VideoItemDetailFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/videoitem_detail">
<ProgressBar android:id="@+id/detailProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"/>
<ScrollView
android:id="@+id/detailMainContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textIsSelectable="true"
android:visibility="invisible">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<ImageView android:id="@+id/detailThumbnailView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:src="@drawable/dummi_thumbnail"/>
<TextView android:id="@+id/detailVideoTitleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailThumbnailView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Bla blabla !!!"/>
<ImageView android:id="@+id/detailUploaderThumbnailView"
android:layout_width="80dp"
android:layout_height="100dp"
android:paddingTop="25dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentLeft="true"
android:src="@drawable/budy" />
<TextView android:id="@+id/detailUploaderView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderThumbnailView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Herr von Gurken" />
<View android:id="@+id/textSeperationLine"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"
android:layout_below="@id/detailUploaderView"
android:paddingTop="20dp"
android:layout_alignParentLeft="true" />
<TextView android:id="@+id/detailViewCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentRight="true"
android:paddingTop="70dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="1.000.115 views" />
<TextView android:id="@+id/detailThumbsDownCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView"
android:layout_alignParentRight="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="5.000" />
<ImageView android:id="@+id/detailThumbsDownImgView"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownCountView"
android:src="@drawable/thumbs_down" />
<TextView android:id="@+id/detailThumbsUpCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownImgView"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="111.111" />
<ImageView android:id="@+id/detailThumbsUpImgView"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsUpCountView"
android:src="@drawable/thumbs_up" />
<TextView android:id="@+id/detailUploadDateView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="20dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Uploaded at: 45.64.1285" />
<TextView android:id="@+id/detailDescriptionView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploadDateView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmodtempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "
/>
<RelativeLayout android:id="@+id/detailNextVideoRootLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/detailDescriptionView" >
<TextView android:id="@+id/detailNextVideoTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="20dp"
android:paddingBottom="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@android:color/black"
android:text="@string/nextVideoTitle"
/>
<View android:id="@+id/detailNextVideoSeperationLine"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:background="@android:color/darker_gray"
android:layout_below="@id/detailNextVideoTitle"
android:layout_alignParentLeft="true" />
<RelativeLayout android:id="@+id/detailNextVidButtonAndContantLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/detailNextVideoSeperationLine">
<FrameLayout
android:id="@+id/detailNextVideoFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/detailNextVideoButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignTop="@id/detailNextVideoFrame"
android:layout_alignBottom="@id/detailNextVideoFrame"
android:background="?attr/selectableItemBackground"/>
</RelativeLayout>
<View android:id="@+id/detailNextVideoSeperationLineEnd"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:background="@android:color/darker_gray"
android:layout_below="@id/detailNextVidButtonAndContantLayout"
android:layout_alignParentLeft="true" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_below="@id/detailNextVideoRootLayout"/>
</RelativeLayout>
</ScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/playVideoButton"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="@color/primaryColorYoutube"
android:src="@drawable/ic_play_arrow_black"
android:layout_margin="16dip"/>
</RelativeLayout>

View File

@@ -42,12 +42,6 @@
android:layout_width="0dp"
android:layout_weight="4">
<ImageView android:id="@+id/list_view_watermark"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:src="@drawable/new_pipe_watermark"/>
<FrameLayout android:id="@+id/videoitem_detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />

View File

@@ -1,139 +1,208 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/videoitem_detail"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="?android:attr/textAppearanceLarge"
tools:context=".VideoItemDetailFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textIsSelectable="true"
tools:context=".VideoItemDetailFragment">
android:id="@+id/videoitem_detail">
<RelativeLayout
<ProgressBar android:id="@+id/detailProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"/>
<ScrollView
android:id="@+id/detailMainContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
android:textIsSelectable="true"
android:visibility="invisible">
<ProgressBar android:id="@+id/detailProgressBar"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:indeterminate="true"/>
<ImageView android:id="@+id/detailThumbnailView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:src="@drawable/dummi_thumbnail"
android:visibility="invisible"/>
android:padding="16dp">
<TextView android:id="@+id/detailVideoTitleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailThumbnailView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Bla blabla !!!"
android:visibility="invisible"/>
<ImageView android:id="@+id/detailThumbnailView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:src="@drawable/dummi_thumbnail"/>
<ImageView android:id="@+id/detailUploaderThumbnailView"
android:layout_width="80dp"
android:layout_height="100dp"
android:paddingTop="25dp"
android:paddingLeft="5dp"
android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentLeft="true"
android:visibility="invisible"
android:src="@drawable/budy" />
<TextView android:id="@+id/detailVideoTitleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailThumbnailView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Bla blabla !!!"/>
<TextView android:id="@+id/detailUploaderView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderThumbnailView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="invisible"
android:text="Herr von Gurken" />
<ImageView android:id="@+id/detailUploaderThumbnailView"
android:layout_width="80dp"
android:layout_height="100dp"
android:paddingTop="25dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentLeft="true"
android:src="@drawable/budy" />
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"
android:layout_below="@id/detailUploaderView"
android:paddingTop="20dp"
android:visibility="invisible"
android:layout_alignParentLeft="true" />
<TextView android:id="@+id/detailUploaderView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderThumbnailView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Herr von Gurken" />
<TextView android:id="@+id/detailViewCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentRight="true"
android:paddingTop="70dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:visibility="invisible"
android:text="1.000.115 views" />
<View android:id="@+id/textSeperationLine"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"
android:layout_below="@id/detailUploaderView"
android:paddingTop="20dp"
android:layout_alignParentLeft="true" />
<TextView android:id="@+id/detailThumbsDownCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView"
android:layout_alignParentRight="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="invisible"
android:text="5.000" />
<TextView android:id="@+id/detailViewCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentRight="true"
android:paddingTop="70dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="1.000.115 views" />
<ImageView android:id="@+id/detailThumbsDownImgView"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownCountView"
android:visibility="invisible"
android:src="@drawable/thumbs_down" />
<TextView android:id="@+id/detailThumbsDownCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView"
android:layout_alignParentRight="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="5.000" />
<TextView android:id="@+id/detailThumbsUpCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownImgView"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="invisible"
android:text="111.111" />
<ImageView android:id="@+id/detailThumbsDownImgView"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownCountView"
android:src="@drawable/thumbs_down" />
<ImageView android:id="@+id/detailThumbsUpImgView"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsUpCountView"
android:visibility="invisible"
android:src="@drawable/thumbs_up" />
<TextView android:id="@+id/detailThumbsUpCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownImgView"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="111.111" />
<TextView android:id="@+id/detailUploadDateView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingTop="20dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:visibility="invisible"
android:text="Uploaded at: 45.64.1285" />
<ImageView android:id="@+id/detailThumbsUpImgView"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsUpCountView"
android:src="@drawable/thumbs_up" />
<TextView android:id="@+id/detailDescriptionView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploadDateView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="invisible"
android:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmodtempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "
/>
<TextView android:id="@+id/detailUploadDateView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="20dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Uploaded at: 45.64.1285" />
</RelativeLayout>
<TextView android:id="@+id/detailDescriptionView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploadDateView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmodtempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "
/>
</ScrollView>
<RelativeLayout android:id="@+id/detailNextVideoRootLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/detailDescriptionView" >
<TextView android:id="@+id/detailNextVideoTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="20dp"
android:paddingBottom="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@android:color/black"
android:text="@string/nextVideoTitle"
/>
<View android:id="@+id/detailNextVideoSeperationLine"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:background="@android:color/darker_gray"
android:layout_below="@id/detailNextVideoTitle"
android:layout_alignParentLeft="true" />
<RelativeLayout android:id="@+id/detailNextVidButtonAndContantLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/detailNextVideoSeperationLine">
<FrameLayout
android:id="@+id/detailNextVideoFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/detailNextVideoButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignTop="@id/detailNextVideoFrame"
android:layout_alignBottom="@id/detailNextVideoFrame"
android:background="?attr/selectableItemBackground"/>
</RelativeLayout>
<View android:id="@+id/detailNextVideoSeperationLineEnd"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:background="@android:color/darker_gray"
android:layout_below="@id/detailNextVidButtonAndContantLayout"
android:layout_alignParentLeft="true" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_below="@id/detailNextVideoRootLayout"/>
</RelativeLayout>
</ScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/playVideoButton"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="@color/primaryColorYoutube"
android:src="@drawable/ic_play_arrow_black"
android:layout_margin="16dip"/>
</RelativeLayout>

View File

@@ -9,17 +9,20 @@
<VideoView android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
android:layout_gravity="center"
android:focusable="false"/>
<Button android:id="@+id/content_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null" />
android:background="@null"
android:focusable="false"/>
<ProgressBar android:id="@+id/play_video_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_gravity="center"/>
android:layout_gravity="center"
android:focusable="false"/>
</FrameLayout>

View File

@@ -1,13 +1,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView android:id="@+id/list_view_watermark"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:src="@drawable/new_pipe_watermark"/>
android:orientation="vertical">
<fragment
xmlns:tools="http://schemas.android.com/tools"
@@ -16,6 +10,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".VideoItemListActivity"
tools:layout="@android:layout/list_content" />
tools:layout="@android:layout/list_content"/>
</LinearLayout>

View File

@@ -1,133 +1,204 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/videoitem_detail"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".VideoItemDetailFragment"
android:textIsSelectable="true"
style="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textIsSelectable="true"
tools:context=".VideoItemDetailFragment">
android:id="@+id/videoitem_detail">
<RelativeLayout
<ProgressBar android:id="@+id/detailProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"/>
<ScrollView
android:id="@+id/detailMainContent"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:visibility="invisible">
<ProgressBar android:id="@+id/detailProgressBar"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:indeterminate="true"/>
android:layout_height="wrap_content">
<ImageView android:id="@+id/detailThumbnailView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:visibility="invisible"
android:src="@drawable/dummi_thumbnail"/>
<ImageView android:id="@+id/detailThumbnailView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:src="@drawable/dummi_thumbnail"/>
<TextView android:id="@+id/detailVideoTitleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailThumbnailView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingBottom="20dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:visibility="invisible"
android:text="Bla blabla !!!"/>
<TextView android:id="@+id/detailVideoTitleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailThumbnailView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingBottom="20dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Bla blabla !!!"/>
<ImageView android:id="@+id/detailUploaderThumbnailView"
android:layout_width="85dp"
android:layout_height="100dp"
android:paddingTop="25dp"
android:paddingLeft="2dp"
android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentLeft="true"
android:visibility="invisible"
android:src="@drawable/budy" />
<ImageView android:id="@+id/detailUploaderThumbnailView"
android:layout_width="85dp"
android:layout_height="100dp"
android:paddingTop="25dp"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentLeft="true"
android:src="@drawable/budy" />
<TextView android:id="@+id/detailUploaderView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderThumbnailView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="invisible"
android:text="Herr von Gurken" />
<TextView android:id="@+id/detailUploaderView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderThumbnailView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Herr von Gurken" />
<TextView android:id="@+id/detailViewCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="25dp"
android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentRight="true"
android:paddingRight="16dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:visibility="invisible"
android:text="drölf views" />
<TextView android:id="@+id/detailViewCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="25dp"
android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentRight="true"
android:paddingRight="16dp"
android:paddingLeft="16dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="drölf views" />
<TextView android:id="@+id/detailThumbsDownCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView"
android:layout_alignParentRight="true"
android:paddingRight="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="invisible"
android:text="-5.000" />
<TextView android:id="@+id/detailThumbsDownCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView"
android:layout_alignParentRight="true"
android:paddingRight="16dp"
android:paddingLeft="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="-5.000" />
<ImageView android:id="@+id/detailThumbsDownImgView"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownCountView"
android:visibility="invisible"
android:src="@drawable/thumbs_down" />
<ImageView android:id="@+id/detailThumbsDownImgView"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownCountView"
android:src="@drawable/thumbs_down" />
<TextView android:id="@+id/detailThumbsUpCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownImgView"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="invisible"
android:text="∞" />
<TextView android:id="@+id/detailThumbsUpCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownImgView"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="∞" />
<ImageView android:id="@+id/detailThumbsUpImgView"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsUpCountView"
android:visibility="invisible"
android:src="@drawable/thumbs_up" />
<ImageView android:id="@+id/detailThumbsUpImgView"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsUpCountView"
android:src="@drawable/thumbs_up" />
<TextView android:id="@+id/detailUploadDateView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingTop="20dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:visibility="invisible"
android:text="Uploaded at: 45.64.1285" />
<TextView android:id="@+id/detailUploadDateView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="20dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Uploaded at: 45.64.1285" />
<TextView android:id="@+id/detailDescriptionView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploadDateView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="invisible"
android:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmodtempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "
/>
<TextView android:id="@+id/detailDescriptionView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detailUploadDateView"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmodtempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "
/>
</RelativeLayout>
<RelativeLayout android:id="@+id/detailNextVideoRootLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/detailDescriptionView" >
</ScrollView>
<TextView android:id="@+id/detailNextVideoTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="20dp"
android:paddingBottom="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@android:color/black"
android:text="@string/nextVideoTitle"
/>
<View android:id="@+id/detailNextVideoSeperationLine"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:background="@android:color/darker_gray"
android:layout_below="@id/detailNextVideoTitle"
android:layout_alignParentLeft="true" />
<RelativeLayout android:id="@+id/detailNextVidButtonAndContantLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/detailNextVideoSeperationLine">
<FrameLayout
android:id="@+id/detailNextVideoFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/detailNextVideoButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignTop="@id/detailNextVideoFrame"
android:layout_alignBottom="@id/detailNextVideoFrame"
android:background="?attr/selectableItemBackground"/>
</RelativeLayout>
<View android:id="@+id/detailNextVideoSeperationLineEnd"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:background="@android:color/darker_gray"
android:layout_below="@id/detailNextVidButtonAndContantLayout"
android:layout_alignParentLeft="true" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_below="@id/detailNextVideoRootLayout"/>
</RelativeLayout>
</ScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/playVideoButton"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="@color/primaryColorYoutube"
android:src="@drawable/ic_play_arrow_black"
android:layout_margin="16dip"/>
</RelativeLayout>

View File

@@ -7,19 +7,24 @@
android:padding="6dp">
<ImageView android:id="@+id/itemThumbnailView"
android:layout_width="125dp"
android:layout_height="70dp"
android:layout_width="142dp"
android:layout_height="80dp"
android:scaleType="centerCrop"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:src="@drawable/dummi_thumbnail"/>
<TextView android:id="@+id/itemVideoTitleView"
android:layout_width="wrap_content"
android:layout_height="55dp"
android:layout_height="40dp"
android:layout_toRightOf="@id/itemThumbnailView"
android:layout_alignParentTop="true"
android:paddingLeft="6dp"
android:textAppearance="?android:attr/textAppearanceLarge" />
android:paddingTop="4dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/text_search_title_size"
android:text="title"
/>
<TextView android:id="@+id/itemUploaderView"
android:layout_width="wrap_content"
@@ -27,16 +32,37 @@
android:layout_toRightOf="@id/itemThumbnailView"
android:layout_below="@id/itemVideoTitleView"
android:paddingLeft="6dp"
android:textAppearance="?android:attr/textAppearanceSmall"/>
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/text_search_uploader_size"
android:text="uploader"/>
<TextView android:id="@+id/itemDurationView"
<TextView android:id="@+id/itemUploadDateView"
android:text="itemUploadDateView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/itemThumbnailView"
android:layout_below="@id/itemUploaderView"
android:paddingLeft="6dp"
android:textAppearance="?android:attr/textAppearanceMedium"/>
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/text_search_uploadtime_size"
/>
<TextView android:id="@+id/itemDurationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/itemThumbnailView"
android:layout_alignRight="@id/itemThumbnailView"
android:layout_marginRight="6dp"
android:layout_marginBottom="12dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:paddingTop="1dp"
android:paddingBottom="1dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/text_search_duration_size"
android:background="@drawable/durationback"
android:textColor="#f7f7f7"
android:text="duration"
/>
</RelativeLayout>

View File

@@ -3,13 +3,23 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_item_play"
android:title="@string/play"
app:showAsAction="ifRoom"
android:icon="@drawable/ic_play_arrow_black"/>
<item android:id="@+id/menu_item_play_audio"
android:title="@string/playAudio"
app:showAsAction="always"
android:icon="@drawable/ai_play"/>
android:icon="@drawable/ic_headset_black" />
<item android:id="@+id/menu_item_share"
android:title="@string/share"
app:showAsAction="ifRoom"
android:icon="@drawable/ai_share"/>
android:icon="@drawable/ic_share_black"/>
<item android:id="@+id/action_play_with_kodi"
android:title="@string/playWithKodiTitle"
app:showAsAction="ifRoom"
android:icon="@drawable/ic_cast_black"/>
<item android:id="@+id/menu_item_openInBrowser"
app:showAsAction="never"
@@ -22,4 +32,6 @@
<item android:id="@+id/action_settings"
app:showAsAction="never"
android:title="@string/settings"/>
</menu>

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: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">Nichts gefunden</string>
<string name="viewSufix">views</string>
<string name="viewSufix">Aufrufe</string>
<string name="uploadDatePrefix">Hochgeladen am: </string>
<string name="noPlayerFound">Keinen Streamplayer gefunden. Vielleicht möchtest du einen installieren.</string>
<string name="installStreamPlayer">Jetzt installieren</string>
@@ -28,4 +29,23 @@
<string name="autoPlayThroughIntentTitle">Automatisch abspielen durch Intent.</string>
<string name="autoPlayThroughIntentSummary">Startet ein Video automatisch wenn es von einer anderen App aufgerufen wurde.</string>
<string name="defaultResolutionPreferenceTitle">Standard Auflösung</string>
<string name="playWithKodiTitle">Mit Kodi abspielen</string>
<string name="koreNotFound">Kore app wurde nicht gefunden. Kore wird benötigt, um Videos mit Kodi wieder zu geben.</string>
<string name="installeKore">Kore installieren</string>
<string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string>
<string name="showPlayWithKodiTitle">Zeige \"Mit Kodi abspielen\" Option</string>
<string name="showPlayWithKodiSummary">Zeigt eine Option an, über die man Videos mit dem Kodi Mediacenter abspielen kann.</string>
<string name="leftPlayButtonTitle">Zeige play button auf der linken seite.</string>
<string name="playAudio">Audio</string>
<string name="defaultAudioFormatTitle">Bevorzugtes Audio Format</string>
<string name="webMAudioDescription">WebM - freies Format</string>
<string name="m4aAudioDescription">m4a - bessere Qualität</string>
<string name="downloadDialogTitle">Herunterladen</string>
<string-array name="downloadOptions">
<item>Video</item>
<item>Audio</item>
</string-array>
<string name="nextVideoTitle">Nächstes Video</string>
<string name="showNextVideoTitle">Zeige \"Nächstes Video\" Auswahl.</string>
<string name="urlNotSupportedText">Url wird nicht unterstützt.</string>
</resources>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">No se ha encontrado nada</string>
<string name="viewSufix">visitas</string>
<string name="uploadDatePrefix">Subido desde: </string>
<string name="noPlayerFound">No se ha encontrado ningún reproductor de vídeo. Quizás quieras instalar alguno.</string>
<string name="installStreamPlayer">Instalar</string>
<string name="cancel">Cancelar</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">Abrir en navegador</string>
<string name="share">Compartir</string>
<string name="play">Reproducir</string>
<string name="download">Descargar</string>
<string name="search">Buscar</string>
<string name="settings">Ajustes</string>
<string name="sendWith">Enviar con</string>
<string name="didYouMean">Querias decir: </string>
<string name="searchPage">Buscar página: </string>
<string name="shareDialogTitle">Compartir con:</string>
<string name="chooseBrowser">Selecciona navegador:</string>
<string name="screenRotation">rotación</string>
<string name="title_activity_settings">Ajustes</string>
<string name="useExternalPlayerTitle">Usar reproductor externo</string>
<string name="downloadLocation">Descargar en...</string>
<string name="downloadLocationSummary">Donde se guardarán los vídeos descargados.</string>
<string name="downloadLocationDialogTitle">Localización del directorio de descargas</string>
<string name="autoPlayThroughIntentTitle">Reproducción automática</string>
<string name="autoPlayThroughIntentSummary">Reproduce los vídeos automaticamente cuando la llamada viene de otra aplicación.</string>
<string name="defaultResolutionPreferenceTitle">Resolución por defecto</string>
<string name="playWithKodiTitle">Reproducir con Kodi</string>
<string name="koreNotFound">Aplicación Kore no encontrada. Kore es necesario para reproducir vídeos con Kodi media center.</string>
<string name="installeKore">Instalar Kore</string>
<string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string>
<string name="showPlayWithKodiTitle">Mostrar la opción \"Reproducir con Kodi\"</string>
<string name="showPlayWithKodiSummary">Muestra una opción para reproducir vídeo vía Kodi media center.</string>
</resources>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">NewPipe</string>
<string name="autoPlayThroughIntentSummary">Démarrer automatiquement la vidéo si elle a été appellée à partir d\'une autre application.</string>
<string name="cancel">Annuler</string>
<string name="chooseBrowser">Choisir un navigateur:</string>
<string name="defaultResolutionPreferenceTitle">Résolution par défaut:</string>
<string name="didYouMean">S\'agirait-il de:</string>
<string name="download">Télécharger</string>
<string name="downloadLocation">Emplacement des téléchargements</string>
<string name="downloadLocationDialogTitle">Entrez l\'emplacement du téléchargement</string>
<string name="downloadLocationSummary">Emplacement des vidéos téléchargées.</string>
<string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="installStreamPlayer">Installer</string>
<string name="installeKore">Installer Kore</string>
<string name="koreNotFound">L\'application Kore est introuvable. Kore est nécessaire afin de lire des vidéos dans Kodi media center.</string>
<string name="noPlayerFound">Aucun lecteur de streaming détecté. Vous devriez en installer un.</string>
<string name="nothingFound">Aucun résultat.</string>
<string name="open_in_browser">Ouvrir dans le navigateur</string>
<string name="play">Lire</string>
<string name="autoPlayThroughIntentTitle">Lecture automatique via Intent.</string>
<string name="playWithKodiTitle">Lire avec Kodi</string>
<string name="screenRotation">rotation</string>
<string name="search">Chercher</string>
<string name="searchPage">Chercher dans la page:</string>
<string name="sendWith">Envoyer avec</string>
<string name="settings">Paramètres</string>
<string name="share">Partager</string>
<string name="shareDialogTitle">Partager avec:</string>
<string name="showPlayWithKodiSummary">Afficher une option pour lire la vidéo avec Kodi media center.</string>
<string name="showPlayWithKodiTitle">Afficher l\'option \"Lire avec Kodi\"</string>
<string name="title_activity_settings">Paramètres</string>
<string name="title_videoitem_detail">NewPipe</string>
<string name="uploadDatePrefix">Envoyé le:</string>
<string name="useExternalPlayerTitle">Utiliser un lecteur externe</string>
<string name="viewSufix">vues</string>
</resources>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">Nincs találat</string>
<string name="viewSufix">megtekintés</string>
<string name="uploadDatePrefix">Feltöltve: </string>
<string name="noPlayerFound">Nem található lejátszó. Telepítsen egyet!</string>
<string name="installStreamPlayer">Telepítsen egyet</string>
<string name="cancel">Mégse</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">Megnyitás böngészőben</string>
<string name="share">Megosztás</string>
<string name="play">Lejátszás</string>
<string name="download">Letöltés</string>
<string name="search">Keresés</string>
<string name="settings">Beállítások</string>
<string name="sendWith">Küldés ezzel:</string>
<string name="didYouMean">Erre gondolt: </string>
<string name="searchPage">Keresési lap: </string>
<string name="shareDialogTitle">Megosztás ezzel:</string>
<string name="chooseBrowser">Válasszon böngészőt:</string>
<string name="screenRotation">forgatás</string>
<string name="title_activity_settings">Beállítások</string>
<string name="useExternalPlayerTitle">Külső lejátszó használata</string>
<string name="downloadLocation">Letöltések helye</string>
<string name="downloadLocationSummary">Útvonal a letöltött videók tárolásához</string>
<string name="downloadLocationDialogTitle">Adja meg a letöltési útvonalat</string>
<string name="autoPlayThroughIntentTitle">Automatikus lejátszás Intent-en keresztül</string>
<string name="autoPlayThroughIntentSummary">Automatikusan elindítja a videót, ha az külső alkalmazásból volt hívva</string>
<string name="defaultResolutionPreferenceTitle">Alapértelmezett felbontás</string>
<string name="playWithKodiTitle">Lejátszás Kodi-val</string>
<string name="koreNotFound">A Kore alkalmazás nem található. A Kore szükséges a videók Kodi médiaközponttal való lejátszásához.</string>
<string name="installeKore">Kore telepítése</string>
<string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string>
<string name="showPlayWithKodiTitle">\"Lejátszás Kodi-val\" opció mutatása</string>
<string name="showPlayWithKodiSummary">Mutat egy opciót a videók Kodi médiaközponttal való lejátszására</string>
<string name="leftPlayButtonTitle">Lejátszás gomb bal oldalon mutatása</string>
<string name="playAudio">Hang</string>
<string name="defaultAudioFormatTitle">Alapértelmezett hang formátum</string>
<string name="webMAudioDescription">WebM - szabad formátum</string>
<string name="m4aAudioDescription">m4a - jobb minőség</string>
<string name="downloadDialogTitle">Letöltés</string>
<string-array name="downloadOptions">
<item>Videó</item>
<item>Hang</item>
</string-array>
</resources>

View File

@@ -0,0 +1,38 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">Geen resultaten</string>
<string name="viewSufix">keer bekeken</string>
<string name="uploadDatePrefix">Geüpload op: </string>
<string name="noPlayerFound">Geen speler met streaming ondersteuning gevonden. Je wilt er misschien een installeren.</string>
<string name="installStreamPlayer">Installeer speler</string>
<string name="cancel">Annuleer</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">Open in browser</string>
<string name="share">Deel</string>
<string name="play">Speel af</string>
<string name="download">Download</string>
<string name="search">Zoek</string>
<string name="settings">Instellingen</string>
<string name="sendWith">Verstuur met</string>
<string name="didYouMean">Bedoelde je: </string>
<string name="searchPage">Zoekpagina: </string>
<string name="shareDialogTitle">Deel met:</string>
<string name="chooseBrowser">Kies browser:</string>
<string name="screenRotation">rotatie</string>
<string name="title_activity_settings">Instellingen</string>
<string name="useExternalPlayerTitle">Gebruik externe speler</string>
<string name="downloadLocation">Downloadlocatie</string>
<string name="downloadLocationSummary">Locatie om gedownloadde videos in op te slaan.</string>
<string name="downloadLocationDialogTitle">Voer downloadlocatie is</string>
<string name="autoPlayThroughIntentTitle">Speel automatisch via Intent</string>
<string name="autoPlayThroughIntentSummary">Speel een video automatisch af indien geopend vanuit een andere app.</string>
<string name="defaultResolutionPreferenceTitle">Standaardresolutie</string>
<string name="playWithKodiTitle">Speel af met Kodi</string>
<string name="koreNotFound">Kore app niet gevonden. Kore is nodig om videos op Kodi af te spelen.</string>
<string name="installeKore">Installeer Kore</string>
<string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string>
<string name="showPlayWithKodiTitle">Toon \"Speel af met Kodi\" optie</string>
<string name="showPlayWithKodiSummary">Toont een optie om een video op een Kodi media center af te spelen.</string>
</resources>

View File

@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Јутјуб цев</string>
<string name="title_videoitem_detail">Јутјуб цев</string>
@@ -28,4 +29,20 @@
<string name="autoPlayThroughIntentTitle">Аутопуштање преко Интента</string>
<string name="autoPlayThroughIntentSummary">Аутоматски почиње пушта видео по позиву из друге апликације.</string>
<string name="defaultResolutionPreferenceTitle">Подразумевана резолуција</string>
</resources>
<string name="playWithKodiTitle">Пусти помоћу Кодија</string>
<string name="koreNotFound">Апликација Кор није нађена. Кор (Kore) је потребан да бисте пуштали видее у Коди медија центру.</string>
<string name="installeKore">Инсталирај Кор</string>
<string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string>
<string name="showPlayWithKodiTitle">Прикажи „Пусти помоћу Кодија“</string>
<string name="showPlayWithKodiSummary">Приказ опције за пуштање видеа у Коди медија центру.</string>
<string name="leftPlayButtonTitle">Прикажи дугме за пуштање на левој страни.</string>
<string name="playAudio">Аудио</string>
<string name="defaultAudioFormatTitle">Подразумевани формат звука</string>
<string name="webMAudioDescription">WebM - слободни формат</string>
<string name="m4aAudioDescription">m4a - бољи квалитет</string>
<string name="downloadDialogTitle">Преузми</string>
<string-array name="downloadOptions">
<item>Видео</item>
<item>Аудио</item>
</string-array>
</resources>

View File

@@ -1,11 +1,12 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="android:actionBarStyle">@style/NewPipeActionbarTheme</item>
<item name="actionBarStyle">@style/NewPipeActionbarTheme</item>
<item name="android:colorPrimary">@color/primaryColorYoutube</item>
<item name="android:colorPrimaryDark">@color/primaryColorDarkYoutube</item>
<item name="colorAccent">@color/accentColorYoutube</item>
<item name="android:colorAccent">@color/accentColorYoutube</item>
</style>
<style name="NewPipeActionbarTheme" parent="Widget.AppCompat.Light.ActionBar.Solid" >
@@ -21,6 +22,8 @@
<item name="windowActionBarOverlay">true</item>
<item name="android:actionBarStyle">@style/NewPipePlayerActionBarTheme</item>
<item name="actionBarStyle">@style/NewPipePlayerActionBarTheme</item>
<item name="colorAccent">@color/primaryColorYoutube</item>
<item name="android:colorAccent">@color/primaryColorYoutube</item>
</style>
<style name="NewPipePlayerActionBarTheme" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse" >
@@ -29,4 +32,4 @@
<item name="android:background">@color/black_overlay</item>
<item name="background">@color/black_overlay</item>
</style>
</resources>
</resources>

View File

@@ -1,12 +0,0 @@
<resources>
<!-- Declare custom theme attributes that allow changing which styles are
used for button bars depending on the API level.
?android:attr/buttonBarStyle is new as of API 11 so this is
necessary to support previous API levels. -->
<declare-styleable name="ButtonBarContainerTheme">
<attr name="metaButtonBarStyle" format="reference" />
<attr name="metaButtonBarButtonStyle" format="reference" />
</declare-styleable>
</resources>

View File

@@ -2,5 +2,6 @@
<resources>
<color name="primaryColorYoutube">#dd0000</color>
<color name="primaryColorDarkYoutube">#bb0000</color>
<color name="accentColorYoutube">#000000</color>
<color name="black_overlay">#66000000</color>
</resources>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="text_search_title_size">14sp</dimen>
<dimen name="text_search_duration_size">11sp</dimen>
<dimen name="text_search_uploader_size">12sp</dimen>
<dimen name="text_search_uploadtime_size">12sp</dimen>
</resources>

View File

@@ -11,4 +11,17 @@
<item>144p</item>
</string-array>
<string name="defaultResolutionListItem">360p</string>
<string name="showPlayWidthKodiPreference">show_play_with_kodi_preference</string>
<string name="leftHandLayout">left_hand_layout</string>
<string name="defaultAudioFormatPreference">default_audio_format</string>
<string-array name="audioFormatDescriptionList">
<item>@string/webMAudioDescription</item>
<item>@string/m4aAudioDescription</item>
</string-array>
<string-array name="audioFormatList">
<item>webm</item>
<item>m4a</item>
</string-array>
<string name="defaultAudioFormat">m4a</string>
<string name="showNextVideo">show_next_video</string>
</resources>

View File

@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">Noting found</string>
<string name="nothingFound">Nothing found</string>
<string name="viewSufix">views</string>
<string name="uploadDatePrefix">Uploaded at: </string>
<string name="noPlayerFound">No StreamPlayer found. You may want to install one.</string>
@@ -28,4 +29,23 @@
<string name="autoPlayThroughIntentTitle">Autoplay through Intent</string>
<string name="autoPlayThroughIntentSummary">Automatically starts a video when it was called from another app.</string>
<string name="defaultResolutionPreferenceTitle">Default Resolution</string>
</resources>
<string name="playWithKodiTitle">Play with Kodi</string>
<string name="koreNotFound">Kore app not found. Kore is needed to play videos with Kodi media center.</string>
<string name="installeKore">Install Kore</string>
<string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string>
<string name="showPlayWithKodiTitle">Show \"Play with Kodi\" option</string>
<string name="showPlayWithKodiSummary">Displays an option to play a video via Kodi media center.</string>
<string name="leftPlayButtonTitle">Show play button on the left side.</string>
<string name="playAudio">Audio</string>
<string name="defaultAudioFormatTitle">Default audio format</string>
<string name="webMAudioDescription">WebM - free format</string>
<string name="m4aAudioDescription">m4a - better quality</string>
<string name="downloadDialogTitle">Download</string>
<string-array name="downloadOptions">
<item>Video</item>
<item>Audio</item>
</string-array>
<string name="nextVideoTitle">Next Video</string>
<string name="showNextVideoTitle">Show \"Next video\" item.</string>
<string name="urlNotSupportedText">Url not Supported.</string>
</resources>

View File

@@ -1,11 +1,11 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="android:actionBarStyle">@style/NewPipeActionbarTheme</item>
<item name="actionBarStyle">@style/NewPipeActionbarTheme</item>
<item name="colorPrimary">@color/primaryColorYoutube</item>
<item name="colorPrimaryDark">@color/primaryColorDarkYoutube</item>
<item name="colorAccent">@color/accentColorYoutube</item>
</style>
<style name="NewPipeActionbarTheme" parent="Widget.AppCompat.Light.ActionBar.Solid" >
@@ -21,6 +21,7 @@
<item name="windowActionBarOverlay">true</item>
<item name="android:actionBarStyle">@style/NewPipePlayerActionBarTheme</item>
<item name="actionBarStyle">@style/NewPipePlayerActionBarTheme</item>
<item name="colorAccent">@color/primaryColorYoutube</item>
</style>
<style name="NewPipePlayerActionBarTheme" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse" >
@@ -29,4 +30,4 @@
<item name="android:background">@color/black_overlay</item>
<item name="background">@color/black_overlay</item>
</style>
</resources>
</resources>

View File

@@ -28,4 +28,27 @@
android:entryValues="@array/resolutionList"
android:defaultValue="@string/defaultResolutionListItem"/>
<CheckBoxPreference
android:key="@string/showPlayWidthKodiPreference"
android:title="@string/showPlayWithKodiTitle"
android:summary="@string/showPlayWithKodiSummary"
android:defaultValue="false" />
<CheckBoxPreference
android:key="@string/leftHandLayout"
android:title="@string/leftPlayButtonTitle"
android:defaultValue="false" />
<ListPreference
android:key="@string/defaultAudioFormatPreference"
android:title="@string/defaultAudioFormatTitle"
android:entries="@array/audioFormatDescriptionList"
android:entryValues="@array/audioFormatList"
android:defaultValue="@string/defaultAudioFormat"/>
<CheckBoxPreference
android:key="@string/showNextVideo"
android:title="@string/showNextVideoTitle"
android:defaultValue="true" />
</PreferenceScreen>

188
assets/new_newpipe_icon.svg Normal file
View File

@@ -0,0 +1,188 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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"
width="500"
height="500"
viewBox="0 0 499.99998 499.99998"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="new_newpipe_icon.svg">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient4191">
<stop
style="stop-color:#000000;stop-opacity:0.42142856"
offset="0"
id="stop4193" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop4195" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4181">
<stop
style="stop-color:#000000;stop-opacity:0.18214285"
offset="0"
id="stop4183" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop4185" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4181"
id="linearGradient4187"
x1="33.701958"
y1="1049.5769"
x2="222.74532"
y2="802.2912"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,-1,0,1604.7196)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4191"
id="linearGradient4197"
x1="156.3342"
y1="806.3598"
x2="137.34325"
y2="1076.3597"
gradientUnits="userSpaceOnUse" />
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter4234">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4236" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4238" />
<feGaussianBlur
in="composite1"
stdDeviation="10"
result="blur"
id="feGaussianBlur4240" />
<feOffset
dx="10"
dy="10"
result="offset"
id="feOffset4242" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4244" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#909090"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="306.78283"
inkscape:cy="188.96397"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
units="px" />
<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>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-552.36209)">
<g
id="g4228"
style="filter:url(#filter4234)"
transform="matrix(0.91500077,0,0,0.91500077,34.121548,64.699974)">
<path
transform="scale(1,-1)"
inkscape:transform-center-y="-0.99541504"
inkscape:transform-center-x="-69.868733"
d="m 466.34766,-802.35761 -216.69307,124.67654 -216.319598,125.32344 0.373489,-249.99997 -0.37349,-250 216.319579,125.32345 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="1.0471975"
sodipodi:arg1="-9.6439996e-10"
sodipodi:r2="143.96407"
sodipodi:r1="288.67511"
sodipodi:cy="-802.3576"
sodipodi:cx="177.67255"
sodipodi:sides="3"
id="path4177"
style="opacity:0.997;fill:#ff0d0d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:type="star" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path4179"
d="m 466.3167,802.35759 -432.596061,0 -0.161527,-249.85824 z"
style="fill:url(#linearGradient4187);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path4189"
d="M 466.3432,802.35759 33.687658,802.35807 33.334206,1052.362 Z"
style="fill:url(#linearGradient4197);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
transform="scale(1,-1)"
inkscape:transform-center-y="-0.99541504"
inkscape:transform-center-x="-69.868733"
d="M 466.01266,-802.36206 249.31959,-677.68553 33,-552.36208 33.373489,-802.36205 33,-1052.362 249.31958,-927.0386 Z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="1.0471975"
sodipodi:arg1="-9.6439996e-10"
sodipodi:r2="143.96407"
sodipodi:r1="288.67511"
sodipodi:cy="-802.36206"
sodipodi:cx="177.33755"
sodipodi:sides="3"
id="path4177-3"
style="opacity:0.997;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:type="star" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

394
assets/new_pipe_icon_3.svg Normal file
View File

@@ -0,0 +1,394 @@
<?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_3.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.7234659"
inkscape:cx="82.753124"
inkscape:cy="90.951077"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient4924">
<stop
style="stop-color:#ffffff;stop-opacity:0.12857144"
offset="0"
id="stop4926" />
<stop
style="stop-color:#ffffff;stop-opacity:0"
offset="1"
id="stop4928" />
</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>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4924"
id="radialGradient4930"
cx="-17.308468"
cy="44.131577"
fx="-17.308468"
fy="44.131577"
r="88"
gradientTransform="matrix(0.00918061,2.1580507,-2.1734097,0.00924596,96.458612,37.749457)"
gradientUnits="userSpaceOnUse" />
<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>
</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 />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="g4191"
transform="matrix(1.0909091,0,0,1.0909091,-8.7272727,-8.6363651)">
<rect
ry="20.886885"
y="31"
x="8"
height="128"
width="176"
id="rect4138-6"
style="fill:#747474;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
ry="20.886885"
y="33"
x="8"
height="128"
width="176"
id="rect4138-9"
style="fill:#4d4d4d;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
ry="20.886885"
y="32"
x="8"
height="128"
width="176"
id="rect4138"
style="fill:#616161;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
style="filter:url(#filter4192)"
transform="matrix(0.57861531,0,0,0.57861531,-50.721139,-52.115781)"
id="g4141">
<circle
style="fill:#ff5252;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4144"
cx="255.30112"
cy="257.71143"
r="86.413193" />
<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 303.94425,257.77663 -40.45827,23.31512 -40.45827,23.31511 0.0377,-46.69544 0.0377,-46.69545 40.42062,23.38033 z" />
</g>
<rect
ry="21.213242"
y="31"
x="8"
height="130"
width="176"
id="rect4138-8"
style="fill:url(#radialGradient4930);fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 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

View File

@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'com.android.tools.build:gradle:1.3.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files