Skip to content

Instantly share code, notes, and snippets.

@glowinthedark
Forked from alexeygrigorev/vimeo-download.py
Last active November 26, 2023 21:38
Show Gist options
  • Save glowinthedark/452f14b0bf29c086583297643bc26131 to your computer and use it in GitHub Desktop.
Save glowinthedark/452f14b0bf29c086583297643bc26131 to your computer and use it in GitHub Desktop.
Downloading segmented video from vimeo
#!/usr/bin/env python3
import subprocess
import sys
from pathlib import Path
import requests
import base64
from tqdm import tqdm
def execute(cmd):
popen = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, # redirect stderr to stdout
universal_newlines=True)
for stdout_line in iter(popen.stdout.readline, ""):
yield stdout_line
popen.stdout.close()
return_code = popen.wait()
if return_code:
raise subprocess.CalledProcessError(return_code, cmd)
if __name__ == '__main__':
master_json_url = sys.argv[1]
ffmpeg_video_audio_path_mp4 = sys.argv[2]
# master_json_url = 'https://31vod-adaptive.akamaized.net/exp=1701029749~acl=%2F201c3bca-a4f7-459a-bf25-ae5cc875ac66%2F%2A~hmac=0fb553666be653b92f01fb63e0e8fe60c8ce4c2f60086b9c5651405450a631ec/201c3bca-a4f7-459a-bf25-ae5cc875ac66/sep/video/289fc95d,3bf78ab1,3e6ffd1a,88ea7314,a864b8ef/master.json?base64_init=1'
base_url = master_json_url[:master_json_url.rfind('/', 0, -26) + 1]
resp = requests.get(master_json_url)
content = resp.json()
heights = [(i, d['height']) for (i, d) in enumerate(content['video'])]
idx, _ = max(heights, key=lambda __h: __h[1])
video = content['video'][idx]
audio_base_url = base_url + video['base_url']
print('base url:', audio_base_url)
video_fname = f'{video["id"]}_video.mp4'
print(f'saving to {video_fname}')
video_path = Path(video_fname)
if not video_path.exists():
video_file = open(video_fname, 'wb')
init_segment = base64.b64decode(video['init_segment'])
video_file.write(init_segment)
for segment in tqdm(video['segments']):
segment_url = audio_base_url + segment['url']
resp = requests.get(segment_url, stream=True)
if resp.status_code != 200:
print('not 200!')
print(resp)
print(segment_url)
break
for chunk in resp:
video_file.write(chunk)
video_file.flush()
video_file.close()
print(f'Wrote {video_path.absolute()}')
else:
print(f'File already exists {video_fname}!')
audio_path = None
if content['audio']:
audio = content['audio'][0] ## AUDIO QUALITY <<<<< take 1st ??????
audio_fname = f'{video["id"]}_audio.m4a'
audio_path = Path(audio_fname)
if not audio_path.exists():
audio_base_url = base_url + audio['base_url']
print('base url:', audio_base_url)
print(f'saving to {audio_fname}')
audio_file = open(audio_fname, 'wb')
init_segment = base64.b64decode(audio['init_segment'])
audio_file.write(init_segment)
for segment in tqdm(audio['segments']):
segment_url = audio_base_url + segment['url']
resp = requests.get(segment_url, stream=True)
if resp.status_code != 200:
print('not 200!')
print(resp)
print(segment_url)
break
for chunk in resp:
audio_file.write(chunk)
audio_file.flush()
audio_file.close()
else:
print(f'file already exists [{audio_fname}]')
if audio_path.exists():
for output in execute(['ffmpeg',
'-i', video_fname,
'-i', audio_fname,
'-codec', 'copy', ffmpeg_video_audio_path_mp4]):
print(output)
video_path.unlink()
audio_path.unlink()
print(f'Wrote merged video+audio: {ffmpeg_video_audio_path_mp4}')
else:
video_path.rename(ffmpeg_video_audio_path_mp4)
print(f'Wrote video: {ffmpeg_video_audio_path_mp4}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment