Output urls by searching video title in a channel
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

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')