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.
- 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!)
The script supports the following codecs:
- mp3
- wav
- flac
- acc
- opus
- mp4
- 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
- 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
Install the dependencies and you are good to go.
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
For a step-by-step installation guide for Android click here.
This is an error due to YouTube changing stuff, either to update or simply to attack Pytube, NewPipe and other clients/downloaders.
If no update was published or the error still persists, follow these steps:
- 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) - 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) - Comment out the following lines: 272 and 273
- 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]\)',
- 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.
- Comment the following line out:
nfunc=function_match.group(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"
- Save and close the file
- You should now be able to download your playlists again
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.
- 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:
- 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). - 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
- Save the file.
- Try again.