NewPipe 0.24.0 released: Farewell, KitKat :'(

post image

Hey peeps. We’re dropping support for Android KitKat, and bumping the minimum supported version to Lollipop, as was announced on the repo months ago.

It’s quite sad that we had to do this, as we fondly remember KitKat as being one of the best Android releases, but it was either this, or continuing to use an unpatched library (one which is used to access the Internet, as well!), exposing our users to untold security risks.

KitKat users can continue to use (at their own risk) the previous version (v0.23.3) for now, at least until the service they use implements breaking changes and stops working with that version. We published a separate blog post about this. TL;DR: If you have the knowledge and are interested in maintaining NewPipe Legacy, you’re most welcome to get in touch with the team. We’ve done our best to add some critical features (such as DASH support and new video notifications) before going ahead with dropping KitKat support. We hope you appreciate the effort.

Anyway, on with the new! This version contains a bunch of changes under the hood, but the biggest one is that the massive player code underwent a major refactor to improve readability and reduce maintenance overhead. Also, there is a new option to hide future videos from the feed. Thumbnails also saw some visual improvements. And finally, the NewPipe ReadMe was rewritten, for those who are into such arcane things.

This post also contains the changes from the previous two hotfixes.


  • @notaLonelyDay added the option to download videos directly through the long-press menu in lists, a nice quality-of-life addition which saves the trouble of waiting for the video details page to load.

  • @carmebar answered the prayers of several irritated souls by adding an option to hide future videos (a.k.a. premieres) from the feed. We even enabled this by default for your express convenience.

  • @litetex took on the unenviable task of finding and removing all the compatibility code that was needed to support Android KitKat. @Fs00 cheerfully pointed out even more places where old code could be dropped or replaced. @TacoTheDank chipped in to keep the code up to date.

    • With this, the minimum supported Android version is now Lollipop. Goodbye, KitKat, you will forever stay in our hearts! On a more positive note, this change has the side effect of unlocking several benefits and removing limitations/workarounds that were necessary to support an Android version that is (as of writing) 9 years old.

    • Related to this, and the actual driving force behind this change: @TacoTheDank updated the OkHttp library, which NewPipe uses to access the Internet, from 3.12.13 to 4.10.0. The 3.x branch has been deprecated since the beginning of the year, and since OkHttp is a critical library used to make HTTP requests to the wild and dangerous Internet, moving to the currently supported 4.x branch was imperative. However, support for KitKat was dropped by OkHttp in the move from the 3.x branch to 4.x. So here we are.

  • @carmebar also added a Share option to local playlists. Since they don’t have a URL (as they are stored purely on your device), this was done by sharing a list of all the video URLs in the playlist instead.


  • Some people reported that the app showed auto-translated English titles for some YouTube videos, instead of the original language. @FireMasterK fixed this. Now the original title is shown.

  • The fast feed refresh option was returning thumbnails with black bars at the top and bottom. @Stypox fixed this, at the cost of slightly lower thumbnail resolution.

  • @OxygenCobalt improved the 1:1 toggle for notification thumbnails. Now it crops the image into a square instead of stretching it to fill, which made it look strange on Android 11 and above.

  • @Stypox added support for all aspect ratios to list thumbnails, so that if they’re something other than 16:9, they are scaled to fit instead of getting cropped. The square thumbnails on SoundCloud and Bandcamp look better as a result. Also, playlist thumbnails had half their area hidden behind a black bar, which was also fixed.

  • @krlvm improved the placeholder images for thumbnails and avatars, helped along by @Stypox. Now they are shown immediately, instead of waiting for an arbitrary timeout period when there is a network error or the connection is poor. Moreover, the low-resolution placeholder images were replaced with vector graphics, which look much better on high-resolution screens. Finally, the placeholders were adapted to look better with the light theme.

  • @litetex removed the “beta” tag from all services because, as was rightly pointed out, NewPipe is an unofficial 3rd-party app. This means that technically all the services we support are permanently in beta, as they could stop working at any time due to service-side changes, which are not under our control.

  • @Stypox took on the daunting task of refactoring the massive player code of NewPipe – variously termed as “a hot pile of garbage” and “a spaghetti monster of doom”, with developer sentiments oscillating between “I would rather shoot myself in the foot than deal with this” and “AAAAAHHHHH” – by breaking it up into smaller, more maintainable and usable parts, which will make future development much easier. It led to an improvement (listed below) and also some bug fixes (including a major one), which are mentioned in the next section:

    • No more does the background/audio player keep the main player and popup player views pointlessly loaded in RAM. Only the currently used player view is kept in memory.
  • @Isira-Seneviratne made tag sorting case-insensitive, making content tags easier to view and use.


  • Regarding the hotfix version 0.23.2 – @Theta-Dev, an external contributor(!), fixed the extraction of the complex nsig functions used by YouTube, as their format was changed.
    • Remember when we said previously that the throttling prevention code was made more resilient to such changes by YouTube? Turns out it wasn’t doing its job properly, so @AudricV fixed that.
    • @AudricV also updated the versions of the YouTube clients NewPipe uses, and improved the extraction of the API key of the desktop website client in particular. They also added more parameters to the HTTP requests of some of these clients, which fixes the issue of replacement of video and audio streams by a silent video that just says “The following content is not available on this app. Watch this content on the latest version of YouTube”.
  • For hotfix version 0.23.3 – @Theta-Dev found that a newer version of a library we use calls a Java class not available on Android, which caused infinite loading of videos. The library was downgraded.
    • @litetex fixed throttling on some videos by checking if the JavaScript code we extract from YouTube is valid code, and falling back to our regex if not. That regex also happened to be missing a }.
  • @Theta-Dev later figured out that Android uses a different regular expression (or regex) parser than standard Java, and used the magical character \ to make our anti-throttling device (patent definitely pending) work properly.

  • After all this messing around with the same problem over multiple releases, @Theta-Dev was fed up, and consequently added a full-fledged JavaScript parser to the Extractor. This replaces the custom implementation present before, which tended to break every time YouTube decided to change the format of their nsig throttling decryption function. What this hopefully translates to is less frequent need for hotfixes in the future.

  • @litetex also fixed the extraction of some YouTube playlists for users in EU by allowing tracking through a consent. We would love to provide this functionality without bending to YouTube’s wishes, but sadly, it is what it is. This change is only available in the Extractor for now.

  • @AudricV fixed that annoying intermittent “Could not get like count” error, which caused an error snackbar to appear on a bunch of videos randomly. It turned out to be a new data model being A/B tested by YouTube, which changed how the like count was being accessed.

  • A (different) new data model being A/B tested also led to the Trending kiosk sometimes not showing any videos (which also affected Piped and was fixed, for those of you who use it). @AudricV added support for that too. (Incidentally, the new model allows us to better separate the regular “Trending”, “Recently Trending”, and the “Shorts” sections. We still extract only the first of these, but it helps to have them separated in the code for future changes.)

  • Now that we have a proper JS parser as mentioned above, we don’t need the throttling decryption function regex. The parser will never fail, theoretically speaking. But we’re still keeping it around as a fallback, because precaution. @AudricV fixed the regex to match updates in YouTube’s provided decryption function.

  • @Stypox noticed that the wrong placeholder image was being used for channel avatars in some places, which is now fixed.

  • The player refactor mentioned in the previous section solved a longstanding bug faced by Android 12 users, where the player sometimes only filled a quarter of the display when in full screen, leaving the rest empty.

  • It also fixed an issue where NewPipe was reported to be displaying over other apps even if only the background player (which is just a notification) was being used.

  • Further refactoring fixed the problem of a newer video playing, but the player notification continuing to show the thumbnail from the previous one.

  • Also, updating the notification metadata was left to ExoPlayer, instead of letting the app issue custom metadata updates, which solved the issue of the wrong duration or current position being shown sometimes.


  • @opusforlife2 overhauled the NewPipe ReadMe to improve clarity, as well as reflect the current status of the project.

  • @chr56 noticed that there were two translation files for Chinese Simplified, which caused issues with maintenance, and some missing or inconsistent translations. One of the files has been removed, restoring order to the world, and improving compatibility with old Android versions, to boot. It required some careful fiddling with Weblate to avoid breaking stuff, but @Stypox got the job done, no sweat.

