Created
September 17, 2016 09:09
-
-
Save alexeygrigorev/a1bc540925054b71e1a7268e50ad55cd to your computer and use it in GitHub Desktop.
Downloading segmented video from vimeo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import base64 | |
from tqdm import tqdm | |
master_json_url = 'https://178skyfiregce-a.akamaihd.net/exp=1474107106~acl=%2F142089577%2F%2A~hmac=0d9becc441fc5385462d53bf59cf019c0184690862f49b414e9a2f1c5bafbe0d/142089577/video/426274424,426274425,426274423,426274422/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) | |
video = content['video'][idx] | |
video_base_url = base_url + video['base_url'] | |
print 'base url:', video_base_url | |
filename = 'video_%d.mp4' % video['id'] | |
print 'saving to %s' % filename | |
video_file = open(filename, 'wb') | |
init_segment = base64.b64decode(video['init_segment']) | |
video_file.write(init_segment) | |
for segment in tqdm(video['segments']): | |
segment_url = video_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() |
so I skidded modifications from comments and added a bit of multi threading. It downloads video and audio, accepts playlist.json and master.json (mainly for playlist.json).
import os
import sys
import base64
import requests
import subprocess
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm
from moviepy.editor import *
import ffmpeg
url = input('enter [master|playlist].json url: ')
name = input('enter output name: ')
if 'master.json' in url:
url = url[:url.find('?')] + '?query_string_ranges=1'
url = url.replace('master.json', 'master.mpd')
print(url)
subprocess.run(['youtube-dl', url, '-o', name])
sys.exit(0)
def download_segment(segment_url, segment_path):
resp = requests.get(segment_url, stream=True)
if resp.status_code != 200:
print('not 200!')
print(segment_url)
return
with open(segment_path, 'wb') as segment_file:
for chunk in resp:
segment_file.write(chunk)
def download(what, to, base):
print('saving', what['mime_type'], 'to', to)
init_segment = base64.b64decode(what['init_segment'])
segment_urls = [base + segment['url'] for segment in what['segments']]
segment_paths = [f"segment_{i}.tmp" for i in range(len(segment_urls))]
with ThreadPoolExecutor(max_workers=15) as executor:
list(tqdm(executor.map(download_segment, segment_urls, segment_paths), total=len(segment_urls)))
with open(to, 'wb') as file:
file.write(init_segment)
for segment_path in segment_paths:
with open(segment_path, 'rb') as segment_file:
file.write(segment_file.read())
os.remove(segment_path)
print('done')
name += '.mp4'
base_url = url[:url.rfind('/', 0, -26) + 1]
content = requests.get(url).json()
vid_heights = [(i, d['height']) for (i, d) in enumerate(content['video'])]
vid_idx, _ = max(vid_heights, key=lambda _h: _h[1])
audio_quality = [(i, d['bitrate']) for (i, d) in enumerate(content['audio'])]
audio_idx, _ = max(audio_quality, key=lambda _h: _h[1])
video = content['video'][vid_idx]
audio = content['audio'][audio_idx]
base_url = base_url + content['base_url']
video_tmp_file = 'video.mp4'
audio_tmp_file = 'audio.mp4'
download(video, video_tmp_file, base_url + video['base_url'])
download(audio, audio_tmp_file, base_url + audio['base_url'])
def combine_video_audio(video_file, audio_file, output_file):
try:
video_stream = ffmpeg.input(video_file)
audio_stream = ffmpeg.input(audio_file)
ffmpeg.output(video_stream, audio_stream, output_file, vcodec='copy', acodec='copy').run(overwrite_output=True)
print(f"Archivo combinado guardado como {output_file}")
except ffmpeg.Error as e:
print(f"Error al combinar archivos: {e.stderr.decode()}")
combine_video_audio('video.mp4', 'audio.mp4', name)
os.remove(video_tmp_file)
os.remove(audio_tmp_file)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
see my previous comment
https://gist.github.com/alexeygrigorev/a1bc540925054b71e1a7268e50ad55cd?permalink_comment_id=5112477#gistcomment-5112477