FreeTube
FreeTube copied to clipboard
[Feature Request]: Export/save playlists as URLs.txt or CSV file for downloaders
Guidelines
- [x] I have searched the issue tracker for open and closed issues that are similar to the feature request I want to file, without success.
- [x] I have searched the documentation for information that matches the description of the feature request I want to file, without success.
- [x] This issue contains only one feature request.
Problem Description
It would be nice to be able to export a playlist from FreeTube for use in external tools. eg, downloading everything using Tartube (yt-dlp). At the moment there is only Settings->Data->Export playlists as FreeTube's own db format.
Proposed Solution
Possibly not worth adding to FreeTube itself? (rarely used feature) but I wrote a simple Python script that can export a plain text list of URLs, or a CSV file with video title, author, length, etc. Utility scripts like this could be bundled with FreeTube in a separate folder?
$ ./export-playlist.py --help
usage: export-playlist.py [-h] [--csv] [--list LIST] [--db DB]
Export playlists from the FreeTube app
options:
-h, --help show this help message and exit
--csv output CSV format instead of plain list of URLs
--list LIST named playlist
--db DB playlists.db file location
$ ./export-playlist.py
playlistName,videos,lastUpdated
"Favorites",10,"21 Feb 2025"
"Electronics",38,"05 Feb 2025"
"Music",268,"24 Feb 2025"
$ ./export-playlist.py --list Electronics
https://youtu.be/byVPAfodTyY
https://youtu.be/T45wk926us4
https://youtu.be/SoDr7vtm_yA
...
$ ./export-playlist.py --list Electronics --csv
videoId,title,author,lengthSeconds,timeAdded
byVPAfodTyY,"How to Install the ESP-IDF Toolchain on Windows","Espressif Systems",290,"31 Dec 2024"
T45wk926us4,"Python NumPy Tutorial for Beginners #1 - Creating Arrays and Dimensional Arrays","Code of the Future",773,"31 Dec 2024"
SoDr7vtm_yA,"Making a 10 cent solder stencil using KiCad, kapton tape, and a laser cutter","elexperiment",256,"31 Dec 2024"
...
#!/usr/bin/env python3
"""Export playlists from the FreeTube app as:
1. Plain text list of YouTube URLs (default), or
2. CSV file of video details (with --csv)"""
# This work is licensed under CC0 Public Domain
# by Nikki Smith 2025, https://Climbers.net
import argparse
import sys
import os
import json
from datetime import datetime
# Uncomment if you want to strip common phrases from video titles
striptitles = {}
#striptitles = {" (Official Video)", " (Official Music Video)",
# " (Official HD Video)", " (Official Audio)", " [Official Audio]",
# " [OFFICIAL VIDEO]", " [Official Music Video]", " [Official Video]",
# " (Official 4K Video)"}
parser = argparse.ArgumentParser(description='Export playlists from the FreeTube app')
parser.add_argument('--csv', action='store_true',
help='output CSV format instead of plain list of URLs')
parser.add_argument('--list', help='named playlist')
parser.add_argument('--db', help='playlists.db file location')
args = parser.parse_args()
if args.db:
fname = args.db
elif sys.platform == "win32":
fname = os.path.expandvars(r"%APPDATA%\FreeTube\playlists.db")
else:
fname = os.path.expanduser("~/.config/FreeTube/playlists.db")
fp = open(fname, encoding='utf-8')
listFound = False
# JSON playlists, one per line
if args.list is None:
print("playlistName,videos,lastUpdated")
for playlist in fp:
data = json.loads(playlist)
if args.list is None:
lastUpdated = datetime.fromtimestamp(data['lastUpdatedAt'] / 1000).strftime("%d %b %Y")
name = data['playlistName'].replace('"', '""')
print("\"%s\",%d,\"%s\"" % (name, len(data['videos']), lastUpdated))
elif args.list.casefold() == data['playlistName'].casefold():
listFound = True
if args.csv:
print("videoId,title,author,lengthSeconds,timeAdded")
for video in data['videos']:
if args.csv:
timeAdded = datetime.fromtimestamp(video['timeAdded'] / 1000).strftime("%d %b %Y")
title = video['title'].replace('"', '""')
for x in striptitles:
title = title.replace(x, "")
author = video['author'].replace('"', '""')
print("%s,\"%s\",\"%s\",%d,\"%s\"" %
(video['videoId'],title,author,video['lengthSeconds'],timeAdded))
else:
print("https://youtu.be/%s" % video['videoId'])
if args.list is not None and listFound is False:
raise ValueError('List not found in playlists')
fp.close()
Alternatives Considered
Clicking on every video in a playlist and manually cut'n'pasting all the URLs ;)
Issue Labels
support for external software
Additional Information
No response