Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
2339f51
[#11930] Share as YouTube temporary playlist
tfga Feb 15, 2025
430b4eb
Translated using Weblate (Persian)
weblate Feb 15, 2025
b764ad3
Drop some assumptions on how PlayerService is started and reused
Stypox Feb 15, 2025
cfb6e11
Disable logs about view animations by default
Stypox Feb 16, 2025
5819546
Have PlayerService implement MediaBrowserServiceCompat
Stypox Feb 15, 2025
7d17468
Instantiate media session and connector in PlayerService
Stypox Feb 16, 2025
1e08cc8
Add MediaBrowserCommon with info item's and pages' IDs
Stypox Feb 16, 2025
9bb2c0b
Add getPlaylist(id) to RemotePlaylistManager
Stypox Feb 16, 2025
690b40d
Allow creating PlayQueue from ListInfo and index
Stypox Feb 16, 2025
5eabcb5
Add getThumbnailUrl() to PlaylistLocalItem interface
Stypox Feb 16, 2025
6cedd11
Add StreamHistoryEntry.toStreamInfoItem()
Stypox Feb 16, 2025
3fcac10
Add MediaBrowserPlaybackPreparer
Stypox Feb 16, 2025
4c88a19
Add MediaBrowserImpl
Stypox Feb 16, 2025
064e1d3
Use the media browser implementation in PlayerService
Stypox Feb 16, 2025
ec6612d
Call exoPlayer.prepare() on PlaybackPreparer.onPrepare()
Stypox Feb 16, 2025
dc62d21
Properly stop PlayerService
Stypox Feb 16, 2025
e5458bc
Properly handle item errors during media browser loading
Stypox Feb 16, 2025
1d98518
Fix loading remote playlists in media browser
Stypox Feb 16, 2025
1d12874
Merge pull request #12046 from TobiGr/weblate
Stypox Feb 16, 2025
6558794
Try to bind to PlayerService when MainActivity starts
Stypox Feb 18, 2025
126f4b0
Fix crash when closing video detail fragment
Stypox Feb 18, 2025
a7a7dc5
Handle player and player service separately
Stypox Feb 18, 2025
94d4c21
[#11930] @Test export_justUrls()
tfga Feb 18, 2025
c6b87cd
[#11930] Making CheckStyle happy
tfga Feb 18, 2025
acac50a
[#11930] Non-Youtube URLs should be ignored
tfga Feb 19, 2025
b1f995a
[#11930] Playlist with more than 50 items
tfga Feb 20, 2025
c9ec257
Ugly fix for broken text colors in dark mode (#12035)
Thompson3142 Feb 21, 2025
49b7194
Fix style and add comment about null player
Stypox Feb 24, 2025
24bb71a
[#11930] Making it more efficient: Reverse iteration + limit(50) + re…
tfga Feb 24, 2025
76a02d5
[#11930] Extracting to a separate file
tfga Feb 24, 2025
998d84d
[#11930] Converting to Kotlin
tfga Feb 24, 2025
3c7b026
[#11930] Updating javadoc
tfga Feb 25, 2025
0fd2d4f
[#11930] Removing Apache Commons Collections
tfga Feb 27, 2025
f0c8949
Fix stream notification grouping
Isira-Seneviratne Feb 27, 2025
ea20ca9
Merge pull request #12067 from Isira-Seneviratne/Fix-notification-gro…
Stypox Feb 28, 2025
d81244e
YT temp playlist URL: http => https
tfga Mar 10, 2025
1011039
Use display name instead of only the language
mileskrell Mar 11, 2025
c28478a
getYouTubeId(): Changing implementation to use YoutubeStreamLinkHandler
tfga Mar 11, 2025
f96b8f7
Comment: maximum length of 50 items
tfga Mar 11, 2025
8830e87
YouTube video IDs are 11 characters long
tfga Mar 11, 2025
587df09
YouTube video IDs are 11 characters long
tfga Mar 11, 2025
599d861
Making ktLint happy
tfga Mar 12, 2025
f3b3d5c
R.string.share_playlist_as_youtube_temporary_playlist
tfga Mar 12, 2025
eb05680
R.string.share_playlist_as_youtube_temporary_playlist: pt-BR
tfga Mar 12, 2025
098f60d
Don't add the title when sharing as YouTube temp playlist
tfga Mar 13, 2025
be097f2
Deleting the "explanatory text" bellow the title
tfga Mar 13, 2025
2ceb702
sharePlaylist(): converting javadoc from Markdown back to "classic ja…
tfga Mar 15, 2025
3dcfdaf
Merge pull request #12065 from tfga/YouTubeTemporaryPlaylist
Stypox Mar 15, 2025
3047704
Merge pull request #12089 from mileskrell/mileskrell/fix-audio-track-…
Stypox Mar 15, 2025
fb4a65a
Merge pull request #12043 from TeamNewPipe/hide-view-logs
TobiGr Mar 15, 2025
d321e57
Translated using Weblate (Czech)
weblate Mar 14, 2025
54bf7f0
BF-11894 : Fix the Duplicate menu options in ChannelFragment
har-123 Mar 8, 2025
48b2008
BF-11894 : Fix the menu disappearing on performing backGesture
har-123 Mar 12, 2025
f289bea
Fix sonar warning
HatakeKakashri Mar 16, 2025
c232193
Merge pull request #12083 from har-123/bugfix/11894_fix_duplicate_men…
TobiGr Mar 16, 2025
a0b76c3
Update NewPipe Extractor and add new proguard rules
TobiGr Mar 16, 2025
b378931
Merge pull request #12104 from TeamNewPipe/update-npe
Stypox Mar 21, 2025
196c277
Merge pull request #12044 from TeamNewPipe/android-auto
Stypox Mar 21, 2025
6486f2d
Merge branch 'dev' into Merge-dev-to-refactor
Isira-Seneviratne Apr 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@

## Rules for NewPipeExtractor
-keep class org.schabi.newpipe.extractor.timeago.patterns.** { *; }
## Rules for Rhino and Rhino Engine
-keep class org.mozilla.javascript.* { *; }
-keep class org.mozilla.javascript.** { *; }
-keep class org.mozilla.javascript.engine.** { *; }
-keep class org.mozilla.classfile.ClassFileWriter
-dontwarn org.mozilla.javascript.JavaToJSONConverters
-dontwarn org.mozilla.javascript.tools.**
-keep class javax.script.** { *; }
-dontwarn javax.script.**
-keep class jdk.dynalink.** { *; }
-dontwarn jdk.dynalink.**

## Rules for ExoPlayer
-keep class com.google.android.exoplayer2.** { *; }
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>

<activity
Expand Down Expand Up @@ -429,5 +432,10 @@
<meta-data
android:name="com.samsung.android.multidisplay.keep_process_alive"
android:value="true" />
<!-- Android Auto -->
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc" />
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
android:resource="@mipmap/ic_launcher" />
</application>
</manifest>
21 changes: 20 additions & 1 deletion app/src/main/java/org/schabi/newpipe/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
Expand Down Expand Up @@ -136,6 +137,19 @@ protected void onCreate(final Bundle savedInstanceState) {
ThemeHelper.setDayNightMode(this);
ThemeHelper.setTheme(this, ServiceHelper.getSelectedServiceId(this));

// Fixes text color turning black in dark/black mode:
// https://github.com/TeamNewPipe/NewPipe/issues/12016
// For further reference see: https://issuetracker.google.com/issues/37124582
if (DeviceUtils.supportsWebView()) {
try {
new WebView(this);
} catch (final Throwable e) {
if (DEBUG) {
Log.e(TAG, "Failed to create WebView", e);
}
}
}

assureCorrectAppLanguage(this);
super.onCreate(savedInstanceState);

Expand Down Expand Up @@ -826,7 +840,8 @@ private void openMiniPlayerUponPlayerStarted() {
@Override
public void onReceive(final Context context, final Intent intent) {
if (Objects.equals(intent.getAction(),
VideoDetailFragment.ACTION_PLAYER_STARTED)) {
VideoDetailFragment.ACTION_PLAYER_STARTED)
&& PlayerHolder.getInstance().isPlayerOpen()) {
openMiniPlayerIfMissing();
// At this point the player is added 100%, we can unregister. Other actions
// are useless since the fragment will not be removed after that.
Expand All @@ -838,6 +853,10 @@ public void onReceive(final Context context, final Intent intent) {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(VideoDetailFragment.ACTION_PLAYER_STARTED);
registerReceiver(broadcastReceiver, intentFilter);

// If the PlayerHolder is not bound yet, but the service is running, try to bind to it.
// Once the connection is established, the ACTION_PLAYER_STARTED will be sent.
PlayerHolder.getInstance().tryBindIfNeeded(this);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package org.schabi.newpipe.database.history.model
import androidx.room.ColumnInfo
import androidx.room.Embedded
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.util.image.ImageStrategy
import java.time.OffsetDateTime

data class StreamHistoryEntry(
Expand All @@ -27,4 +29,17 @@ data class StreamHistoryEntry(
return this.streamEntity.uid == other.streamEntity.uid && streamId == other.streamId &&
accessDate.isEqual(other.accessDate)
}

fun toStreamInfoItem(): StreamInfoItem =
StreamInfoItem(
streamEntity.serviceId,
streamEntity.url,
streamEntity.title,
streamEntity.streamType,
).apply {
duration = streamEntity.duration
uploaderName = streamEntity.uploader
uploaderUrl = streamEntity.uploaderUrl
thumbnails = ImageStrategy.dbUrlToImageList(streamEntity.thumbnailUrl)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.schabi.newpipe.database.playlist;

import androidx.annotation.Nullable;

import org.schabi.newpipe.database.LocalItem;

public interface PlaylistLocalItem extends LocalItem {
Expand All @@ -10,4 +12,7 @@ public interface PlaylistLocalItem extends LocalItem {
long getUid();

void setDisplayIndex(long displayIndex);

@Nullable
String getThumbnailUrl();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_THUMBNAIL_STREAM_ID;
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_THUMBNAIL_URL;

import androidx.annotation.Nullable;

public class PlaylistMetadataEntry implements PlaylistLocalItem {
public static final String PLAYLIST_STREAM_COUNT = "streamCount";

Expand Down Expand Up @@ -71,4 +73,10 @@ public long getUid() {
public void setDisplayIndex(final long displayIndex) {
this.displayIndex = displayIndex;
}

@Nullable
@Override
public String getThumbnailUrl() {
return thumbnailUrl;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public interface PlaylistRemoteDAO extends BasicDAO<PlaylistRemoteEntity> {

@Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE "
+ REMOTE_PLAYLIST_ID + " = :playlistId")
Flowable<List<PlaylistRemoteEntity>> getPlaylist(long playlistId);
Flowable<PlaylistRemoteEntity> getPlaylist(long playlistId);

@Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE "
+ REMOTE_PLAYLIST_URL + " = :url AND " + REMOTE_PLAYLIST_SERVICE_ID + " = :serviceId")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.text.TextUtils;

import androidx.annotation.Nullable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
Expand Down Expand Up @@ -134,6 +135,8 @@ public void setName(final String name) {
this.name = name;
}

@Nullable
@Override
public String getThumbnailUrl() {
return thumbnailUrl;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@
import org.schabi.newpipe.player.PlayerService;
import org.schabi.newpipe.player.PlayerType;
import org.schabi.newpipe.player.event.OnKeyDownListener;
import org.schabi.newpipe.player.event.PlayerHolderLifecycleEventListener;
import org.schabi.newpipe.player.event.PlayerServiceEventListener;
import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.helper.PlayerHolder;
import org.schabi.newpipe.player.playqueue.PlayQueue;
Expand Down Expand Up @@ -137,8 +136,7 @@
public final class VideoDetailFragment
extends BaseStateFragment<StreamInfo>
implements BackPressable,
PlayerServiceEventListener,
PlayerHolderLifecycleEventListener,
PlayerServiceExtendedEventListener,
OnKeyDownListener {
public static final String KEY_SWITCHING_PLAYERS = "switching_players";

Expand Down Expand Up @@ -236,10 +234,14 @@ public final class VideoDetailFragment
// Service management
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onServiceConnected(final PlayerService connectedPlayerService,
final boolean playAfterConnect) {
player = connectedPlayerService.getPlayer();
public void onServiceConnected(@NonNull final PlayerService connectedPlayerService) {
playerService = connectedPlayerService;
}

@Override
public void onPlayerConnected(@NonNull final Player connectedPlayer,
final boolean playAfterConnect) {
player = connectedPlayer;

// It will do nothing if the player is not in fullscreen mode
hideSystemUiIfNeeded();
Expand Down Expand Up @@ -271,11 +273,18 @@ && isAutoplayEnabled()
updateOverlayPlayQueueButtonVisibility();
}

@Override
public void onPlayerDisconnected() {
player = null;
// the binding could be null at this point, if the app is finishing
if (binding != null) {
restoreDefaultBrightness();
}
}

@Override
public void onServiceDisconnected() {
playerService = null;
player = null;
restoreDefaultBrightness();
}


Expand Down Expand Up @@ -394,7 +403,7 @@ public void onDestroy() {
if (activity.isFinishing() && isPlayerAvailable() && player.videoPlayerSelected()) {
playerHolder.stopService();
} else {
playerHolder.unsetListeners();
playerHolder.setListener(null);
}

PreferenceManager.getDefaultSharedPreferences(activity)
Expand Down Expand Up @@ -659,10 +668,10 @@ protected void initListeners() {
});

setupBottomPlayer();
if (playerHolder.isNotBoundYet()) {
if (!playerHolder.isBound()) {
setHeightThumbnail();
} else {
playerHolder.startService(false, this, this);
playerHolder.startService(false, this);
}
}

Expand Down Expand Up @@ -1053,7 +1062,7 @@ private void openPopupPlayer(final boolean append) {

// See UI changes while remote playQueue changes
if (!isPlayerAvailable()) {
playerHolder.startService(false, this, this);
playerHolder.startService(false, this);
} else {
// FIXME Workaround #7427
player.setRecovery();
Expand Down Expand Up @@ -1116,7 +1125,7 @@ public void openVideoPlayerAutoFullscreen() {
private void openNormalBackgroundPlayer(final boolean append) {
// See UI changes while remote playQueue changes
if (!isPlayerAvailable()) {
playerHolder.startService(false, this, this);
playerHolder.startService(false, this);
}

final PlayQueue queue = setupPlayQueueForIntent(append);
Expand All @@ -1130,7 +1139,7 @@ private void openNormalBackgroundPlayer(final boolean append) {

private void openMainPlayer() {
if (!isPlayerServiceAvailable()) {
playerHolder.startService(autoPlayEnabled, this, this);
playerHolder.startService(autoPlayEnabled, this);
return;
}
if (currentInfo == null) {
Expand Down Expand Up @@ -1385,11 +1394,9 @@ public void onReceive(final Context context, final Intent intent) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
// Rebound to the service if it was closed via notification or mini player
if (playerHolder.isNotBoundYet()) {
if (!playerHolder.isBound()) {
playerHolder.startService(
false,
VideoDetailFragment.this,
VideoDetailFragment.this);
false, VideoDetailFragment.this);
}
break;
}
Expand Down Expand Up @@ -1838,13 +1845,16 @@ public void onPlayerError(final PlaybackException error, final boolean isCatchab

@Override
public void onServiceStopped() {
setOverlayPlayPauseImage(false);
if (currentInfo != null) {
updateOverlayData(currentInfo.getName(),
currentInfo.getUploaderName(),
currentInfo.getThumbnails());
// the binding could be null at this point, if the app is finishing
if (binding != null) {
setOverlayPlayPauseImage(false);
if (currentInfo != null) {
updateOverlayData(currentInfo.getName(),
currentInfo.getUploaderName(),
currentInfo.getThumbnails());
}
updateOverlayPlayQueueButtonVisibility();
}
updateOverlayPlayQueueButtonVisibility();
}

@Override
Expand Down
Loading
Loading