Nerd Talk

  • dependabot updates in NewPipeExtractor:
    • Bump spotbugs-annotations from 4.7.0 to 4.7.1
    • Bump jsoup from 1.15.1 to 1.15.3 (which contains a fix for a vulnerability)
    • Bump junit-bom from 5.8.2 to 5.9.0
    • Bump gson from 2.9.0 to 2.9.1
  • @mhmdanas ensured that the GitHub CI has only the absolute minimum required permissions when running workflows, by manually specifying them. Further, @Stypox removed its write permissions to further tighten security.

  • Hurricane @Isira-Seneviratne strikes again! They further improved the Extractor by introducing modern code and cleaning up the old:
    • Used Objects.requireNonNull()
    • Used Collections methods
    • Used String.join() and Collectors.joining()
    • Made improvements to methods using toArray()
    • Removed usage of the EMPTY_STRING utility function and replaced it with actual empty strings
  • @AudricV removed an old and deprecated version of the throttling decryption code, replaced since 0.22.0 by a better version.

  • @litetex also added a check to see if our throttling parameter decryption function, needed for some YouTube content, is valid JavaScript code, letting it fallback to a regular expression (RegEx) version if not.

  • Moreover, @litetex fixed all the currently failing Extractor tests, and the corresponding code.

  • @TacoTheDank updated the Extractor’s Gradle version to 7.5.1.

  • On the front end, @Isira-Seneviratne made too many improvements to list. So here is a list… of some of them:
    • Refactoring several files, simplifying and replacing old, deprecated code with better or modern methods, as well as removing unused code.
    • More use of the Java 8 Stream API.
    • Some use of Java 9 methods as well!
    • Use of a compatibility class to fix a Lollipop UI bug.
    • Some more Kotlin-isation.
    • Beating @TacoTheDank to the punch, AndroidX Lifecycle was updated from version 2.3.1 to 2.5.0.
    • Revealing it to be a 2-hit combo, AppCompat was updated as well, from version 1.3.1 to 1.4.2.
    • Use of better display metrics APIs on Android 11 and above.
  • @Stypox noticed that the CI wasn’t running for some release candidate PRs. Turns out the accepted format of release branch names was too narrow. This has been mitigated.

  • @TacoTheDank found some cruft in the ProGuard file and cleaned it up. He got +5 cleanliness points as a reward for this side quest.

  • @TacoTheDank updated ExoPlayer from 2.17.1 to 2.18.1, fixing deprecations along the way. Also, they specified the ExoPlayer libraries we actually use, instead of letting the entire ExoPlayer library bundle be added to the project and cause bloat.

  • @litetex modified Checkstyle to enforce having the assignment operator (=) on the same line instead of a new one, and changed the code accordingly, also cleaning up some unused code along the way.

  • @TacoTheDank, the friendly neighbourhood library guy, passed by on the way to the pizzeria:
    • Checkstyle 10.0 -> 10.3.1
    • AssertJ 3.22.0 -> 3.23.1
    • desugar_jdk_libs 1.1.5 -> 1.1.6
    • Ktlint 0.44.0 -> 0.45.2
    • AndroidX Constraintlayout 2.1.3 -> 2.1.4
    • AndroidX Core 1.6.0 -> 1.8.0
    • AndroidX Media 1.5.0 -> 1.6.0
    • jsoup 1.14.3 -> 1.15.2
    • PrettyTime 5.0.2 -> 5.0.3
    • Android Gradle Plugin 7.2.0 -> 7.2.2
    • AndroidX Fragment 1.3.6 -> 1.4.1
    • Google Material 1.5.0 -> 1.6.1
    • AndroidX Room 2.4.2 -> 2.4.3
    • Gradle 7.4.2 -> 7.5.1, and to a smaller variant of the library
  • @Stypox deduplicated the SQL queries used to access the feed database and fetch streams from it.

  • @TacoTheDank made a custom fork of the No Nonsense File Picker that NewPipe uses for devices that don’t have SAF or users that choose to opt out of it. This custom fork let us disable Jetifier.

  • @Isira-Seneviratne changed the PeertubeInstanceListFragment, SuggestionListAdapter and PreferenceSearchAdapter classes to use AndroidX ListAdapter to handle displaying list data. We have no idea what this does, but anything involving AndroidX automatically becomes cooler by 10%.

  • @opusforlife2 added ‘reading the FAQ’ to the issue template checklist, which will hopefully help solve user problems before they even open an issue.

  • @mhmdanas removed some extra whitespace from the issue and PR templates, and also clarified in the README that hidden links kept for backwards compatibility don’t need to be copied over to new translations.

  • @Stypox ensured that the app keeps strong references to Picasso notification icon loading targets, which fixes a potential bug that caused new stream notifications to not show whenever the garbage collector did its job prematurely.

