You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
2.2 KiB
70 lines
2.2 KiB
import json
|
|
import youtube_dl
|
|
|
|
from contextlib import redirect_stdout
|
|
from io import StringIO
|
|
from youtube_dl.utils import DownloadError, UnavailableVideoError, MaxDownloadsReached
|
|
|
|
|
|
def get_video_list(chnl_url):
|
|
"""Get playlist with youtube-dl and output a dict containing urls to videos in the playlist."""
|
|
options = {
|
|
'format': 'bestvideo+bestaudio/best',
|
|
'extract_flat': 'in_playlist',
|
|
'quiet': True,
|
|
'dump_single_json': True,
|
|
}
|
|
|
|
str_buf = StringIO()
|
|
with redirect_stdout(str_buf):
|
|
with youtube_dl.YoutubeDL(options) as ydl:
|
|
try:
|
|
res = ydl.extract_info(chnl_url, download=False)
|
|
except UnavailableVideoError:
|
|
print("Failed channel URL: " + chnl_url)
|
|
ydl.report_error('unable to download video')
|
|
except MaxDownloadsReached:
|
|
print("Failed channel URL: " + chnl_url)
|
|
ydl.to_screen('[info] Maximum number of downloaded files reached.')
|
|
raise
|
|
except DownloadError as e:
|
|
print("Failed channel URL: " + chnl_url)
|
|
raise e
|
|
except Exception as e:
|
|
print("Failed channel URL: " + chnl_url)
|
|
raise e
|
|
else:
|
|
if ydl.params.get('dump_single_json', False):
|
|
ydl.to_stdout(json.dumps(res))
|
|
res['output_filename'] = ydl.prepare_filename(res)
|
|
retcode = ydl._download_retcode
|
|
|
|
try:
|
|
info = json.loads(str_buf.getvalue())
|
|
except ValueError as e:
|
|
print("Bad JSON")
|
|
raise e
|
|
|
|
return info
|
|
|
|
|
|
def filter_urls(info, keyword='', output=None):
|
|
"""Filter video names by pattern, print urls or output to file."""
|
|
entries = info['entries']
|
|
filtered_entries = []
|
|
|
|
for entry in entries:
|
|
url = "www.youtube.com/watch?v=" + entry['url']
|
|
if keyword in entry['title']:
|
|
print(entry['title'])
|
|
filtered_entries.append(url + "\n")
|
|
|
|
if output is None:
|
|
return filtered_entries
|
|
else:
|
|
with open(output, 'w') as f:
|
|
f.writelines(filtered_entries)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
filter_urls(get_video_list(''), '', 'output.txt')
|
|
|