Merge pull request #3741 from fynngodau/bandcamp

Bandcamp support
This commit is contained in:
Tobi 2021-03-14 20:00:40 +01:00 committed by GitHub
commit 3e83bb0d95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 185 additions and 9 deletions

View File

@ -84,6 +84,7 @@ NewPipe は複数のサービスに対応しています。[ドキュメント](
* SoundCloud \[ベータ\]
* media.ccc.de \[ベータ\]
* PeerTube インスタンス \[ベータ\]
* Bandcamp \[ベータ\]
<!-- Hidden span to keep old links compatible. -->
<span id="updates"></span>

View File

@ -79,6 +79,7 @@ NewPipe는 여러가지 서비스를 지원합니다. 우리의 [문서](https:/
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
* PeerTube instances \[beta\]
* Bandcamp \[beta\]
## Updates
NewPipe 코드의 변경이 있을 때(기능 추가 또는 버그 수정으로 인해), 결국 릴리즈가 발생할 것입니다. 이것들의 형식은 x.xx.x 입니다.

View File

@ -81,6 +81,7 @@ NewPipe supports multiple services. Our [docs](https://teamnewpipe.github.io/doc
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
* PeerTube instances \[beta\]
* Bandcamp \[beta\]
<!-- Hidden span to keep old links compatible. -->
<span id="updates"></span>

View File

@ -79,6 +79,7 @@ O NewPipe suporta vários serviços. Nosso [documentação](https://teamnewpipe.
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
* PeerTube instances \[beta\]
* Bandcamp \[beta\]
## Atualizações
Quando uma alteração no código NewPipe (devido à adição de recursos ou fixação de bugs), eventualmente ocorrerá uma versão. Estes estão no formato x.xx.x . A fim de obter esta nova versão, você pode:

View File

@ -81,6 +81,7 @@ NewPipe suportă servicii multiple. [Documentele](https://teamnewpipe.github.io/
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
* Instanţe PeerTube \[beta\]
* Bandcamp \[beta\]
<!-- Hidden span to keep old links compatible. -->
<span id="updates"></span>

View File

@ -79,6 +79,7 @@ NewPipe wuxuu taageeraa adeegyo badan. [warqadan](https://teamnewpipe.github.io/
* SoundCloud \[tijaabo\]
* media.ccc.de \[tijaabo\]
* PeerTube instances \[tijaabo\]
* Bandcamp \[tijaabo\]
## Kushubida iyo cusboonaysiinta
Marka koodhka NewPipe isbadal ku dhaco (wax cusub oo lagusoo kordhiyay ama cilad bixin), ugu dambayn waxaa lasii daayaa mid cusub (Siidayn). Siidaynta qaabkeedu waa x.xx.x . Si aad midka cusub u hesho, waxaad samayn kartaa:

View File

@ -180,7 +180,7 @@ dependencies {
// NewPipe dependencies
// You can use a local version by uncommenting a few lines in settings.gradle
implementation "com.github.TeamNewPipe:NewPipeExtractor:7e6f464407fc1a2c8fb0886d294093526a6ef0f1"
implementation 'com.github.TeamNewPipe:NewPipeExtractor:def745b801b2ef35c1a0fee1be950331ca6a0cd2'
implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751"
implementation "org.jsoup:jsoup:1.13.1"

View File

@ -317,6 +317,22 @@
<data android:pathPrefix="/accounts/" />
<data android:pathPrefix="/video-channels/" />
</intent-filter>
<!-- Bandcamp filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:host="bandcamp.com"/>
<data android:host="*.bandcamp.com"/>
<data android:pathPrefix="/"/>
</intent-filter>
</activity>
<service
android:name=".RouterActivity$FetcherService"

View File

@ -62,6 +62,7 @@ import org.schabi.newpipe.error.ReCaptchaActivity;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.Stream;
@ -1547,8 +1548,19 @@ public final class VideoDetailFragment
}
if (!info.getErrors().isEmpty()) {
showSnackBarError(new ErrorInfo(info.getErrors(),
UserAction.REQUESTED_STREAM, info.getUrl(), info));
// Bandcamp fan pages are not yet supported and thus a ContentNotAvailableException is
// thrown. This is not an error and thus should not be shown to the user.
for (final Throwable throwable : info.getErrors()) {
if (throwable instanceof ContentNotSupportedException
&& "Fan pages are not supported".equals(throwable.getMessage())) {
info.getErrors().remove(throwable);
}
}
if (!info.getErrors().isEmpty()) {
showSnackBarError(new ErrorInfo(info.getErrors(),
UserAction.REQUESTED_STREAM, info.getUrl(), info));
}
}
binding.detailControlsDownload.setVisibility(info.getStreamType() == StreamType.LIVE_STREAM

View File

@ -1129,6 +1129,12 @@ public final class Player implements
// Close it because when changing orientation from portrait
// (in fullscreen mode) the size of queue layout can be larger than the screen size
closeItemsList();
// When the orientation changed, the screen height might be smaller.
// If the end screen thumbnail is not re-scaled,
// it can be larger than the current screen height
// and thus enlarging the whole player.
// This causes the seekbar to be ouf the visible area.
updateEndScreenThumbnail();
break;
case Intent.ACTION_SCREEN_ON:
// Interrupt playback only when screen turns on
@ -1187,6 +1193,78 @@ public final class Player implements
.loadImage(url, ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS, this);
}
/**
* Scale the player audio / end screen thumbnail down if necessary.
* <p>
* This is necessary when the thumbnail's height is larger than the device's height
* and thus is enlarging the player's height
* causing the bottom playback controls to be out of the visible screen.
* </p>
*/
public void updateEndScreenThumbnail() {
if (currentThumbnail == null) {
return;
}
final float endScreenHeight = calculateMaxEndScreenThumbnailHeight();
final Bitmap endScreenBitmap = Bitmap.createScaledBitmap(
currentThumbnail,
(int) (currentThumbnail.getWidth()
/ (currentThumbnail.getHeight() / endScreenHeight)),
(int) endScreenHeight,
true);
if (DEBUG) {
Log.d(TAG, "Thumbnail - updateEndScreenThumbnail() called with: "
+ "currentThumbnail = [" + currentThumbnail + "], "
+ currentThumbnail.getWidth() + "x" + currentThumbnail.getHeight()
+ ", scaled end screen height = " + endScreenHeight
+ ", scaled end screen width = " + endScreenBitmap.getWidth());
}
binding.endScreen.setImageBitmap(endScreenBitmap);
}
/**
* Calculate the maximum allowed height for the {@link R.id.endScreen}
* to prevent it from enlarging the player.
* <p>
* The calculating follows these rules:
* <ul>
* <li>
* Show at least stream title and content creator on TVs and tablets
* when in landscape (always the case for TVs) and not in fullscreen mode.
* This requires to have at least <code>85dp</code> free space for {@link R.id.detail_root}
* and additional space for the stream title text size
* ({@link R.id.detail_title_root_layout}).
* The text size is <code>15sp</code> on tablets and <code>16sp</code> on TVs,
* see {@link R.id.titleTextView}.
* </li>
* <li>
* Otherwise, the max thumbnail height is the screen height.
* </li>
* </ul>
*
* @return the maximum height for the end screen thumbnail
*/
private float calculateMaxEndScreenThumbnailHeight() {
// ensure that screenHeight is initialized and thus not 0
updateScreenSize();
if (DeviceUtils.isTv(context) && !isFullscreen) {
final int videoInfoHeight =
DeviceUtils.dpToPx(85, context) + DeviceUtils.spToPx(16, context);
return Math.min(currentThumbnail.getHeight(), screenHeight - videoInfoHeight);
} else if (DeviceUtils.isTablet(context) && service.isLandscape() && !isFullscreen) {
final int videoInfoHeight =
DeviceUtils.dpToPx(85, context) + DeviceUtils.spToPx(15, context);
return Math.min(currentThumbnail.getHeight(), screenHeight - videoInfoHeight);
} else { // fullscreen player: max height is the device height
return Math.min(currentThumbnail.getHeight(), screenHeight);
}
}
@Override
public void onLoadingStarted(final String imageUri, final View view) {
if (DEBUG) {
@ -1207,23 +1285,29 @@ public final class Player implements
@Override
public void onLoadingComplete(final String imageUri, final View view,
final Bitmap loadedImage) {
final float width = Math.min(
// scale down the notification thumbnail for performance
final float notificationThumbnailWidth = Math.min(
context.getResources().getDimension(R.dimen.player_notification_thumbnail_width),
loadedImage.getWidth());
currentThumbnail = Bitmap.createScaledBitmap(
loadedImage,
(int) notificationThumbnailWidth,
(int) (loadedImage.getHeight()
/ (loadedImage.getWidth() / notificationThumbnailWidth)),
true);
if (DEBUG) {
Log.d(TAG, "Thumbnail - onLoadingComplete() called with: "
+ "imageUri = [" + imageUri + "], view = [" + view + "], "
+ "loadedImage = [" + loadedImage + "], "
+ loadedImage.getWidth() + "x" + loadedImage.getHeight()
+ ", scaled width = " + width);
+ ", scaled notification width = " + notificationThumbnailWidth);
}
currentThumbnail = Bitmap.createScaledBitmap(loadedImage,
(int) width,
(int) (loadedImage.getHeight() / (loadedImage.getWidth() / width)), true);
binding.endScreen.setImageBitmap(loadedImage);
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
// there is a new thumbnail, thus the end screen thumbnail needs to be changed, too.
updateEndScreenThumbnail();
}
@Override

View File

@ -6,8 +6,10 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.BatteryManager;
import android.os.Build;
import android.util.TypedValue;
import android.view.KeyEvent;
import androidx.annotation.Dimension;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
@ -70,4 +72,20 @@ public final class DeviceUtils {
return false;
}
}
public static int dpToPx(@Dimension(unit = Dimension.DP) final int dp,
@NonNull final Context context) {
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
context.getResources().getDisplayMetrics());
}
public static int spToPx(@Dimension(unit = Dimension.SP) final int sp,
@NonNull final Context context) {
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
sp,
context.getResources().getDisplayMetrics());
}
}

View File

@ -48,6 +48,10 @@ public final class KioskTranslator {
return c.getString(R.string.recent);
case "live":
return c.getString(R.string.duration_live);
case "Featured":
return c.getString(R.string.featured);
case "Radio":
return c.getString(R.string.radio);
default:
return kioskId;
}
@ -69,6 +73,10 @@ public final class KioskTranslator {
return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_thumb_up);
case "live":
return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_live_tv);
case "Featured":
return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_stars);
case "Radio":
return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_radio);
default:
return 0;
}

