Skip to content

Latest commit

 

History

History
176 lines (138 loc) · 7.09 KB

README.md

File metadata and controls

176 lines (138 loc) · 7.09 KB

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 download 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
  • Export playlists as CSV file
  • Export playlists as a TXT file (Format: "Playlist title" \n "URLs")
  • Export playlists as a Markdown file
  • Export playlists as a M3U8 file
  • 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 steps:

  • Download 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/downloaders.

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 (normally: ~/.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 (normally: ~/.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.