Refactoring the player

  • Here are some under-the-hood changes involved in refactoring the player, so you could get an idea of how complex it was earlier:

    • Approximately 2500 lines of code, dealing with the different kinds of players, were extracted out from the Player class and moved into their own individual plug-and-play UI classes: a base class (PlayerUi), and a class for each kind of playback, namely NotificationPlayerUi, MainPlayerUi, and PopupPlayerUi (with the code common to the latter two kept in VideoPlayerUi).
    • Newer APIs were introduced in the process as well, which made the code much simpler to write and use.
    • The Queue Activity was changed to use its own adapter, instead of using the player’s queue adapter.
    • The BackgroundPlayerUi, PlayerState and PlayerServiceBinder classes were removed. Less code is good code.
    • For Android 7 and higher, the setVideoSurfaceHolder method is now used, unlike lower Android versions where its manual alternative still has to be used.
    • The notification calls were moved to the NotificationPlayerUi class.
  • In the next round of refactoring:

    • A MediaSessionPlayerUi class was introduced, containing yet more code extracted from the Player class, and MediaSessionManager was merged into it.
    • The MediaSessionCallback and PlayerMediaSession wrapper classes were removed, and their function used directly.

Farewell to a team member who left the project

We’re sad to say that @mhmdanas/triallax is leaving the team, after dedicating more than 2 years to the project in the form of code contributions, repo maintenance, and community interaction. Most people who hang around the NewPipe repo and IRC channel are familiar with him, and anyone who has opened an issue in the repo has likely interacted with him at least once. In a way, @mhmdanas’s near constant presence has become a staple of the NewPipe project experience, and it will be difficult for us to get used to not having him around all the time. Fear not, however! This will not turn into a missing person case. @mhmdanas will stick around in the IRC channel, so anyone and everyone can walk up to him and tap him on the shoulder, metaphorically speaking.

Where to get this brand-new version

NewPipe notifies you about new versions. You can download them when you press the notification, which will take you to the GitHub Releases page.

If you use the F-Droid app, it, too, notifies you about updates for NewPipe. Please keep in mind that it can take F-Droid a while to update their repository. If you have problems installing the update, you may need to uninstall NewPipe and then install it afresh. (Make sure to backup data by exporting your database from the Settings > Content menu.)

If you already installed NewPipe from F-Droid’s repository, to get this version of NewPipe you can do one of the following:

Note: If you installed NewPipe from GitHub Releases you will not have to uninstall NewPipe to switch to our custom repo. Just let it update your current version. Make sure you back up your data as mentioned in the warning at the top of the FAQ page!

Now that you’ve (hopefully) updated, please let us know what your experience of the latest release is, especially bugs in need of fixing. As usual, you can reach out to us via IRC (#newpipe on Libera.Chat), open issues on GitHub or, ideally, use our built-in crash reporter to send us machine-readable issue reports. You can even send in fixes yourself.

If you have any other questions, feel free to post them in the comments here and someone will reply to you. Also, thanks for reading it until the end! We put quite some time into these blog posts.

See also:  pinned  release

Let us know what you think!

Please read our rules before leaving a comment!

→ Feature requests or bug reports need to be reported on GitHub! ←