View File

@ -38,6 +38,8 @@ public final class ServiceHelper {
return R.drawable.place_holder_gadse;
case 3:
return R.drawable.place_holder_peertube;
case 4:
return R.drawable.place_holder_bandcamp;
default:
return R.drawable.place_holder_circle;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -44,4 +44,13 @@
<color name="dark_media_ccc_accent_color">#FFFFFF</color>
<color name="dark_media_ccc_statusbar_color">#9e9e9e</color>
<!-- Bandcamp -->
<color name="light_bandcamp_primary_color">#17a0c4</color>
<color name="light_bandcamp_accent_color">#000000</color>
<color name="light_bandcamp_statusbar_color">#17a0c4</color>
<color name="dark_bandcamp_primary_color">#17a0c4</color>
<color name="dark_bandcamp_accent_color">#FFFFFF</color>
<color name="dark_bandcamp_statusbar_color">#17a0c4</color>
</resources>

View File

@ -707,4 +707,6 @@
<string name="private_content">This content is private, so it cannot be streamed or downloaded by NewPipe.</string>
<string name="youtube_music_premium_content">This video is available only to YouTube Music Premium members, so it cannot be streamed or downloaded by NewPipe.</string>
<string name="paid_content">This content is only available to users who have paid, so it cannot be streamed or downloaded by NewPipe.</string>
<string name="featured">Featured</string>
<string name="radio">Radio</string>
</resources>

View File

@ -70,4 +70,23 @@
<item name="colorAccent">@color/dark_media_ccc_accent_color</item>
</style>
<!-- Bandcamp -->
<style name="LightTheme.Bandcamp" parent="LightTheme">
<item name="colorPrimary">@color/light_bandcamp_primary_color</item>
<item name="colorPrimaryDark">@color/light_bandcamp_statusbar_color</item>
<item name="colorAccent">@color/light_bandcamp_accent_color</item>
</style>
<style name="DarkTheme.Bandcamp" parent="DarkTheme">
<item name="colorPrimary">@color/dark_bandcamp_primary_color</item>
<item name="colorPrimaryDark">@color/dark_bandcamp_statusbar_color</item>
<item name="colorAccent">@color/dark_bandcamp_accent_color</item>
</style>
<style name="BlackTheme.Bandcamp" parent="BlackTheme">
<item name="colorPrimary">@color/dark_bandcamp_primary_color</item>
<item name="colorPrimaryDark">@color/dark_bandcamp_statusbar_color</item>
<item name="colorAccent">@color/dark_bandcamp_accent_color</item>
</style>
</resources>