Skip to content

Instantly share code, notes, and snippets.

@quietvoid
Created April 17, 2021 18:03
Show Gist options
  • Save quietvoid/ced5232c83c14a9e2a2cbbea40392812 to your computer and use it in GitHub Desktop.
Save quietvoid/ced5232c83c14a9e2a2cbbea40392812 to your computer and use it in GitHub Desktop.
Vimeo downloader with tweaks
#!/bin/env python3
import base64
import os
import re
import sys
import tempfile
from urllib.parse import urlparse
import requests
from tqdm import tqdm
def download_video(url, content, base_url, path_split):
global session
base_video_url = base_url
path_offset = content['base_url'].count('../')
sep_path = path_split[-1].split('/')
base_sep_url = '/'.join(sep_path[0:len(sep_path) - 1 - path_offset])
base_video_url += base_sep_url + '/'
heights = [(i, d['height']) for (i, d) in enumerate(content['video'])]
idx, _ = max(heights, key=lambda h: h[1])
video = content['video'][idx]
video_path = base_video_url + video['base_url']
filenameVideo = tempfile.NamedTemporaryFile(prefix='video.', suffix='.mp4', dir=cwd, delete=False)
print ('Saving video to {}'.format(filenameVideo.name))
with open(filenameVideo.name, 'wb') as video_file:
init_segment = base64.b64decode(video['init_segment'])
video_file.write(init_segment)
for segment in tqdm(video['segments']):
segment_url = url._replace(path=video_path + segment['url'])
segment_url = segment_url._replace(query='')
resp = session.get(segment_url.geturl(), stream=True)
if resp.status_code != 200:
print('not 200!')
print(resp)
print(segment_url)
raise ValueError('Video segment could not be downloaded: ' + str(resp.status_code))
for chunk in resp:
video_file.write(chunk)
video_file.flush()
def download_audio(url, content, base_url, path_split):
global session
base_audio_url = base_url
path_offset = content['base_url'].count('../')
sep_path = path_split[-1].split('/')
# Audio download here
bitrate = [(i, d['bitrate']) for (i, d) in enumerate(content['audio'])]
print('Bitrate', bitrate)
idx, _ = max(bitrate, key=lambda x: x[1])
audio = content['audio'][idx]
track_offset = audio['base_url'].count('../')
base_sep_url = '/'.join(sep_path[0:len(sep_path) - 1 - path_offset - track_offset])
base_audio_url += base_sep_url + '/'
audio_path = base_audio_url + audio['base_url'].replace('../','')
print('Audio Base url:', audio_path)
filenameAudio = tempfile.NamedTemporaryFile(prefix='audio.', suffix='.mp4', dir=cwd, delete=False)
print('Saving audio to %s' % filenameAudio.name)
with open(filenameAudio.name, 'wb') as audio_file:
init_segment = base64.b64decode(audio['init_segment'])
audio_file.write(init_segment)
for segment in tqdm(audio['segments']):
segment_url = url._replace(path=audio_path + segment['url'])
segment_url = segment_url._replace(query='')
resp = session.get(segment_url.geturl(), stream=True)
if resp.status_code != 200:
print('not 200!')
print(resp)
print(segment_url)
raise ValueError('Audio segment could not be downloaded: ' + str(resp.status_code))
for chunk in resp:
audio_file.write(chunk)
audio_file.flush()
if len(sys.argv) >= 1:
master_json_url = sys.argv[1]
else:
print('master.json must be passed as argument', file=sys.stderr)
exit(1)
cwd = os.getcwd()
base_url = master_json_url[:master_json_url.rfind('/', 0, -26) + 1]
url = urlparse(master_json_url)
session = requests.Session()
resp = session.get(master_json_url)
content = resp.json()
path_split = url.path.split(f"/{content['clip_id']}/")
base_url = path_split[0] + "/" + content['clip_id'] + "/"
download_video(url, content, base_url, path_split)
download_audio(url, content, base_url, path_split)
print("Done!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment