如何在python脚本中使用youtube-dl从播放列表中检索单个视频URL?

How do I retrieve individual video URLs from a playlist, using youtube-dl within a python script?

我正在努力:

  • 在python脚本中使用youtube dl定期下载视频
  • 通过YouTube数据动态组织/命名视频,即%(标题)s
  • 提取音频/mp3并将这些文件移动到名为"mp3"的子目录中

我对python还很陌生,我确信有一些杂乱无章、不必要的代码;所以,我也愿意接受清理建议。

我遇到了一个问题,当我输入播放列表的URL(而不是单个的URL)时,我只是获取播放列表的名称而不是单个标题,上载程序数据是我用来排序文件的。(我不知道如何或是否可以在整个代码中使用outmpl选项/变量)

我实际上把代码分成三部分/模块。

问题的基本示例如下-我输入:

1
outmpl: 'F:\\Videos\\Online Videos\\Comics\\%(uploader)s\\%(playlist)s\\%(playlist_index)s_%(title)s.%(ext)s'

将视频保存到:

1
'F:\\Videos\\Online Videos\\Comics\\Comicstorian\\Annhililation\\01_Annihilation Beginnings Drax Earthfall - Complete Story.mp4' - and so on (for the rest of the videos)

但是,我不知道要将目录变量传递到我移动文件的模块中。

这是代码-三个模块/部件

pyfile下载.py

1
2
3
4
5
6
7
8
9
10
11
12
from __future__ import unicode_literals
import youtube_dl
import Move_MP3
import ytdl_variables

#Uses variables from ytdl_variables script and downloads the video

with youtube_dl.YoutubeDL(ytdl_variables.ydl_opts) as ydl:
    ydl.download([ytdl_variables.video_url])

#Calls script to create folder and move MP3 files
Move_MP3

YTDL_variables.py(YTDL_变量.py)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from __future__ import unicode_literals
import youtube_dl

global video_title, uploader, playlist, playlist_index, video_url, ydl_opts, ydl

video_url = 'https://www.youtube.com/playlist?list=PL6FhCd_HO_ACJzTiLKfETgzLc1an_t05i'


ydl_opts = {
    'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
    'outtmpl': 'F:\\Videos\\Online Videos\\Comics\\%(uploader)s\\%(playlist)s\\%(playlist_index)s_%(title)s.%(ext)s',
    'postprocessors': [{
        'key': 'FFmpegExtractAudio',
        'preferredcodec': 'mp3',
        'preferredquality': '192',
    }],
    'download_archive': 'F:\\Videos\\Online Videos\\Archive.txt',
}

with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        #The next part creates a variable that returns info when provided the video_url variable >> http://stackoverflow.com/questions/23727943/how-to-get-information-from-youtube-dl-in-python
        '''
            Code here should get take the youtube playlist and spit out
            each url to move to the next step as vLinks variable, but
            I haven't figured out how to pass (title) etc. variables from
           each video in a playlist.



  link = individual video url from playlist

The following puts actual info into variables for Python to use. These are made global above. I made a 'for' loop to repeat grabbing info for each video - but it doesn't work right now b/c I didn't define vLinks.
'''

    for vLink in vLinks:
        info_dict = ydl.extract_info(link, download=False)
        video_title = info_dict.get('title', None)
        playlist_index = info_dict.get('playlist_index', None)
        playlist = info_dict.get('playlist', None)
        uploader = info_dict.get('uploader', None)
        print(video_title)

#Checks if the video is in a playlist; if it's not, 'NA' will be the string returned: http://stackoverflow.com/questions/23086383/how-to-test-nonetype-in-python

if playlist is None:
    playlist = 'NA'

if playlist_index is None:
    playlist_index = 'NA'

移动MP3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from __future__ import unicode_literals
import ytdl_variables
import shutil
import os, os.path

#Sets variables for renaming the files
newfolder = 'F:\\Videos\\Online Videos\\Comics\' + ytdl_variables.uploader + '\' + ytdl_variables.playlist + '\\MP3\'
oa_savedir = '
F:\\Videos\\Online Videos\\Comics\' + ytdl_variables.uploader + '\' + ytdl_variables.playlist + '\' + ytdl_variables.playlist_index + '_' + ytdl_variables.video_title + '.mp3'
fa_savedir = '
F:\\Videos\\Online Videos\\Comics\' + ytdl_variables.uploader + '\' + ytdl_variables.playlist + '\\MP3\' + ytdl_variables.playlist_index + '_' + ytdl_variables.video_title + '.mp3'

#Function that creates file directory before moving file there - changed from http://stackoverflow.com/questions/23793987/python-write-file-to-directory-doesnt-exist
def mkdir_p(path):
    if not os.path.exists(path):
        os.makedirs(path);

#Function that checks whether the file already exists where I want to move it >> http://stackabuse.com/python-check-if-a-file-or-directory-exists/
def chkfl_p(path):
    if not os.path.isfile(path):
        shutil.move(oa_savedir, fa_savedir);

#Calls function to look for \MP3 directory and creates directory if it doesn'
t exist
mkdir_p(newfolder)
#Calls function to look for file and moves file if it isn't already there
chkfl_p(fa_savedir)

我正在努力清理这个问题,但是我在另一个答案的一部分找到了答案…

要从播放列表URL获取单个链接,请执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ydl = youtube_dl.YoutubeDL({'outtmpl': '%(id)s%(ext)s', 'quiet':True,})
video =""

with ydl:
    result = ydl.extract_info \
    (yt_url,
    download=False) #We just want to extract the info

    if 'entries' in result:
        # Can be a playlist or a list of videos
        video = result['entries']

        #loops entries to grab each video_url
        for i, item in enumerate(video):
            video = result['entries'][i]

youtube_dl.YoutubeDL似乎从youtube api返回json数据。YT_URL是视频或播放列表的变量。

如果返回的数据有"entries",它是一个播放列表-然后我循环这些条目(用i(ndex)枚举条目),从那里我可以用URL或其他信息做我想要的事情。

1
2
3
4
5
result['entries'][i]['webpage_url']     #url of video
result['entries'][i]['title']           #title of video
result['entries'][i]['uploader']        #username of uploader
result['entries'][i]['playlist']        #name of the playlist
result['entries'][i]['playlist_index']  #order number of video