windows下载ActivityNet数据集的福利来了,最近下载该数据集,用方法1的方法,发现只能在Linux下面下,然后用他的连接里面的第二种方法,该方法可以在windows下面下载,但只有一个线程,下的时间太长,而且下载下来以后格式不是.mp4,根本就没有后缀,更甚而,这个数据集有的视频被分成了几个片段,但下载下来以后根本就没有成几个,还是一个原始的没有后缀的视频,需要自己再重新写代码修改后缀和按照json文件里面的起止时间将视频再分成几个片段,这样太麻烦了。于是我就将下载Kinetics数据集的方法,修改以后用到这里来,该程序一次性到位,下载以后的视频就是我们想要的视频,而且我还将所有片段的分辨率设置成320x240,现在不设置,以后跑代码的时候也要设置,所以就现在设置了,少占内存,很多视频是1920x1080的,太大了,我下载的ActivityNet100,有10%左右的网址已经失效,没下载下来,下载下来以后的总视频大小是33G,比Kinetics600的530G小多了。但该视频数据集的起止时间有些问题,有的视频片段持续时间一秒钟都不到,我自己下载的时候也没有设置这个,当然可以在程序里面将这个起止时间前后挪挪,视频就可以长一点了,大家下载的时候可以修改一下程序。由于本人水平不行,这点程序调试了我几乎一天的时间,终于搞定,下载周期12个小时,不过国内的用户下载的话,需要用到代理,需要在command = [‘youtube-dl’, ‘–quiet’, ‘–no-warnings’, ‘-f’, ‘mp4’, ‘-o’, ‘"%s"’ % tmp_filename, ‘"%s"’ % (url_base + video_identifier)]这一句中间加上‘-sslocal’,’ ',最后这个引号里面好像是http:\\127.0.0.1:1080, 还是什么的,反正你用代理的就应该知道这里填的啥了。我是将电脑放在澳门朋友那里让朋友在澳门帮忙下载的,网速比国内快多了,所以半天就下载好了,国内下载这个数据集,代理账号应该会被查封,我下载Kinetics的时候,下了2天,就被查封了,以后再也下不了了。虽然这个数据集小点,我在澳门下载的是ActivityNet100用了半天,在国内用代理至少得2天时间,如果要下载ActivityNet200,时间就会更长。话不多说,上代码吧。
准备工作:
1.安装anaconda
2.pip install youtube-dl
3.pip install ffmpeg
4. 随便建一个工程,新建一个python file文档,命名为download.py,将下面的代码拷贝进去
5. 去ActivityNet官网下载json文件,说是下载,其实是点开下图这个向下的箭头 ,
在自己新建的工程里面新建一个txt文档(和download.py放在同一个文件夹下),把刚才点击下拉箭头后出现的文档全部复制进去,然后重新命名为activity_net.v1-3.min.json。
6. 将下面代码的 directory = 'dataset/'后面的dataset/, 按照你自己的喜好重新命名,注意后面的‘/’不能少。
7. cd 到download.py所在的目录,执行python download.py 开始告诉下载之旅吧。
import os
import json
import uuid
import glob
import subprocess
from joblib import delayed
from joblib import Parallel
# specify download directory
directory = 'dataset/'
videoCounter = 0
num_jobs = 24
# open json file
with open('activity_net.v1-3.min.json') as data_file:
data = json.load(data_file)
# take only video informations from database object
videos = data['database']
total = len(videos)
# iterate through dictionary of videos
def download_clip(videos, i, key, directory, total):
video = videos[key]
# find video subset
subset = video['subset']
# find video label
annotations = video['annotations']
label = ''
if len(annotations) != 0:
label = annotations[0]['label']
label = '/' + label.replace(' ', '_')
# create folder named as <label> if does not exist
label_dir = directory + subset + label
if not os.path.exists(label_dir):
os.makedirs(label_dir)
# take url of video
url = video['url']
tmp_dir = 'tmp'
url_base = 'https://www.youtube.com/watch?v='
video_identifier = key
tmp_filename = os.path.join(tmp_dir,
'%s.%%(ext)s' % uuid.uuid4())
command = ['youtube-dl',
'--quiet', '--no-warnings',
'-f', 'mp4',
'-o', '"%s"' % tmp_filename,
'"%s"' % (url_base + video_identifier)]
command = ' '.join(command)
attempts = 0
num_attempts = 5
while True:
try:
output = subprocess.check_output(command, shell=True,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as err:
attempts += 1
if attempts == num_attempts:
return err.output
else:
break
tmp_filename = glob.glob('%s*' % tmp_filename.split('.')[0])[0]
# Construct command to trim the videos (ffmpeg required).
if len(annotations) == 0:
sstr = label_dir + '/' + key + '.mp4'
command = ['ffmpeg',
'-i', '"%s"' % tmp_filename,
'-strict', str(-2),
'-s', '320x240',
'-loglevel', 'panic',
'"%s"' % sstr]
command = ' '.join(command)
try:
output = subprocess.check_output(command, shell=True,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as err:
return err.output
else:
for jj in range(len(annotations)):
sstr = label_dir + '/' +key + '_' + str(annotations[jj]['segment'][0]) + '_' + str(annotations[jj]['segment'][1]) + '.mp4'
command = ['ffmpeg',
'-i', '"%s"' % tmp_filename,
'-ss', str(annotations[jj]['segment'][0]),
'-t', str(annotations[jj]['segment'][1] - annotations[jj]['segment'][0]),
'-strict', str(-2),
'-s', '320x240',
'-c:v', 'libx264', '-c:a', 'copy',
'-threads', '1',
'-loglevel', 'panic',
'"%s"' % sstr]
command = ' '.join(command)
try:
output = subprocess.check_output(command, shell=True,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as err:
return err.output
# Check if the video was successfully saved.
# status = os.path.exists(output_filename)
os.remove(tmp_filename)
print('已经下载了 {}/{}, 请耐心等待'.format(i, total))
return True
if num_jobs == 1:
for i, key in enumerate(videos):
download_clip(videos, i, key, directory, total)
else:
Parallel(n_jobs=num_jobs)(delayed(download_clip)(
videos, i, key, directory, total) for i, key in enumerate(videos) if i >= videoCounter)
# 后面的if语句是为了防止下载途中意外中断,videoCouter表示之前已经下载了的视频个数,终端之后你只需要,
# 比如“已经下载了 8887/9682, 请耐心等待”,在重新运行代码之前修改代码里面的 videoCounter = 0,当然由于是并行,所以最好修改成 #videoCounter = 8500.这个if语句 相当于从断点下载,但不需要一个一个的重新扫描已经下载的文件,非常耗时。本人下载kinetics600时,中途
#突然掉线扫描已经下载好的文件都扫描了一两天的时间。
当然,标题是window, Linux系统应该也是可以用的。
如果发现运行有问题,你可以按照方法二中的方法进行系统设置,然后把ActivityNet_Dataset_Download.py的代码全部替换成我这里的代码,就可以了,因为我的代码就是在这里编写的。