commit
3e83bb0d95
|
@ -84,6 +84,7 @@ NewPipe は複数のサービスに対応しています。[ドキュメント](
|
|||
* SoundCloud \[ベータ\]
|
||||
* media.ccc.de \[ベータ\]
|
||||
* PeerTube インスタンス \[ベータ\]
|
||||
* Bandcamp \[ベータ\]
|
||||
|
||||
<!-- Hidden span to keep old links compatible. -->
|
||||
<span id="updates"></span>
|
||||
|
|
|
@ -79,6 +79,7 @@ NewPipe는 여러가지 서비스를 지원합니다. 우리의 [문서](https:/
|
|||
* SoundCloud \[beta\]
|
||||
* media.ccc.de \[beta\]
|
||||
* PeerTube instances \[beta\]
|
||||
* Bandcamp \[beta\]
|
||||
|
||||
## Updates
|
||||
NewPipe 코드의 변경이 있을 때(기능 추가 또는 버그 수정으로 인해), 결국 릴리즈가 발생할 것입니다. 이것들의 형식은 x.xx.x 입니다.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
@ -1546,10 +1547,21 @@ public final class VideoDetailFragment
|
|||
updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnailUrl());
|
||||
}
|
||||
|
||||
if (!info.getErrors().isEmpty()) {
|
||||
// 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
|
||||
|| info.getStreamType() == StreamType.AUDIO_LIVE_STREAM ? View.GONE : View.VISIBLE);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 |
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue