Skip to content

Quasolaris/NewPipePlaylistExtractor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NewPipe Playlist Extractor

NewPipe Playlist Extractor


This Python script extracts playlists made with the NewPipe app and allows you to download them as audio-files.

When you create a playlist in NewPipe it is not saved as a YouTube playlist and can therefore not be downloaded via a playlist-link. This script allows you to extract the list of videos you have in a playlist and downlaod them as audio files.

Buy Me A Coffe!

Stargazers over time

Note: To use script on Windows or Andriod please see instructions below

Note: MacOS users, you can follow the Linux guide

Table of Contents

  1. Features
  2. Codecs
  3. Dependencies
  4. Usage
  5. Linux
  6. Windows
  7. Android
  8. Errors and Troubleshooting

Features

  • Download all playlists with chosen audio codec
  • Downloads single playlist with chosen audio codec
  • Exports playlists as CSV file
  • Exports playlist into a TXT file (Format: "Playlist title" \n "URLs")
  • Output is coloured (Because colours are fun!)

Codecs

The script supports the following codecs:

  • mp3
  • wav
  • flac
  • acc
  • opus
  • mp4

Dependencies

  • pytube pip install pytube
  • db-sqlite3 pip install db-sqlite3
  • pydub pip install pydub
  • ffmpeg sudo apt install ffmpeg
  • The codec you want to download has to be installed on your machine

Usage

  • Export your NewPipe data (Click here to see how)
  • Load it to your PC
  • Extract it (You will need the newpipe.db file)
  • Run script with path to your newpipe.db file python3 main.py newpipe.db
  • Choose action
  • Follow instructions
  • To update playlists just repeat with new .db file, already downloaded files get ignored
  • Enjoy your music!

The playlists get saved into the /Script/Playlists folder

Linux

Install the dependencies and you are good to go.

Windows

To use the script on Windows you have to do a few extra stepps:

  • Dowanload ffmpeg for windows
  • Unpack the archive
  • Copy all .exe files from /ARCHIVE_NAME/bin
  • Paste them inside the /Scripts folder
  • Run script

Android

For a step-by-step installation guide for Android click here.

Errors and Troubleshooting

get_throttling_function_name: could not find match for multiple

This is an error due to YouTube changing stuff, either to update or simply to attack Pytube, NewPipe and other clients/downloader.

First: Check if Pytube has an update, maybe the Pytube team already fixed it.

If no update was published or the error still persists, follow these steps:

  1. Go to the pytube package folder (normaly: ~/.local/lib/python3.9/site-packages/pytube or use pip list -v to find it if that doesn't work)
  2. Open the cipher.py file in an editor of your choice (nano -c cipher.py the -c flag displays the line number where your cursor is)
  3. Comment out the following lines: 272 and 273
  4. Paste the following regex beneath the lines you just commented out (Make sure the white spaces are correct, it is python after all):
r'a\.[a-zA-Z]\s*&&\s*\([a-z]\s*=\s*a\.get\("n"\)\)\s*&&.*?\|\|\s*([a-z]+)',
r'\([a-z]\s*=\s*([a-zA-Z0-9$]+)(\[\d+\])?\([a-z]\)',
  1. Now go to line 290 (or 288 if you deleted the regex lines instead of commenting them out) with CTRL+_ in nano you can jump to a specific line.
  2. Comment the following line out:
nfunc=function_match.group(1)),
  1. Right underneath the now commented out line, place the following:
nfunc=re.escape(function_match.group(1))),

The file sector you changed should now look like this:

function_patterns = [
        # https://github.com/ytdl-org/youtube-dl/issues/29326#issuecomment-865985377
        # https://github.com/yt-dlp/yt-dlp/commit/48416bc4a8f1d5ff07d5977659cb8ece7640dcd8
        # var Bpa = [iha];
        # ...
        # a.C && (b = a.get("n")) && (b = Bpa[0](b), a.set("n", b),
        # Bpa.length || iha("")) }};
        # In the above case, `iha` is the relevant function name
        #r'a\.[a-zA-Z]\s*&&\s*\([a-z]\s*=\s*a\.get\("n"\)\)\s*&&\s*'
        #r'\([a-z]\s*=\s*([a-zA-Z0-9$]{3})(\[\d+\])?\([a-z]\)',
        r'a\.[a-zA-Z]\s*&&\s*\([a-z]\s*=\s*a\.get\("n"\)\)\s*&&.*?\|\|\s*([a-z]+)',
        r'\([a-z]\s*=\s*([a-zA-Z0-9$]+)(\[\d+\])?\([a-z]\)',
    ]
    logger.debug('Finding throttling function name')
    for pattern in function_patterns:
        regex = re.compile(pattern)
        function_match = regex.search(js)
        if function_match:
            logger.debug("finished regex search, matched: %s", pattern)
            if len(function_match.groups()) == 1:
                return function_match.group(1)
            idx = function_match.group(2)
            if idx:
                idx = idx.strip("[]")
                array = re.search(
                    r'var {nfunc}\s*=\s*(\[.+?\]);'.format(
                        #nfunc=function_match.group(1)),
                        nfunc=re.escape(function_match.group(1))),
                    js
                )
                if array:
                    array = array.group(1).strip("[]").split(",")
                    array = [x.strip() for x in array]
                    return array[int(idx)]

    raise RegexMatchError(
        caller="get_throttling_function_name", pattern="multiple"
  1. Save and close the file
  2. You should now be able to download your playlists again

AttributeError: 'NoneType' object has no attribute 'span'

This is an error due to YouTube changing stuff, either to update or simply to attack Pytube, NewPipe and other clients/downloader. See pytube/pytube#1499 (comment) for the issue and the fix.

  1. First: Check if Pytube has an update, maybe the Pytube team already fixed it. If no update was published or the error still persists, follow these steps:
  2. Go to the pytube package folder (normaly: ~/.local/lib/python3.9/site-packages/pytube or use pip list -v to find it if that doesn't work)
  3. Modify {path to pip packages}/pytube/cipher.py:
        transform_plan_raw = find_object_from_startpoint(raw_code, match.span()[1] - 1)

to

        transform_plan_raw = js
  1. Save the file
  2. Try again.