finished
This commit is contained in:
parent
ad9ce7ca77
commit
d3a17f6651
30
download
30
download
@ -1 +1,29 @@
|
||||
#!/bin/env python3
|
||||
#!/bin/env fish
|
||||
|
||||
if ! test -d venv
|
||||
/bin/env python3 -m venv venv
|
||||
. venv/bin/activate.fish
|
||||
/bin/env python3 -m pip install -r requirements.txt
|
||||
echo
|
||||
else
|
||||
. venv/bin/activate.fish
|
||||
end
|
||||
|
||||
if ! type -q curl
|
||||
echo "curl is required to run this script"
|
||||
exit
|
||||
end
|
||||
|
||||
if ! type -q chromedriver || ! type -q chromium-browser
|
||||
echo "both chromium-browser and chromedriver are required to run this script"
|
||||
exit
|
||||
end
|
||||
|
||||
if ! type -q ffmpeg
|
||||
echo "ffmpeg is required to run this script"
|
||||
exit
|
||||
end
|
||||
|
||||
if ! /bin/env python3 download.py $argv
|
||||
echo "download failed"
|
||||
end
|
||||
|
126
download.py
Normal file
126
download.py
Normal file
@ -0,0 +1,126 @@
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import subprocess
|
||||
from time import sleep
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
|
||||
|
||||
STUDON_LOGIN_URL = 'https://www.studon.fau.de/studon/saml.php'
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('url', help='Interactive StudOn screencast url')
|
||||
parser.add_argument('outfile', help='Destination file name without extension')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def find_video_urls(url):
|
||||
driver = webdriver.Chrome()
|
||||
wait = WebDriverWait(driver, 10)
|
||||
|
||||
try:
|
||||
driver.get(STUDON_LOGIN_URL)
|
||||
|
||||
while not driver.current_url.startswith('https://www.studon.fau.de'):
|
||||
driver.implicitly_wait(1)
|
||||
|
||||
driver.get(url)
|
||||
|
||||
wait.until(EC.presence_of_element_located((By.TAG_NAME, 'iframe')))
|
||||
iframe = driver.find_element(By.TAG_NAME, 'iframe')
|
||||
driver.switch_to.frame(iframe)
|
||||
|
||||
video_selector = (
|
||||
By.CSS_SELECTOR,
|
||||
'.h5p-current video'
|
||||
)
|
||||
|
||||
prev_button_selector = (
|
||||
By.CSS_SELECTOR,
|
||||
'.h5p-footer-previous-slide[role="button"]'
|
||||
)
|
||||
|
||||
next_button_selector = (
|
||||
By.CSS_SELECTOR,
|
||||
'.h5p-footer-next-slide[role="button"]'
|
||||
)
|
||||
|
||||
wait.until(EC.presence_of_element_located(prev_button_selector))
|
||||
for i in range(100):
|
||||
prev_button = driver.find_element(*prev_button_selector)
|
||||
if prev_button.get_attribute('aria-disabled') == 'true':
|
||||
break
|
||||
|
||||
prev_button.click()
|
||||
sleep(0.1)
|
||||
|
||||
video_urls = []
|
||||
for i in range(100):
|
||||
wait.until(EC.presence_of_element_located(video_selector))
|
||||
video = driver.find_element(*video_selector)
|
||||
video_urls.append(video.get_attribute('src'))
|
||||
|
||||
next_button = driver.find_element(*next_button_selector)
|
||||
if next_button.get_attribute('aria-disabled') == 'true':
|
||||
print('breaking')
|
||||
break
|
||||
|
||||
next_button.click()
|
||||
sleep(0.25)
|
||||
|
||||
return video_urls
|
||||
|
||||
finally:
|
||||
driver.quit()
|
||||
|
||||
|
||||
def download_and_merge_videos(urls, outfile):
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
|
||||
filenames = []
|
||||
|
||||
for idx, url in enumerate(urls):
|
||||
ext = url.split('.')[-1]
|
||||
filename = os.path.join(temp_dir, f'video_{idx}.{ext}')
|
||||
filenames.append(filename)
|
||||
|
||||
status = subprocess.call(['curl', '-o', filename, url])
|
||||
if status != 0:
|
||||
return False
|
||||
|
||||
list_content = ''
|
||||
for filename in filenames:
|
||||
list_content += f"file '{filename}'\n"
|
||||
|
||||
list_path = os.path.join(temp_dir, 'list.txt')
|
||||
with open(list_path, 'w') as f:
|
||||
f.write(list_content)
|
||||
|
||||
ext = urls[0].split('.')[-1]
|
||||
status = subprocess.call(['ffmpeg', '-f', 'concat', '-safe', '0',
|
||||
'-i', list_path, '-c', 'copy', outfile + '.' + ext])
|
||||
|
||||
shutil.rmtree(temp_dir, ignore_errors=True)
|
||||
|
||||
return status == 0
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
urls = find_video_urls(args.url)
|
||||
if not urls or len(urls) <= 0:
|
||||
exit(1)
|
||||
|
||||
if not download_and_merge_videos(urls, args.outfile):
|
||||
exit(1)
|
||||
|
||||
|
||||
main()
|
@ -1,7 +0,0 @@
|
||||
/bin/env python3 -m venv venv
|
||||
. venv/bin/activate.fish
|
||||
python3 -m pip install -r requirements.txt
|
||||
|
||||
echo
|
||||
echo "Usage: ./download <StudOn-Course-URL>"
|
||||
|
Loading…
x
Reference in New Issue
Block a user