├── pyproject.toml ├── setup.cfg ├── images ├── kadenze1.png └── kadenze2.png ├── .coveragerc ├── requirements.in ├── .gitignore ├── requirements-dev.in ├── kadenze_dl ├── models.py ├── configuration.yml ├── tests │ ├── test_client.py │ ├── test_settings.py │ ├── test_cli.py │ ├── test_utils.py │ └── data │ │ ├── data-lectures-json.json │ │ ├── data-courses-data.json │ │ └── video_json.json ├── kadenze-dl.py ├── settings.py ├── utils.py └── kadenzeclient.py ├── Makefile ├── docker └── Dockerfile ├── setup.py ├── .github └── workflows │ ├── test.yml │ └── docker.yml ├── requirements.txt ├── LICENSE ├── requirements-dev.txt └── README.md /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 150 -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md 3 | -------------------------------------------------------------------------------- /images/kadenze1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gaarv/kadenze-dl/HEAD/images/kadenze1.png -------------------------------------------------------------------------------- /images/kadenze2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gaarv/kadenze-dl/HEAD/images/kadenze2.png -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | source = 3 | kadenze_dl 4 | omit = 5 | */tests/* 6 | **/__init__.py -------------------------------------------------------------------------------- /requirements.in: -------------------------------------------------------------------------------- 1 | typer==0.4.1 2 | PyYAML==5.4.1 3 | requests==2.25.1 4 | python-slugify==4.0.1 5 | playwright==1.22.0 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .coverage 3 | .cache/ 4 | .pytest_cache/ 5 | __pycache__ 6 | *.pyc 7 | *.egg-info/ 8 | *.spec 9 | /.pypirc 10 | /MANIFEST 11 | dist/ 12 | build/ 13 | venv/ 14 | test-configuration.yml -------------------------------------------------------------------------------- /requirements-dev.in: -------------------------------------------------------------------------------- 1 | typer==0.4.1 2 | PyYAML==5.4.1 3 | requests==2.25.1 4 | python-slugify==4.0.1 5 | playwright==1.22.0 6 | 7 | pip-tools==6.6.2 8 | black 9 | pytest==7.1.2 10 | pytest-cov==3.0.0 11 | pyinstaller==5.1 -------------------------------------------------------------------------------- /kadenze_dl/models.py: -------------------------------------------------------------------------------- 1 | from typing import NamedTuple 2 | 3 | 4 | class Session(NamedTuple): 5 | course: str 6 | index: int 7 | name: str 8 | path: str 9 | 10 | 11 | class Video(NamedTuple): 12 | session: Session 13 | index: int 14 | title: str 15 | url: str 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | install: 4 | pip install pip-tools 5 | pip-compile requirements.in 6 | pip install -r requirements.txt 7 | pip install -U . 8 | 9 | install-dev: 10 | pip install pip-tools 11 | pip-compile requirements-dev.in 12 | pip install -r requirements-dev.txt 13 | pip install -U . 14 | 15 | test: 16 | python -m pytest --cov -v -s -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.10 as builder 2 | 3 | RUN mkdir -p /app 4 | WORKDIR /app 5 | 6 | COPY kadenze_dl kadenze_dl 7 | COPY requirements-dev.in requirements-dev.in 8 | COPY setup.py setup.py 9 | COPY Makefile Makefile 10 | 11 | RUN make install-dev && \ 12 | pyinstaller --onefile kadenze_dl/kadenze-dl.py 13 | 14 | FROM mcr.microsoft.com/playwright/python:v1.22.0-focal 15 | 16 | RUN mkdir -p /app 17 | WORKDIR /app 18 | 19 | COPY --from=builder /app/dist . 20 | 21 | ENV PATH="/app:${PATH}" 22 | 23 | CMD ["kadenze-dl"] -------------------------------------------------------------------------------- /kadenze_dl/configuration.yml: -------------------------------------------------------------------------------- 1 | kadenze: 2 | login: "myemail@gmail.com" 3 | password: "mypassword" 4 | download: 5 | proxy: "" # Proxy URL, ie. "http://127.0.0.1:3128". Empty string "" if none. 6 | resolution: "720" # Video resolution to download. Valid values are "720" or "360". 7 | download_path: "/home/user/videos/kadenze" # The absolute path to download to 8 | courses: # Courses to download, as they appear in the URL. You can also use the keyword "all" 9 | - "all" 10 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name="kadenze-dl", 5 | version="1.2.0", 6 | description="Small application to download Kadenze (https://www.kadenze.com) videos for courses you enrolled in", 7 | author="Gaarv", 8 | author_email="gaarv@users.noreply.github.com", 9 | classifiers=[ 10 | "License :: OSI Approved :: MIT License", 11 | "Programming Language :: Python :: 3.8", 12 | "Programming Language :: Python :: 3.9", 13 | "Programming Language :: Python :: 3.10", 14 | "Programming Language :: Python :: 3 :: Only", 15 | ], 16 | url="https://github.com/gaarv/kadenze-dl", 17 | keywords=["kadenze", "download", "videos"], 18 | packages=["kadenze_dl"], 19 | python_requires=">=3.8, <4", 20 | ) 21 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | strategy: 8 | matrix: 9 | python: ['3.8', '3.9', '3.10'] 10 | platform: [ubuntu-latest] 11 | runs-on: ${{ matrix.platform }} 12 | 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v3 16 | 17 | - name: Set up Python ${{ matrix.python }} 18 | uses: actions/setup-python@v3 19 | with: 20 | python-version: ${{ matrix.python }} 21 | 22 | - name: Install dependencies 23 | run: python -m pip install -r requirements.txt 24 | 25 | - name: Install package 26 | run: python -m pip install -U . 27 | 28 | - name: Run test suite 29 | run: | 30 | pip install pytest 31 | python -m pytest -v -s 32 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile with python 3.10 3 | # To update, run: 4 | # 5 | # pip-compile requirements.in 6 | # 7 | certifi==2022.5.18.1 8 | # via requests 9 | chardet==4.0.0 10 | # via requests 11 | click==8.1.3 12 | # via typer 13 | colorama==0.4.4 14 | # via click 15 | greenlet==1.1.2 16 | # via playwright 17 | idna==2.10 18 | # via requests 19 | playwright==1.22.0 20 | # via -r requirements.in 21 | pyee==8.1.0 22 | # via playwright 23 | python-slugify==4.0.1 24 | # via -r requirements.in 25 | pyyaml==5.4.1 26 | # via -r requirements.in 27 | requests==2.25.1 28 | # via -r requirements.in 29 | text-unidecode==1.3 30 | # via python-slugify 31 | typer==0.4.1 32 | # via -r requirements.in 33 | urllib3==1.26.9 34 | # via requests 35 | websockets==10.1 36 | # via playwright 37 | -------------------------------------------------------------------------------- /kadenze_dl/tests/test_client.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import time 3 | from pathlib import Path 4 | from unittest.mock import patch 5 | 6 | from kadenze_dl.kadenzeclient import KadenzeClient 7 | from kadenze_dl.settings import build_settings 8 | from playwright.sync_api import sync_playwright 9 | 10 | TEST_CONFIG_FILE = Path(".").absolute() / "kadenze_dl" / "configuration.yml" 11 | 12 | 13 | def download_all_courses_videos_mock(self) -> None: 14 | subprocess.run(["playwright", "install"]) 15 | p = sync_playwright().start() 16 | browser = p.firefox.launch(headless=True) 17 | time.sleep(1) 18 | browser.close() 19 | p.stop() 20 | 21 | 22 | def test_playwright_install(): 23 | patch("kadenze_dl.kadenzeclient.KadenzeClient.download_all_courses_videos", download_all_courses_videos_mock).start() 24 | settings = build_settings(courses=["all"], resolution="720", config_file=TEST_CONFIG_FILE) 25 | kadendze_client = KadenzeClient(settings) 26 | kadendze_client.download_all_courses_videos() 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Gaarv 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Docker image 2 | 3 | on: 4 | push: 5 | branches: ['master'] 6 | 7 | env: 8 | REGISTRY: ghcr.io 9 | IMAGE_NAME: ${{ github.repository }} 10 | 11 | jobs: 12 | build-and-push-image: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: read 16 | packages: write 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v3 21 | 22 | - name: Log in to the Container registry 23 | uses: docker/login-action@v2 24 | with: 25 | registry: ${{ env.REGISTRY }} 26 | username: ${{ github.actor }} 27 | password: ${{ secrets.GITHUB_TOKEN }} 28 | 29 | - name: Extract metadata (tags, labels) for Docker 30 | id: meta 31 | uses: docker/metadata-action@v4 32 | with: 33 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 34 | 35 | - name: Build and push Docker image 36 | uses: docker/build-push-action@v3 37 | with: 38 | context: . 39 | file: ./docker/Dockerfile 40 | push: true 41 | tags: ghcr.io/gaarv/kadenze-dl:latest -------------------------------------------------------------------------------- /kadenze_dl/kadenze-dl.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | from pathlib import Path 3 | from typing import List, Optional 4 | 5 | import typer 6 | 7 | from kadenze_dl.kadenzeclient import KadenzeClient 8 | from kadenze_dl.settings import build_settings 9 | 10 | app = typer.Typer() 11 | 12 | 13 | @app.command() 14 | def main( 15 | login: Optional[str] = typer.Option(None, help="Login (email only) to kadenze"), 16 | password: Optional[str] = typer.Option(None, help="Password to kadenze"), 17 | resolution: str = typer.Option("720", help="Video resolution. Valid values are 360 and 720"), 18 | download_path: Optional[Path] = typer.Option(None, help="Absolute path to where to save videos on disk"), 19 | courses: List[str] = typer.Option(["all"], help="Courses to download, usage can be repeated."), 20 | config_file: Path = typer.Option(None, help="Path to a YAML configuration file that will take precedence over all CLI arguments"), 21 | proxy: Optional[str] = typer.Option(None, help="Proxy URL, ie. http://127.0.0.1:3128"), 22 | ): 23 | try: 24 | if config_file: 25 | typer.secho(f"Loading configuration from {config_file.as_posix()}", fg=typer.colors.GREEN) 26 | if config_file or all([login, password, download_path]): 27 | settings = build_settings(courses, resolution, config_file, login, password, download_path, proxy) 28 | subprocess.run(["playwright", "install", "firefox"]) 29 | kadenze_client = KadenzeClient(settings) 30 | kadenze_client.download_all_courses_videos() 31 | else: 32 | typer.secho("No config file and or not enough mandatory arguments were provided. Check --help", fg=typer.colors.RED) 33 | except Exception as e: 34 | typer.secho(e, fg=typer.colors.RED) 35 | 36 | 37 | if __name__ == "__main__": 38 | app() 39 | -------------------------------------------------------------------------------- /kadenze_dl/tests/test_settings.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import pytest 4 | from kadenze_dl.settings import build_settings 5 | 6 | TEST_CONFIG_FILE = Path(".").absolute() / "kadenze_dl" / "configuration.yml" 7 | 8 | 9 | def test_build_settings_config_file(): 10 | settings = build_settings(courses=["awesome-course-1", "awesome-course-2"], resolution="360", config_file=TEST_CONFIG_FILE) 11 | assert settings.login == "myemail@gmail.com" 12 | assert settings.password == "mypassword" 13 | assert settings.download_path.as_posix() == "/home/user/videos/kadenze" 14 | assert settings.courses == ["all"] 15 | assert settings.resolution.value == "720" 16 | 17 | 18 | def test_settings_singleton(): 19 | s1 = build_settings(courses=["all"], resolution="720", config_file=TEST_CONFIG_FILE) 20 | s2 = build_settings(courses=[], resolution="360", config_file=TEST_CONFIG_FILE) 21 | assert s1 is s2 22 | assert s2.login == "myemail@gmail.com" 23 | assert s2.password == "mypassword" 24 | assert s2.download_path.as_posix() == "/home/user/videos/kadenze" 25 | assert s2.courses == ["all"] 26 | assert s2.resolution.value == "720" 27 | 28 | 29 | def test_settings_cli_valid_arguments(): 30 | test_login = "myemail@gmail.com" 31 | test_password = "mypassword" 32 | test_download_path = Path("/home/user/videos/kadenze") 33 | settings = build_settings( 34 | courses=["all"], 35 | resolution="720", 36 | login=test_login, 37 | password=test_password, 38 | download_path=test_download_path, 39 | ) 40 | assert settings.login == test_login 41 | assert settings.password == test_password 42 | assert settings.download_path == test_download_path 43 | assert settings.courses == ["all"] 44 | assert settings.resolution.value == "720" 45 | 46 | 47 | def test_settings_cli_invalid_arguments(): 48 | test_download_path = Path("/home/user/videos/kadenze") 49 | with pytest.raises(ValueError): 50 | # no login, no password and no config file provided 51 | build_settings(courses=["all"], resolution="720", download_path=test_download_path) 52 | -------------------------------------------------------------------------------- /kadenze_dl/tests/test_cli.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | from pathlib import Path 3 | from unittest.mock import patch 4 | 5 | import typer 6 | from typer.testing import CliRunner 7 | 8 | TEST_CONFIG_FILE = Path(".").absolute() / "kadenze_dl" / "configuration.yml" 9 | 10 | runner = CliRunner() 11 | 12 | 13 | def download_all_courses_videos_mock(self) -> None: 14 | return None 15 | 16 | 17 | def test_cli_with_config(): 18 | patch("kadenze_dl.kadenzeclient.KadenzeClient.download_all_courses_videos", download_all_courses_videos_mock).start() 19 | entrypoint: typer.Typer = importlib.import_module("kadenze_dl.kadenze-dl") # type:ignore 20 | app = entrypoint.app # type:ignore 21 | result = runner.invoke(app, ["--config-file", TEST_CONFIG_FILE.as_posix()]) 22 | assert result.exit_code == 0 23 | 24 | 25 | def test_cli_with_args(): 26 | patch("kadenze_dl.kadenzeclient.KadenzeClient.download_all_courses_videos", download_all_courses_videos_mock).start() 27 | entrypoint: typer.Typer = importlib.import_module("kadenze_dl.kadenze-dl") # type:ignore 28 | app = entrypoint.app # type:ignore 29 | result = runner.invoke(app, ["--login", "myemail@gmail.com", "--password", "mypassword", "--download-path", "/home/user/videos/kadenze"]) 30 | assert result.exit_code == 0 31 | 32 | 33 | def test_cli_with_missing_arg(): 34 | patch("kadenze_dl.kadenzeclient.KadenzeClient.download_all_courses_videos", download_all_courses_videos_mock).start() 35 | entrypoint: typer.Typer = importlib.import_module("kadenze_dl.kadenze-dl") # type:ignore 36 | app = entrypoint.app # type:ignore 37 | result = runner.invoke(app, ["--login", "myemail@gmail.com", "--password", "mypassword"]) 38 | assert "No config file and or not enough mandatory arguments were provided" in result.stdout 39 | 40 | 41 | def test_cli_bad_config_file(): 42 | patch("kadenze_dl.kadenzeclient.KadenzeClient.download_all_courses_videos", download_all_courses_videos_mock).start() 43 | entrypoint: typer.Typer = importlib.import_module("kadenze_dl.kadenze-dl") # type:ignore 44 | app = entrypoint.app # type:ignore 45 | result = runner.invoke(app, ["--config-file", "requirements.txt"]) 46 | assert "Error while building configuration from file or provided arguments" in result.stdout 47 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile with python 3.10 3 | # To update, run: 4 | # 5 | # pip-compile requirements-dev.in 6 | # 7 | altgraph==0.17.2 8 | # via pyinstaller 9 | atomicwrites==1.4.0 10 | # via pytest 11 | attrs==21.4.0 12 | # via pytest 13 | black==22.3.0 14 | # via -r requirements-dev.in 15 | certifi==2022.5.18.1 16 | # via requests 17 | chardet==4.0.0 18 | # via requests 19 | click==8.1.3 20 | # via 21 | # black 22 | # pip-tools 23 | # typer 24 | colorama==0.4.4 25 | # via 26 | # click 27 | # pytest 28 | coverage[toml]==6.4 29 | # via pytest-cov 30 | future==0.18.2 31 | # via pefile 32 | greenlet==1.1.2 33 | # via playwright 34 | idna==2.10 35 | # via requests 36 | iniconfig==1.1.1 37 | # via pytest 38 | mypy-extensions==0.4.3 39 | # via black 40 | packaging==21.3 41 | # via pytest 42 | pathspec==0.9.0 43 | # via black 44 | pefile==2022.5.30 45 | # via pyinstaller 46 | pep517==0.12.0 47 | # via pip-tools 48 | pip-tools==6.6.2 49 | # via -r requirements-dev.in 50 | platformdirs==2.5.2 51 | # via black 52 | playwright==1.22.0 53 | # via -r requirements-dev.in 54 | pluggy==1.0.0 55 | # via pytest 56 | py==1.11.0 57 | # via pytest 58 | pyee==8.1.0 59 | # via playwright 60 | pyinstaller==5.1 61 | # via -r requirements-dev.in 62 | pyinstaller-hooks-contrib==2022.6 63 | # via pyinstaller 64 | pyparsing==3.0.9 65 | # via packaging 66 | pytest==7.1.2 67 | # via 68 | # -r requirements-dev.in 69 | # pytest-cov 70 | pytest-cov==3.0.0 71 | # via -r requirements-dev.in 72 | python-slugify==4.0.1 73 | # via -r requirements-dev.in 74 | pywin32-ctypes==0.2.0 75 | # via pyinstaller 76 | pyyaml==5.4.1 77 | # via -r requirements-dev.in 78 | requests==2.25.1 79 | # via -r requirements-dev.in 80 | text-unidecode==1.3 81 | # via python-slugify 82 | tomli==2.0.1 83 | # via 84 | # black 85 | # coverage 86 | # pep517 87 | # pytest 88 | typer==0.4.1 89 | # via -r requirements-dev.in 90 | urllib3==1.26.9 91 | # via requests 92 | websockets==10.1 93 | # via playwright 94 | wheel==0.37.1 95 | # via pip-tools 96 | 97 | # The following packages are considered to be unsafe in a requirements file: 98 | # pip 99 | # setuptools 100 | -------------------------------------------------------------------------------- /kadenze_dl/settings.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from enum import Enum, unique 3 | from pathlib import Path 4 | from typing import Dict, List, Optional 5 | 6 | from yaml import Loader, load 7 | 8 | 9 | @unique 10 | class Resolution(Enum): 11 | _360 = "360" 12 | _720 = "720" 13 | 14 | 15 | @dataclass 16 | class Settings: 17 | login: str 18 | password: str 19 | download_path: Path 20 | courses: List[str] 21 | resolution: Resolution 22 | proxy: Optional[str] = None 23 | 24 | def __new__(cls, *args, **kwargs): 25 | if not hasattr(cls, "instance"): 26 | cls.instance = super(Settings, cls).__new__(cls) 27 | return cls.instance 28 | 29 | 30 | def build_settings( 31 | courses: List[str], 32 | resolution: str, 33 | config_file: Optional[Path] = None, 34 | login: Optional[str] = None, 35 | password: Optional[str] = None, 36 | download_path: Optional[Path] = None, 37 | proxy: Optional[str] = None, 38 | ) -> Settings: 39 | try: 40 | if config_file and config_file.exists(): 41 | # use input config file and merge with defaults 42 | with open(config_file, "r") as f: 43 | d: Dict = load(f, Loader=Loader) 44 | _login: str = d["kadenze"]["login"] 45 | _password: str = d["kadenze"]["password"] 46 | _download_path = Path(d["download"]["download_path"]) 47 | _courses = d["download"]["courses"] 48 | _resolution = d["download"]["resolution"] 49 | _proxy = str(d["download"]["proxy"]) or None 50 | return Settings(_login, _password, _download_path, _courses, Resolution[f"_{_resolution}"], _proxy) 51 | else: 52 | # use provided arguments from CLI 53 | if all([login, password, download_path]): 54 | config = {} 55 | config["login"] = login 56 | config["password"] = password 57 | config["download_path"] = download_path 58 | config["resolution"] = Resolution[f"_{resolution}"] 59 | config["courses"] = courses if courses else ["all"] 60 | config["proxy"] = proxy 61 | return Settings(**config) 62 | 63 | else: 64 | raise ValueError("No config file and or no mandatory arguments were provided. Check --help") 65 | 66 | except Exception as e: 67 | raise ValueError(f"Error while building configuration from file or provided arguments: {e}") 68 | -------------------------------------------------------------------------------- /kadenze_dl/tests/test_utils.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import kadenze_dl.utils as utils 4 | from kadenze_dl.models import Session 5 | 6 | TEST_DATA_PATH = Path(".").absolute().joinpath("kadenze_dl", "tests", "data") 7 | 8 | 9 | def test_format_course(): 10 | courses_data = TEST_DATA_PATH.joinpath("data-courses-data.json").read_text() 11 | courses = utils.get_courses_from_json(courses_data) 12 | formatted_courses = [utils.format_course(course) for course in courses] 13 | expected_courses = [ 14 | "physics-based-sound-synthesis-for-games-and-interactive-systems-iv", 15 | "machine-learning-for-musicians-and-artists-v", 16 | "introduction-to-programming-for-the-visual-arts-with-p5-js-vi", 17 | "real-time-audio-signal-processing-in-faust", 18 | "creative-applications-of-deep-learning-with-tensorflow-i", 19 | "creative-applications-of-deep-learning-with-tensorflow-iv", 20 | ] 21 | assert formatted_courses == expected_courses 22 | 23 | 24 | def test_extract_filename(): 25 | video_url = ( 26 | "https://cdnc-prod-assets-private.kadenze.com/uploads/lecture_medium/4894/file/Reb_L5_720.mp4?Expires" 27 | "=1482662443\u0026Signature=QklHU9hV7z2gwVp9yYfN21IITWxPZnPa7c3QOUByerXthMHnGy7-PfWvw~jrk5bE6sNtj2uee" 28 | "gCiGNsusW3ummw0zQoNzO4e592eduSgP6SuN0axaqsdqiYGHHDG0dExRD~DepPmG1vSat2lJ3d8SOA0mYOfYMYz5Qk-oJd-wRHsx" 29 | "LQPKLhTW5sOD6OjSSajr7Qruu0s5Ej-5WKm4XLdLORz6q~OJEnye~ra~HsXhxqOfEDxoUYojvQZZNVdSRXUSZigEJ7vgYyNop-N7" 30 | "~HVRUGjXU~Z~NsB3LtFctaEvoNWd3CMVH~zwHmTKEF1rmDDb2To~ABS6t8sXREUdZ36pQ__\u0026Key-Pair-Id=APKAIPB43QU" 31 | "CA2NXZVSQmp4" 32 | ) 33 | filename = utils.extract_filename(video_url) 34 | assert filename == "Reb_L5_720.mp4" 35 | 36 | 37 | def test_get_courses_from_json(): 38 | courses_data = TEST_DATA_PATH.joinpath("data-courses-data.json").read_text("utf-8") 39 | courses = utils.get_courses_from_json(courses_data) 40 | assert len(courses) == 6 41 | 42 | 43 | def test_get_sessions_from_json(): 44 | sessions_data = TEST_DATA_PATH.joinpath("data-lectures-json.json").read_text("utf-8") 45 | courses = utils.get_sessions_from_json(sessions_data, course="real-time-audio-signal-processing-in-faust") 46 | assert len(courses) == 5 47 | 48 | 49 | def test_get_videos_from_json(): 50 | videos_data = TEST_DATA_PATH.joinpath("video_json.json").read_text("utf-8") 51 | session = Session( 52 | course="real-time-audio-signal-processing-in-faust", 53 | index=1, 54 | name="faust-overview-and-language-basics", 55 | path="/courses/real-time-audio-signal-processing-in-faust/sessions/faust-overview-and-language-basics", 56 | ) 57 | videos_360 = utils.get_videos_from_json(videos_data, 360, session) 58 | videos_720 = utils.get_videos_from_json(videos_data, 720, session) 59 | assert len(videos_360) == 10 60 | assert len(videos_720) == 10 61 | assert len(videos_360) == max(v.index for v in videos_360) 62 | assert len(videos_720) == max(v.index for v in videos_720) 63 | 64 | 65 | def test_get_video_title(): 66 | videos_data = TEST_DATA_PATH.joinpath("video_json.json").read_text("utf-8") 67 | session = Session( 68 | course="real-time-audio-signal-processing-in-faust", 69 | index=1, 70 | name="faust-overview-and-language-basics", 71 | path="/courses/real-time-audio-signal-processing-in-faust/sessions/faust-overview-and-language-basics", 72 | ) 73 | videos = utils.get_videos_from_json(videos_data, 720, session) 74 | videos_titles = [utils.get_video_title(v.title, utils.extract_filename(v.url)) for v in videos] # type: ignore 75 | videos_titles_expected = [ 76 | "Faust_C1_S1_1_V2_1080_2700kp_introduction.mp4", 77 | "Faust_C1_S1_2_V2_1080_2700kp_faust-online-editor.mp4", 78 | "Faust_C1_S1_3_V2_1080_2700kp_first-faust-program.mp4", 79 | "Faust_C1_S1_4_V2_1080_2700kp_adding-a-reverb.mp4", 80 | "Faust_C1_S1_5_V2_1080_2700kp_automating-triggering-and-generating-a-mobile-app.mp4", 81 | "Faust_C1_S1_6_V2_1080_2700kp_using-a-sawtooth-oscillator.mp4", 82 | "Faust_C1_S1_7_V2_1080_2700kp_breath-control.mp4", 83 | "Faust_C1_S1_8_V2_1080_2700kp_additive-synthesizer.mp4", 84 | "Faust_C1_S1_9_V2_1080_2700kp_polyphonic-midi-synthesizer.mp4", 85 | "Faust_C1_S1_10_V2_1080_2700kp_polyphonic-synthesizer-and-audio-effect.mp4", 86 | ] 87 | assert videos_titles == videos_titles_expected 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | kadenze-dl 4 | === 5 | 6 | Application to download Kadenze (https://www.kadenze.com) videos for courses you enrolled in. 7 | 8 | Download videos for offline usage / archive based on your profile information given in the configuration file to download videos courses. 9 | 10 | 11 | ## Docker 12 | 13 | Image size is 1.86GB. 14 | 15 | docker pull ghcr.io/gaarv/kadenze-dl:latest 16 | 17 | 18 | Pass options to command line: 19 | 20 | docker run --rm \ 21 | -v /absolute/local/path/to/download:/app/download \ 22 | ghcr.io/gaarv/kadenze-dl kadenze-dl \ 23 | --login "myemail@gmail.com" \ 24 | --password "mypassword" \ 25 | --download-path /app/download 26 | 27 | Here, `/absolute/local/path/to/download` is where you want to do download videos on your system. Other paths defined in the command line as `/app/download` do not need changes as they refer to the Docker internal path. 28 | 29 | 30 | You may also use a [Configuration file](#configuration-file): 31 | 32 | docker run --rm \ 33 | -v /absolute/local/path/to/download:/app/download \ 34 | -v /absolute/local/path/to/configuration.yml:/app/configuration.yml \ 35 | ghcr.io/gaarv/kadenze-dl kadenze-dl \ 36 | --config-file /app/configuration.yml 37 | 38 | In this setup, the download path defined in the configuration file must match the Docker internal path `/app/download` 39 | 40 | 41 | List all available options with: 42 | 43 | docker run --rm ghcr.io/gaarv/kadenze-dl kadenze-dl --help 44 | 45 | 46 | ## From source 47 | 48 | Preferably in a virtual environment, install package (Python >=3.8). Download or clone repository, then into root directory: 49 | 50 | pip3 install -U . 51 | 52 | 53 | Change directory to `kadenze_dl`: 54 | 55 | cd kadenze_dl/ 56 | 57 | 58 | Run the app, example: 59 | 60 | python3 kadenze-dl.py \ 61 | --login "myemail@gmail.com" \ 62 | --password "mypassword" \ 63 | --download-path /home/user/videos/kadenze 64 | 65 | 66 | List all available options with: 67 | 68 | python3 kadenze-dl.py --help 69 | 70 | 71 | ## Configuration file 72 | 73 | A YAML configuration file can also be used, template is available as `configuration.yml` in `kadenze_dl` directory: 74 | 75 | python3 kadenze-dl.py --config-file configuration.yml 76 | 77 | 78 | Replace placeholder fields in the configuration file in YAML format, example: 79 | 80 | kadenze: 81 | login: "myemail@gmail.com" 82 | password: "mypassword" 83 | download: 84 | proxy: "" # Proxy URL, ie. "http://127.0.0.1:3128". Empty string "" if none. 85 | resolution: "720" # Video resolution to download. Valid values are "720" or "360". 86 | download_path: "/home/user/videos/kadenze" # The absolute path to download to 87 | courses: # Courses to download, as they appear in the URL. You can also use the keyword "all" 88 | - "creative-applications-of-deep-learning-with-tensorflow-i" 89 | - "physics-based-sound-synthesis-for-games-and-interactive-systems-iv" 90 | 91 | 92 | Courses names must be reported as they appears in the URL, examples: 93 | 94 | https://www.kadenze.com/courses/creative-applications-of-deep-learning-with-tensorflow-i 95 | https://www.kadenze.com/courses/physics-based-sound-synthesis-for-games-and-interactive-systems-iv 96 | 97 | 98 | In configuration.yml: 99 | 100 | courses: 101 | - "creative-applications-of-deep-learning-with-tensorflow-i" 102 | - "physics-based-sound-synthesis-for-games-and-interactive-systems-iv" 103 | 104 | 105 | You can also use: 106 | 107 | courses: 108 | - "all" 109 | 110 | To download all courses listed in your "Home" page (including archived ones). 111 | 112 | For manual selected courses, you can get links from the "Home" page of your account or from the "Dashboard" URL on the left panel inside a course. 113 | 114 |  115 | 116 |  117 | 118 | 119 | ## Notes 120 | 121 | - kadenze-dl only support login from email / password. 122 | - you must be enrolled in the course for which you want to download related videos as they need to appear in your account. 123 | - **please be fair to Kadenze** and keep the videos for offline and personal use only, do not redistribute them 124 | - videos already present in the same path but incomplete are re-downloaded at the next run 125 | 126 | 127 | ## Credits 128 | 129 | Thanks to [Vladimir Ignatyev](https://gist.github.com/vladignatyev) for the progress console bar : 130 | https://gist.github.com/vladignatyev/06860ec2040cb497f0f3 -------------------------------------------------------------------------------- /kadenze_dl/utils.py: -------------------------------------------------------------------------------- 1 | import json 2 | import re 3 | from pathlib import Path 4 | from typing import List, Optional 5 | 6 | import requests 7 | import typer 8 | from slugify import slugify 9 | 10 | from kadenze_dl.models import Session, Video 11 | 12 | FILENAME_PATTERN = re.compile("file/(.*\\.mp4)\\?") 13 | 14 | 15 | def format_course(course: str) -> str: 16 | formatted_course = course.split("/")[-1] 17 | return f"{formatted_course}" 18 | 19 | 20 | def extract_filename(video_url: str) -> Optional[str]: 21 | filename = None 22 | try: 23 | match = re.search(FILENAME_PATTERN, video_url) 24 | if match: 25 | filename = match.group(1) 26 | except Exception as e: 27 | typer.secho(f"Error while extracting filename: {e}", fg=typer.colors.RED) 28 | return filename 29 | 30 | 31 | def get_courses_from_json(response: str) -> List[str]: 32 | try: 33 | json_string = json.loads(response) 34 | courses = [course["course_path"] for course in json_string["courses"]] 35 | except ValueError: 36 | typer.secho("Error getting the courses list. Check that you're enrolled on selected courses.", fg=typer.colors.RED) 37 | courses = [] 38 | return courses 39 | 40 | 41 | def get_sessions_from_json(response: str, course: str) -> List[Session]: 42 | sessions = [] 43 | try: 44 | d = json.loads(response) 45 | lectures = d["lectures"] 46 | for i, lecture in enumerate(lectures, start=1): 47 | try: 48 | session = Session(course, lecture["order"], slugify(lecture["title"]), lecture["course_session_path"]) 49 | sessions.append(session) 50 | except Exception as e: 51 | typer.secho(f"Error while extracting session metadata from course {course} at index {i}: {e}", fg=typer.colors.RED) 52 | except Exception as e: 53 | typer.secho(f"Error while extracting session metadata from course {course}: {e}", fg=typer.colors.RED) 54 | return sessions 55 | 56 | 57 | def get_videos_from_json(response: str, resolution: int, session: Session) -> List[Video]: 58 | videos = [] 59 | try: 60 | d = json.loads(response) 61 | video_format = f"h264_{resolution}_url" 62 | vs = d["videos"] 63 | for i, v in enumerate(vs, start=1): 64 | try: 65 | video = Video(session, v["order"], v["title"], v[video_format]) 66 | videos.append(video) 67 | except Exception as e: 68 | typer.secho(f"Error while extracting video metadata from session {session.name} at index {i}: {e}", fg=typer.colors.RED) 69 | except Exception as e: 70 | typer.secho(f"Error getting videos: {e}", fg=typer.colors.RED) 71 | return videos 72 | 73 | 74 | def get_video_title(video_title: str, filename: str) -> str: 75 | try: 76 | slug = slugify(video_title) 77 | video_title = "_".join(filename.split(".")[:-1]) + "p_" + slug + "." + filename.split(".")[-1] 78 | except IndexError: 79 | video_title = filename 80 | return video_title 81 | 82 | 83 | def write_video(video_url: str, full_path: Path, filename: str, chunk_size: int = 4096, proxy: Optional[str] = None) -> None: # pragma: no cover 84 | try: 85 | _proxy = {"http": proxy, "https": proxy} if proxy else None 86 | size = int(requests.head(video_url, proxies=_proxy).headers["Content-Length"]) 87 | size_on_disk = check_if_file_exists(full_path, filename) 88 | if size_on_disk < size: 89 | full_path.mkdir(parents=True, exist_ok=True) 90 | r = requests.get(video_url, stream=True, proxies=_proxy) 91 | current_size = 0 92 | with open(full_path / filename, "wb") as f: 93 | for chunk in r.iter_content(chunk_size=chunk_size): 94 | f.write(chunk) 95 | current_size += chunk_size 96 | s = progress(current_size, size, filename) 97 | print(s, end="", flush=True) 98 | typer.echo(s) # type: ignore 99 | else: 100 | typer.echo(f"{filename} already downloaded, skipping...") 101 | except Exception as e: 102 | typer.secho(f"Error while writing video to {full_path.joinpath(filename).as_posix()}: {e}", fg=typer.colors.RED) 103 | 104 | 105 | def check_if_file_exists(full_path: Path, filename: str) -> int: # pragma: no cover 106 | f = full_path / filename 107 | if f.exists(): 108 | return f.stat().st_size 109 | else: 110 | return 0 111 | 112 | 113 | def progress(count, total, status="") -> str: # pragma: no cover 114 | bar_len = 60 115 | filled_len = int(round(bar_len * count / float(total))) 116 | percents = round(100.0 * count / float(total), 1) 117 | bar = "=" * filled_len + "-" * (bar_len - filled_len) 118 | s = f"[{bar}] {percents}% filename: {status}\r" 119 | return s 120 | -------------------------------------------------------------------------------- /kadenze_dl/kadenzeclient.py: -------------------------------------------------------------------------------- 1 | import time 2 | from enum import Enum, unique 3 | from random import randint 4 | from typing import List 5 | 6 | import typer 7 | from playwright._impl._browser import Browser 8 | from playwright._impl._page import Page 9 | from playwright.sync_api import sync_playwright 10 | 11 | import kadenze_dl.utils as utils 12 | from kadenze_dl.models import Session, Video 13 | from kadenze_dl.settings import Settings 14 | 15 | BASE_URL = "https://www.kadenze.com" 16 | 17 | 18 | @unique 19 | class KadenzeSelectors(str, Enum): 20 | cookies_consent = '//*[@id="iubenda-cs-banner"]/div/div/a' 21 | login_email_button = "#email-login-btn" 22 | login_email_input = "input#login_user_email" 23 | login_password_input = "input#login_user_password" 24 | login_button = "//*[@id='login_user']/button" 25 | view_all_courses = "text=View all" 26 | view_my_courses = "div#my_courses" 27 | view_lectures = "div#lectures_json" 28 | pagination = "#pagination_page_number" 29 | pagination_next_disabled = ".next.is-disabled" 30 | videos = '//*[@id="video_json"]' 31 | 32 | 33 | class KadenzeClient: 34 | def __init__(self, settings: Settings) -> None: 35 | self.conf = settings 36 | 37 | def execute_login(self, browser: Browser) -> Page: # pragma: no cover 38 | typer.echo("Signing in www.kadenze.com ...") 39 | page: Page = browser.new_page() # type: ignore 40 | _ = page.goto(BASE_URL) 41 | random_wait() 42 | _ = page.mouse.click(0, 0) # Click popup banner 43 | _ = page.click(KadenzeSelectors.cookies_consent) # Click cookie consent 44 | _ = page.click(KadenzeSelectors.login_email_button) 45 | _ = page.fill(KadenzeSelectors.login_email_input, self.conf.login) 46 | _ = page.fill(KadenzeSelectors.login_password_input, self.conf.password) 47 | random_wait() 48 | _ = page.click(KadenzeSelectors.login_button) 49 | random_wait() 50 | return page 51 | 52 | def list_courses(self, page: Page) -> List[str]: # pragma: no cover 53 | try: 54 | _ = page.goto(BASE_URL + "/my_courses") 55 | random_wait() 56 | _ = page.click(KadenzeSelectors.view_all_courses) 57 | random_wait() 58 | div_courses = page.query_selector(KadenzeSelectors.view_my_courses) 59 | json_courses = div_courses.get_attribute("data-courses-data") # type: ignore 60 | courses = utils.get_courses_from_json(json_courses) 61 | except Exception as e: 62 | typer.secho(f"Error while listing courses: {e}", fg=typer.colors.RED) 63 | courses = [] 64 | return courses 65 | 66 | def extract_sessions(self, page: Page, course: str) -> List[Session]: # pragma: no cover 67 | sessions = [] 68 | typer.echo(f"Parsing course: {course}") 69 | sessions_url = "/".join((BASE_URL, "courses", course, "sessions")) 70 | page_num = 1 71 | 72 | try: 73 | while True: 74 | sessions_url = sessions_url if page_num == 1 else sessions_url + f"?page={page_num}" 75 | _ = page.goto(sessions_url) 76 | random_wait() 77 | div_sessions = page.query_selector(KadenzeSelectors.view_lectures) 78 | if div_sessions: 79 | json_sessions = div_sessions.get_attribute("data-lectures-json") # type: ignore 80 | _sessions = utils.get_sessions_from_json(json_sessions, course) 81 | sessions.extend(_sessions) 82 | 83 | # for courses with more than 10 sessions 84 | if page.query_selector(KadenzeSelectors.pagination) and not page.query_selector(KadenzeSelectors.pagination_next_disabled): 85 | page_num += 1 86 | else: 87 | break 88 | 89 | except Exception as e: 90 | typer.secho(f"Error while extracting sessions from course {course}: {e}", fg=typer.colors.RED) 91 | 92 | return sessions 93 | 94 | def extract_session_videos(self, page: Page, session: Session) -> List[Video]: # pragma: no cover 95 | videos = [] 96 | typer.echo(f"Parsing session: {session.name}") 97 | try: 98 | _ = page.goto(BASE_URL + session.path) 99 | random_wait() 100 | div_videos = page.query_selector(KadenzeSelectors.videos) 101 | json_videos = div_videos.get_attribute("value") # type: ignore 102 | videos = utils.get_videos_from_json(json_videos, self.conf.resolution.value, session) 103 | except Exception: 104 | typer.secho(f"Error while extracting videos from session={session.name}. Skipping...", fg=typer.colors.RED) 105 | return videos 106 | 107 | def download_video(self, video: Video) -> None: # pragma: no cover 108 | filename = utils.extract_filename(video.url) 109 | download_path = self.conf.download_path 110 | if filename and download_path: 111 | session_prefix = str(video.session.index) + "-" + video.session.name 112 | full_path = download_path / video.session.course / session_prefix 113 | full_path.mkdir(parents=True, exist_ok=True) 114 | filename = utils.get_video_title(video.title, filename) 115 | utils.write_video(video.url, full_path, filename, proxy=self.conf.proxy) 116 | else: 117 | typer.secho( 118 | f"Could not extract filename: video={video.title}, session={video.session.name}, course={video.session.course}. Skipping...", 119 | fg=typer.colors.BLUE, 120 | ) 121 | 122 | def download_course_videos(self, page: Page, course: str) -> None: # pragma: no cover 123 | videos: List[Video] = [] 124 | sessions = self.extract_sessions(page, course) 125 | for session in sessions: 126 | session_videos = self.extract_session_videos(page, session) 127 | videos.extend(session_videos) 128 | videos = [v for v in videos if v.url is not None] # filter out None urls (possible premium access) 129 | for video in videos: 130 | try: 131 | self.download_video(video) 132 | except Exception as e: 133 | typer.secho(f"Error while downloading video {video.title} from course {course}: {e}", fg=typer.colors.RED) 134 | 135 | def download_all_courses_videos(self) -> None: # pragma: no cover 136 | """main function to download all courses videos""" 137 | 138 | p = sync_playwright().start() 139 | proxy = {"server": self.conf.proxy} if self.conf.proxy else None 140 | browser = p.firefox.launch(headless=True, proxy=proxy) # type: ignore 141 | try: 142 | page = self.execute_login(browser) # type: ignore 143 | enrolled_courses = [utils.format_course(course) for course in self.list_courses(page)] 144 | if "all" in self.conf.courses: 145 | courses = enrolled_courses 146 | elif enrolled_courses: 147 | courses = [c for c in enrolled_courses if any(substring in c for substring in self.conf.courses)] 148 | else: 149 | courses = enrolled_courses 150 | typer.echo("Selected courses for download:") 151 | typer.echo("\n".join(courses)) 152 | for course in courses: 153 | self.download_course_videos(page, course) 154 | _ = page.close() 155 | except Exception as e: 156 | typer.secho(f"Error while running kadenze-dl: {e}", fg=typer.colors.RED) 157 | finally: 158 | browser.close() 159 | p.stop() 160 | 161 | 162 | def random_wait(): # pragma: no cover 163 | time.sleep(randint(5, 8)) 164 | -------------------------------------------------------------------------------- /kadenze_dl/tests/data/data-lectures-json.json: -------------------------------------------------------------------------------- 1 | { 2 | "timezone": "2022-06-03T11:44:40.778+02:00", 3 | "first_page": true, 4 | "last_page": true, 5 | "total_lectures": 5, 6 | "adaptive": true, 7 | "sort_lectures_path": "/courses/real-time-audio-signal-processing-in-faust/sessions/sort", 8 | "new_lecture_path": "/courses/real-time-audio-signal-processing-in-faust/sessions/new", 9 | "course_lectures_path": "/courses/real-time-audio-signal-processing-in-faust/sessions", 10 | "lectures_ids": [ 11 | 1005, 12 | 1006, 13 | 1007, 14 | 1008, 15 | 1009 16 | ], 17 | "course_id": 169, 18 | "lectures": [ 19 | { 20 | "id": 1005, 21 | "course_id": 169, 22 | "order": 1, 23 | "created_at": "2017-11-11T02:51:15.456+01:00", 24 | "start_date": "2019-01-16T00:00:00.000+01:00", 25 | "end_date": null, 26 | "title": "Faust Overview and Language Basics", 27 | "description": "This session gives an overview of the Faust ecosystem and of its various features. Simple high-level programming examples are provided towards making audio plug-ins, mobile and web apps, and externals for PureData and Max/MSP. It also begins a detailed survey of the Faust language that will be continued in Session 2.", 28 | "show_meets_from": false, 29 | "visible_on": "2019-01-16T00:00:00.000+01:00", 30 | "lecture_media_count": 10, 31 | "media_meta_data": "10 Video Files: 00:29:40", 32 | "button_title": "Go to Session", 33 | "button_class": "", 34 | "modal": false, 35 | "course_session_path": "/courses/real-time-audio-signal-processing-in-faust/sessions/faust-overview-and-language-basics", 36 | "title_with_type_and_number": "Session 1: Faust Overview and Language Basics", 37 | "thumb_url": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/169/lecture/1005/logo/cinema_Faust_S1.png?Expires=1654854280&Signature=Q9Fi9e7JR0CNCICaeFrTbcz-9lxIQ1hxhGeYhpmd9QCt3YIeiNw6sisIhtO6o0m9BmfzvVS8xtVScP0ZrAqi28-v6B4xKaXOtw5sh272N0J5a-Dr3AOz0G3dFTwTa3i9KgB2B9h0f9Eaxtyam1KUDnCicUDE0PTcurmx2SX10d9h09BXf67bd076IcXzvqnbf2rECInolTVHUkP2SpjvXLabU~UjeTqwSynAlfKu3FQVtyhQT1OCskfvcYiUSalH1nTPz1I0XhBPqw1rr1Ujo4~0ITtuvZg7QEai-~po8HyUCQjYnOTQOxv-YuqP~f5Pw5S6HegGYAvVUfrX1CzE7A__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 38 | "adaptive": true, 39 | "coursework": [ 40 | { 41 | "name": "Intro Survey (Stanford)", 42 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/survey-1-intro-survey-stanford", 43 | "link_to_cw": true 44 | }, 45 | { 46 | "name": "Breath-Controlled Polyphonic Synthesizer", 47 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-2-breath-controlled-polyphonic-synthesizer", 48 | "link_to_cw": true 49 | }, 50 | { 51 | "name": "Polyphonic Synthesizer", 52 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-1-polyphonic-synthesizer", 53 | "link_to_cw": true 54 | } 55 | ] 56 | }, 57 | { 58 | "id": 1006, 59 | "course_id": 169, 60 | "order": 2, 61 | "created_at": "2017-11-11T02:51:37.366+01:00", 62 | "start_date": "2019-01-16T00:00:00.000+01:00", 63 | "end_date": null, 64 | "title": "Programming with Faust", 65 | "description": "This lecture extends the review of the Faust language. Its goal is to present a detailed description of Faust’s semantics through a series of examples. In particular students will learn how to code any visual block diagram in Faust, and express the corresponding mathematical semantics. By the end of this lecture, students should be aware of all the syntactical element of the language and have a basic understanding of them. They will have implemented various simple sound synthesizers and effects…", 66 | "show_meets_from": false, 67 | "visible_on": "2019-01-16T00:00:00.000+01:00", 68 | "lecture_media_count": 9, 69 | "media_meta_data": "9 Video Files: 01:29:40", 70 | "button_title": "Go to Session", 71 | "button_class": "", 72 | "modal": false, 73 | "course_session_path": "/courses/real-time-audio-signal-processing-in-faust/sessions/programming-with-faust", 74 | "title_with_type_and_number": "Session 2: Programming with Faust", 75 | "thumb_url": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/169/lecture/1006/logo/cinema_Faust_S2.png?Expires=1654854280&Signature=C9YlRm2-Id-WduY5S9Gro6DlRs5YxFv5RuO-UkjVzARaANvYTdsxCZiQp1tTnfH3k-cR3HSY~Jk1SADRW8cc9dCfHlexwW7BlZyooHPYKX7TZwq6hGdUvXfg7-6CvwedvD~PGDI~AxwglYlKpev6CyhEQ7eSynKqm1lq8dJqFNZkblyYREGANe96g943XDzVPTwDxIkd7UeZKqEZPibrWthYVzA3efIyTs31lCL5FBcflsZ4O8WIy16GrWDKEiRIcLoA8b6~mPE6YRcd-M6HBEzg2q69xgUugPt6x2v1Qj1HqIS1~g5KyqWLGuAii2WvZp6gk9rtB4w~ZeGvOSEaeQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 76 | "adaptive": true, 77 | "coursework": [ 78 | { 79 | "name": "Working with Delays", 80 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-4-working-with-delays", 81 | "link_to_cw": true 82 | }, 83 | { 84 | "name": "Quiz: Expressions, Semantics, and Notation", 85 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/form-submission-3-quiz-expressions-semantics-and-notation", 86 | "link_to_cw": true 87 | }, 88 | { 89 | "name": "Triangular Waveform Generation", 90 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-6-triangular-waveform-generation", 91 | "link_to_cw": true 92 | }, 93 | { 94 | "name": "Create a User Interface", 95 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-5-create-a-user-interface", 96 | "link_to_cw": true 97 | } 98 | ] 99 | }, 100 | { 101 | "id": 1007, 102 | "course_id": 169, 103 | "order": 3, 104 | "created_at": "2017-11-11T02:51:56.609+01:00", 105 | "start_date": "2019-01-16T00:00:00.000+01:00", 106 | "end_date": null, 107 | "title": "Sound Synthesis and Processing I: Oscillators, AM, FM, and Subtractive Synthesis", 108 | "description": "The goal of this session is to implement various sound synthesis techniques (e.g., AM, FM, subtractive, sampling, basic physical modeling, granular) from scratch in Faust. A strong emphasis will be given to making “finished products,” (advanced user interfaces, polyphony and MIDI compatibility, etc.) ready to be converted to some of the platforms presented later.", 109 | "show_meets_from": false, 110 | "visible_on": "2019-01-16T00:00:00.000+01:00", 111 | "lecture_media_count": 4, 112 | "media_meta_data": "4 Video Files: 00:24:38", 113 | "button_title": "Go to Session", 114 | "button_class": "", 115 | "modal": false, 116 | "course_session_path": "/courses/real-time-audio-signal-processing-in-faust/sessions/sound-synthesis-and-processing-i-oscillators-am-fm-and-subtractive-synthesis", 117 | "title_with_type_and_number": "Session 3: Sound Synthesis and Processing I: Oscillators, AM, FM, and Subtractive Synthesis", 118 | "thumb_url": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/169/lecture/1007/logo/cinema_Faust_S3.png?Expires=1654854280&Signature=K-KG56kpOPFGmhNOMuUDTBQs4c8SBh8AK5ZnNvDiONrgf9j9kbMHJI39nubWOskYWBHuzw3PmKP-kqwMmC0sVt8CHyqf~Eb001i8G6d09GBtQUlfg7o1OFbMh26gZoLauCUziZ7SWTVTsCqusTk6nWEWSPuO-gLMrrHOEdGPmD2L69XgzFoDHYpLWHJ5vKtUe3rCRh25GpYXMMGqIYVZFRPaYOMjzCk8ozmU6wfViVrJGRbtZoXzx2fMb0EFGfrhL7VtiZ5WtPUWRJR9E9L9KQ9m-0y7KX5qgtAHYhMSsF8xQMkFY5J4rzeyE0kDzvX7laTfF~EKsUmyfog388l~mw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 119 | "adaptive": true, 120 | "coursework": [ 121 | { 122 | "name": "Towards the DX7", 123 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-9-towards-the-dx7", 124 | "link_to_cw": true 125 | }, 126 | { 127 | "name": "Fun With Subtractive Synthesis: Trying Other Types of Filters", 128 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-7-fun-with-subtractive-synthesis-trying-other-types-of-filters", 129 | "link_to_cw": true 130 | }, 131 | { 132 | "name": "Fun With Subtractive Synthesis: Using Multiple Filters", 133 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-8-fun-with-subtractive-synthesis-using-multiple-filters", 134 | "link_to_cw": true 135 | } 136 | ] 137 | }, 138 | { 139 | "id": 1008, 140 | "course_id": 169, 141 | "order": 4, 142 | "created_at": "2017-11-11T02:52:21.993+01:00", 143 | "start_date": "2019-01-16T00:00:00.000+01:00", 144 | "end_date": null, 145 | "title": "Sound Synthesis and Processing II: Filters, Echo, Basic Physical Modeling, Sampling and Granular Synthesis", 146 | "description": "In this session, various sound processing techniques/audio effects (basic filters, ring modulation, distortion, compressor, Schroeder reverb, flanger, phaser, pitch shifter, etc.) are implemented from scratch in Faust. As for Session 4, a strong emphasis will be given to implementing “finished products” that are “ready to be shipped”.", 147 | "show_meets_from": false, 148 | "visible_on": "2019-01-16T00:00:00.000+01:00", 149 | "lecture_media_count": 6, 150 | "media_meta_data": "6 Video Files: 00:40:55", 151 | "button_title": "Go to Session", 152 | "button_class": "", 153 | "modal": false, 154 | "course_session_path": "/courses/real-time-audio-signal-processing-in-faust/sessions/sound-synthesis-and-processing-ii-filters-echo-basic-physical-modeling-sampling-and-granular-synthesis", 155 | "title_with_type_and_number": "Session 4: Sound Synthesis and Processing II: Filters, Echo, Basic Physical Modeling, Sampling and Granular Synthesis", 156 | "thumb_url": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/169/lecture/1008/logo/cinema_Faust_S4.png?Expires=1654854281&Signature=FpKWpqyv4fZNBcpb~OyY3Q50VYvycqAKM9FmY5ST2G0wtTyDHOx3poq8AbUtCFAPrpeTu1TLo425Tvd2CGk8EjGSMOy4Eo-zuKaVYTLuy4IJfmnV5~VuzWfg7KfXEbfUiQvMY3hS6RxfgHygI~81JYSkUgJAVvaQidChK3IzO-QmVQ0RVpi-uEeJoVb1-Nc3WzFRRZBQrKWjZVcbp1X6gcHPGOVcl0rNjcLQWjqciFSG1YHkx1ZwRSAE7hRsCwFwRp7HwLTLDgpS3b7-qGAofa2~WZ8Niq4x66zInhfvrrdm~csSLjyA-8rOKPZ1BXN9QoBZ24Z2qwQfFk7DKy5Xqw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 157 | "adaptive": true, 158 | "coursework": [ 159 | { 160 | "name": "Using Effects From the Libraries", 161 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-11-using-effects-from-the-libraries", 162 | "link_to_cw": true 163 | }, 164 | { 165 | "name": "Shred It! ", 166 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-10-shred-it", 167 | "link_to_cw": true 168 | } 169 | ] 170 | }, 171 | { 172 | "id": 1009, 173 | "course_id": 169, 174 | "order": 5, 175 | "created_at": "2017-11-11T02:52:43.608+01:00", 176 | "start_date": "2019-01-16T00:00:00.000+01:00", 177 | "end_date": null, 178 | "title": "Deploying Faust Programs", 179 | "description": "This lecture provides a survey of the different Faust targets and shows how audio plug-ins, musical mobile and web apps, standalone applications, etc. can be generated with Faust. It also demonstrates how DSP engines can be embedded in other projects for a wide range of platforms, frameworks, and standards (e.g., web, mobile, VR, etc.). ", 180 | "show_meets_from": false, 181 | "visible_on": "2019-01-16T00:00:00.000+01:00", 182 | "lecture_media_count": 6, 183 | "media_meta_data": "6 Video Files: 01:09:53", 184 | "button_title": "Go to Session", 185 | "button_class": "", 186 | "modal": false, 187 | "course_session_path": "/courses/real-time-audio-signal-processing-in-faust/sessions/deploying-faust-programs-28433c5f-d62f-44b0-936d-8b87c62e13ca", 188 | "title_with_type_and_number": "Session 5: Deploying Faust Programs", 189 | "thumb_url": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/169/lecture/1009/logo/cinema_Faust_S5.png?Expires=1654854281&Signature=DSdbxq57L4HkCKTJGNcw7ssgoqlCAftpbvN7SNMPMMzy6n0TDqPToL31t1eXIKA4RcSO-Hjt4j~gapqvRF~a96dX6EFhGlLAg5BECjLZh89i79JDPojemtUFhat52RmA2hfZ7DlbwJfCuvY1aPZeFPkRvDAENdnjoZcT0Lj7GFO2cTJb6B78vWRujIoPYuKGGeJach0WGKacmr7RyZveAlwThgwgBU852ZX-R-PMr7fayRcEmoVsxF6vkpfqeXfauuyoWvLiCb5hitl0m3snBP5x0gXh9P45oOBAX1lv7EobTsdwF-8jd1-MVnt6TPt8iodIlaK2WvF52vy6cDm5KQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 190 | "adaptive": true, 191 | "coursework": [ 192 | { 193 | "name": "PureData Externals", 194 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-12-puredata-externals", 195 | "link_to_cw": true 196 | }, 197 | { 198 | "name": "SmartKeyboard Looper", 199 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/file-submission-13-smartkeyboard-looper", 200 | "link_to_cw": true 201 | }, 202 | { 203 | "name": "Exit Survey", 204 | "course_coursework_path": "/courses/real-time-audio-signal-processing-in-faust/coursework/survey-2-exit-survey", 205 | "link_to_cw": true 206 | } 207 | ] 208 | } 209 | ], 210 | "paginator": "" 211 | } -------------------------------------------------------------------------------- /kadenze_dl/tests/data/data-courses-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "courses": [ 3 | { 4 | "id": 91, 5 | "number": "RS 400", 6 | "name": "Physics-Based Sound Synthesis for Games and Interactive Systems", 7 | "institution_name": "Stanford University", 8 | "restricted": false, 9 | "full_name": "Physics-Based Sound Synthesis for Games and Interactive Systems", 10 | "skill_level": "Intermediate", 11 | "instructors": [ 12 | { 13 | "id": 14, 14 | "full_name": "Perry Cook", 15 | "abbr_name": "P. Cook" 16 | }, 17 | { 18 | "id": 63, 19 | "full_name": "Julius Smith", 20 | "abbr_name": "J. Smith" 21 | } 22 | ], 23 | "first_instructor": "Perry Cook", 24 | "instructor_names": "Perry Cook and Julius Smith", 25 | "instructors_count": 2, 26 | "guest_lecturer_text": "", 27 | "in_program": false, 28 | "program_only": false, 29 | "term_id": null, 30 | "term_name": null, 31 | "description": "
This course introduces the basics of Digital Signal Processing and computational acoustics, motivated by the vibrational physics of real-world objects and systems. We will build from a simple mass-spring and pendulum to demonstrate oscillation, learn how to simulate those systems in the computer, and also prove that these simple oscillations behave as a sine wave. From that we move to plucked strings and struck bars, showing both solutions as combined traveling waves and combined sine wave…
", 32 | "start_date": "09/20/2016", 33 | "end_date": "", 34 | "date_range": "Open for Enrollment", 35 | "time_status": "Active", 36 | "course_info_path": "/courses/physics-based-sound-synthesis-for-games-and-interactive-systems-iv/info", 37 | "course_share_url": "https://www.kadenze.com/courses/physics-based-sound-synthesis-for-games-and-interactive-systems-iv/info?utm_campaign=course_card_share&utm_content=course_id%3D91&utm_medium=share&utm_source=kadenze", 38 | "course_path": "/courses/physics-based-sound-synthesis-for-games-and-interactive-systems-iv", 39 | "gallery_path": "/courses/physics-based-sound-synthesis-for-games-and-interactive-systems-iv/gallery", 40 | "profile_path": "/users/14", 41 | "is_draft": false, 42 | "is_pending": false, 43 | "is_active": true, 44 | "is_upcoming": false, 45 | "is_cloning": false, 46 | "is_denied": false, 47 | "is_locked": false, 48 | "grade_accomplishment": false, 49 | "top_one_percent": false, 50 | "top_five_percent": false, 51 | "top_ten_percent": false, 52 | "is_completed": false, 53 | "is_ended": null, 54 | "for_credit": null, 55 | "micro_course": false, 56 | "standard_course": true, 57 | "program_for_credit": null, 58 | "prerequisite_courses": [], 59 | "is_private": false, 60 | "discount": null, 61 | "title": "Physics-Based Sound Synthesis for Games and Interactive Systems", 62 | "truncated_title": "Physics-Based Sound Synthesis for Games and Interactive Systems", 63 | "subtitle": "Stanford University", 64 | "extra_info": "RS 400", 65 | "url": "/courses/physics-based-sound-synthesis-for-games-and-interactive-systems-iv", 66 | "card_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/91/logo/thumb_image.jpg?Expires=1654066250&Signature=Mc771Gh3LU6S5vRFmz1jMpNSMt9NAMOpRqqcNZqsssRzMHPgiejPSB6hpCfheo5yvJVqVg17eYbGwuXyHyu5pRDo0R~rabIxKJqlbr74R0bB3Tg89UX1UyH8AUXHpQF9INrSpHSkDw4guBi3QxeOqfSj0s84QGLqWZUk7fRVjXYpl2xqrgs-vxqwAxV35Af52Tl2TKVyU2JJd~D7c9LnCV4FdlvBaLWlt-KFyJ71fCQ0f~bpFIVlf19ttfiGVUMcNsN0CNveW6YsNDE3hmVpX~Qq1P2IOM84634kivhzKATXQQfvOxanTzVDbaSwqVM1kh3nU6EFvWSGzWHxke4Y9Q__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 67 | "enrolled_student_count": 6856, 68 | "enrolled_student_count_floored": "6K+", 69 | "instructor_string": "Instructor", 70 | "default_instructor_image": false, 71 | "instructor_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/user/14/avatar/thumb_VampirePerry.jpg?Expires=1654066250&Signature=lk7eSr3HBixYvg8sB7LNdWohJqPt7VZuVttTne~ocN2EJCNBnuuP55OADbVlKfWmid0qAOF3dVZhmYI58SidV1CQTtlNPdoSTWLISXf~i~449h5SlAJAYNFTke9eVas7jeXMakQDB0ZBBjz8gavQgtiGKdpZcB0edNpnpVSUlOJcfbq2iWIXuRcA2wZv25hrvHpcsyOLpRGivUiv2ciWae0XzgM49IROcvCcGUWIzvTrKm2amvDFO3OZO4Hs2MenXTZwFG5IWhnmwK3mMoN8pz5INmdMSxOz8CdSNtd5XpZas~1m4LwqI1mSo7ZzHejqe6VKZCklzn6skhoFRfDtHQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 72 | "institution_logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/institution/2/logo/stanford_logo_red.svg?Expires=1654066250&Signature=DEJ4lNRYEScxjomSMDEuyC2R-2btPSTMRUi7RkFJRIa12HFL4A-9Lg15-Sob68fTVkccJiNu6k~DLYIAy58op3zOhl1yMPqLwCtNCFnIIy0Yk~JRE5y92o6PDwSAqo9gHgd2LeWceAAt8BvsXH9ChYEKqSTiVSAVs6jkw-LEhQW99ErSheXLhLCu1dX--kC1F14ra1scrUubsZ9B3lUoxnf7~dFG35KoTWu8eVKFTgLZ63jU-sMcQgv0z2PpVLWlpf7N0~Z~grU1GPKkLYqTmB7M71N-Gip3vT2Nse92PTDn-c3f22TGzqZKnSB81ydtACIHgThCmW0HHpzxogTq0w__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 73 | "full_stars": 0, 74 | "gray_stars": 5, 75 | "half_star": 0, 76 | "review_all_url": null, 77 | "total_reviews_count": " STUDENT RATING", 78 | "is_cohort_locked": false, 79 | "next_cohort_occurrence": "2022-06-07T23:00:00.000+02:00", 80 | "trigger_course_action": false, 81 | "logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/91/logo/thumb_image.jpg?Expires=1654852724&Signature=Pr4rM212pl7D6PqUlm36YMpgiggH1oIVNDQGEDK24gN1WOQO75AfZqplzDqpmZ2lcLxoj9kxuCQ~X~qsErIfKUQLI1IPso0iXxrSTSq7FXmqC2ChfQ34YWq39~gmcSYmr3wDVInxlamyjDcOd-s8LXhw1zWkaFm38KymnndGQ-Wy7NYWr1cTL7~qLDJTs47bwTTOWv4Kmw88WB~VJDQ94QxDjGsJiNlD~UW7GiUyNsU41LbgpBVTs1VYGPhMZh7Ltcv84C~trKDqGvg8XoLjNchddJlham0DmPuyKExi-8CnZsxwhZu9CQ-PdUaT20k7fK5KOKprVw16zeFkKXUfmA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 82 | "logo_retina": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/91/logo/thumb_image%402x.jpg?Expires=1654852724&Signature=HThMiM26qFzl4Ij4RuP7oizbuLcPFjz8ayQA-Bkq1zueMrqDGT9~M-K-DLSVRMFbBn248eFnc45zjw4CS37FIfz8qsWdHLeNsy4NObgt~l~ZipGkbPmvLfLk3qO5F1m8G5w67IpjTH6ChL2XeouqTdhjOD7-7t~JPmYyY18SEN~RFS0CqRq5OXeL0tj36E~ihg3BcN2Xi5LT38QvdX~R6-vXRLkMykP9oGRyqdfh4mdl-jhqipN3gnOfLh~L2f1zAec6az9onz00q59~7eixNdo77lMxlbgIxHCgJy5FQBl5p0mVRUet60j3~uE8gTPK-o4HRR~v1-K7CgDUuurivg__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 83 | "student_access_on_draft_course": null, 84 | "student_recently_enrolled": true, 85 | "current_user": { 86 | "is_student": true, 87 | "is_instructor": false, 88 | "is_admin": false, 89 | "is_enrolled": true, 90 | "is_for_credit": false, 91 | "is_pending": false, 92 | "is_invited": false, 93 | "is_archived": false, 94 | "is_completed": false, 95 | "is_locked": false, 96 | "is_program": false, 97 | "archived_at": "", 98 | "enroll_path": "/students/student/enroll/physics-based-sound-synthesis-for-games-and-interactive-systems-iv", 99 | "unenroll_path": "/students/student/unenroll/physics-based-sound-synthesis-for-games-and-interactive-systems-iv", 100 | "archive_path": "/courses/physics-based-sound-synthesis-for-games-and-interactive-systems-iv/archive", 101 | "clone_path": "/courses/new?copy_from=91" 102 | } 103 | }, 104 | { 105 | "id": 99, 106 | "number": "Goldsmiths", 107 | "name": "Machine Learning for Musicians and Artists", 108 | "institution_name": "Goldsmiths University of London", 109 | "restricted": false, 110 | "full_name": "Machine Learning for Musicians and Artists", 111 | "skill_level": "Intermediate", 112 | "instructors": [ 113 | { 114 | "id": 26, 115 | "full_name": "Rebecca Fiebrink", 116 | "abbr_name": "R. Fiebrink" 117 | }, 118 | { 119 | "id": 37809, 120 | "full_name": "Juhee Han", 121 | "abbr_name": "J. Han" 122 | } 123 | ], 124 | "first_instructor": "Rebecca Fiebrink", 125 | "instructor_names": "Rebecca Fiebrink", 126 | "instructors_count": 1, 127 | "guest_lecturer_text": "with special guests L. Sonami and B. Caramiaux", 128 | "in_program": false, 129 | "program_only": false, 130 | "term_id": null, 131 | "term_name": null, 132 | "description": "Have you ever wanted to build a new musical instrument that responded to your gestures by making sound? Or create live visuals to accompany a dancer? Or create an interactive art installation that reacts to the movements or actions of an audience? If so, take this course!
\nIn this course, students will learn fundamental machine learning techniques that can be used to make sense of human gesture, musical audio, and other real-time data. The focus will be on learning about algorithms, software…
", 133 | "start_date": "10/18/2016", 134 | "end_date": "", 135 | "date_range": "Open for Enrollment", 136 | "time_status": "Active", 137 | "course_info_path": "/courses/machine-learning-for-musicians-and-artists-v/info", 138 | "course_share_url": "https://www.kadenze.com/courses/machine-learning-for-musicians-and-artists-v/info?utm_campaign=course_card_share&utm_content=course_id%3D99&utm_medium=share&utm_source=kadenze", 139 | "course_path": "/courses/machine-learning-for-musicians-and-artists-v", 140 | "gallery_path": "/courses/machine-learning-for-musicians-and-artists-v/gallery", 141 | "profile_path": "/users/26", 142 | "is_draft": false, 143 | "is_pending": false, 144 | "is_active": true, 145 | "is_upcoming": false, 146 | "is_cloning": false, 147 | "is_denied": false, 148 | "is_locked": false, 149 | "grade_accomplishment": false, 150 | "top_one_percent": false, 151 | "top_five_percent": false, 152 | "top_ten_percent": false, 153 | "is_completed": false, 154 | "is_ended": null, 155 | "for_credit": null, 156 | "micro_course": false, 157 | "standard_course": true, 158 | "program_for_credit": null, 159 | "prerequisite_courses": [], 160 | "is_private": false, 161 | "discount": null, 162 | "title": "Machine Learning for Musicians and Artists", 163 | "truncated_title": "Machine Learning for Musicians and Artists", 164 | "subtitle": "Goldsmiths University of London", 165 | "extra_info": "Goldsmiths", 166 | "url": "/courses/machine-learning-for-musicians-and-artists-v", 167 | "card_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/99/logo/thumb_machinecard_mini.jpg?Expires=1654066250&Signature=Xhj~DVWU1DNkL6VfcsRr1acNhCOhSfZr89PB7yPjp0yNZ9haNbJ1HR4wU3wiIyVOtN3H1NCRc6-~ZW5oItql0hfniqeTu9gi5LMx4N~FQDDNcytQRtPfdmQsYSoQDiGAmYvdEsnRWglAgsbrvX~ceZBXXKbDXtX3W1MOpK-GMRaOcw-~mqxq3JCSPoS~RwdwLEArjS4tqQEToRnbQmcw5nCTFk67JPQuXHmnA3D6U~yKGjJEaKN2Wmju7MPRIvGkxDsXuWBbp-eheF9RJxt8BSLxB43dBFlYdt~pU8p4UGdBfkT9DO4IflgWeR9mUa~d1LJdhAf-pMg~DASpSlv6eA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 168 | "enrolled_student_count": 17880, 169 | "enrolled_student_count_floored": "17K+", 170 | "instructor_string": "Instructor", 171 | "default_instructor_image": false, 172 | "instructor_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/user/26/avatar/thumb_FiebrinkPhoto3.jpg?Expires=1654066250&Signature=cgYB0KxKVpgXeaa99SmXgm2dDi1FZ3fznZirCyGy7nISnHMP2T~VlhIfZmYaDK07i1PdWE-S2r9Osx~me~DGxfAJO-2zVI-TwVVyFG5vbGaM3CbBzUwn6zR3pGOPOVXzNNu7FS0lKVxkyPvNkAasMQSC3XYOToA-u-P0HhvmItBNoLeDr~8HwlAxWQ~7BY2GvH7COhfxHtj45GUBjuZkR8zPnxzJuc3fOhd0~HRPHVp8gBM8pDyGTYBzkHwGS6Pbmo-SGKN1gOmDwM2PsNysYns2oCrC1L~EfRJgAww62CvHyAP2pgh7yYCtgUyU-6L~2awzzIrpQNZ~uaWGCFtRng__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 173 | "institution_logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/institution/9/logo/goldsmith_logo_black.svg?Expires=1654066250&Signature=iC4vN6cOGgyCnks-aE28Cxu4kCiUn1vDQFx4WE4TosceRM8xoLnjr9xmt9rGYHTXuZOgu14u4ffR9cbR5tqDHx7NwC4daFUPRtSV6BUob586HqOGJq7JoW-p0rXw1tfY4Elt~~1CBdbWCEpOPaw6mbbYDyINtJD31p2~JkgIRQF45SPqB2~YK8JkPGzgfulw4wMuVYilDzw3dMDWWm1-J9xvCoSjcxieN7rZpN69qCFfb-tovbsxqiXm1ECaVGIbd6sYvx64KkZf2hwHCKWc88mLrYcmjTsODwp4YAkpQmO4oikAM7Av60ODith5pFhtSMOrX0alcMccklbw4cbxsw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 174 | "full_stars": 0, 175 | "gray_stars": 5, 176 | "half_star": 0, 177 | "review_all_url": null, 178 | "total_reviews_count": " STUDENT RATING", 179 | "is_cohort_locked": false, 180 | "next_cohort_occurrence": "2022-06-07T19:00:00.000+02:00", 181 | "trigger_course_action": false, 182 | "logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/99/logo/thumb_machinecard_mini.jpg?Expires=1654852724&Signature=ST0T7xLpUn0YAhWEVJfxKUK2gX4AjN4cAwpDs3ubZkZbM0a~A8q0b4SOfnHkhIjZSERfQpg4RmZgNyIPK7as~odTTAzXXeZpfGi1Z6hVp4SVLBcIjA0Bvd9rYyrt8-X3CnVwz0LZmDhEfWjTs-UQWP8a2sS9wmex0G4bOyb9djjLGjRQwF-K8PyiEsI0StjZiaphdKC6tLl-xyyNbxDdHv51kVsjb23sKYM9kIpe1r4iIudGqPerIP0q4FgVCcaQ9GA5zymvdO6ZX~jiAC4QJuPTwU1Li2nCtOt~1Wxj-uKuJPCEtNj~XXkImFkq53llAJWqSKfhI1UrkbhzdEtzcQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 183 | "logo_retina": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/99/logo/thumb_machinecard_mini%402x.jpg?Expires=1654852724&Signature=ebyMawiXqSUiUGeMtskectptyD48vh2cbguJM3mshnWgSrpW-UFSeE1Jn80-H1HgLlWqpT5iHZXwg0H~g5sNNrCQrBZlQvOjt81fHDB6sD-DLphe1UsjHi8-CwAfGq7JgUdIN3270xeCGyQk7wIvIAieYKrAwbtf-mZ3jEVqa88AoAIeIJH-TUaGQg5JJl5ZBTel-3DT7rlDzTFv2Hr9fcbANXbwCrhD0XhTMFof-0tCqku0XNhqRje9zW6AugA-MpDqpZ3QZpHN9Xz-qKPI7ikaLO0RcwYY0uHQW-vwHnH5atZmqyxa4Pv9s-uigUAMrutMlWeNkD~IHSjjG0ZXew__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 184 | "student_access_on_draft_course": null, 185 | "student_recently_enrolled": true, 186 | "current_user": { 187 | "is_student": true, 188 | "is_instructor": false, 189 | "is_admin": false, 190 | "is_enrolled": true, 191 | "is_for_credit": false, 192 | "is_pending": false, 193 | "is_invited": false, 194 | "is_archived": false, 195 | "is_completed": false, 196 | "is_locked": false, 197 | "is_program": false, 198 | "archived_at": "", 199 | "enroll_path": "/students/student/enroll/machine-learning-for-musicians-and-artists-v", 200 | "unenroll_path": "/students/student/unenroll/machine-learning-for-musicians-and-artists-v", 201 | "archive_path": "/courses/machine-learning-for-musicians-and-artists-v/archive", 202 | "clone_path": "/courses/new?copy_from=99" 203 | } 204 | }, 205 | { 206 | "id": 100, 207 | "number": "P 500 ", 208 | "name": "Introduction to Programming for the Visual Arts with p5.js", 209 | "institution_name": "University of California, Los Angeles, Department of Arts", 210 | "restricted": false, 211 | "full_name": "Introduction to Programming for the Visual Arts with p5.js", 212 | "skill_level": "Beginner", 213 | "instructors": [ 214 | { 215 | "id": 39, 216 | "full_name": "Casey Reas", 217 | "abbr_name": "C. Reas" 218 | }, 219 | { 220 | "id": 40, 221 | "full_name": "Lauren McCarthy", 222 | "abbr_name": "L. McCarthy" 223 | }, 224 | { 225 | "id": 31, 226 | "full_name": "Chandler McWilliams", 227 | "abbr_name": "C. McWilliams" 228 | } 229 | ], 230 | "first_instructor": "Casey Reas", 231 | "instructor_names": "Casey Reas, Lauren McCarthy, and Chandler McWilliams", 232 | "instructors_count": 3, 233 | "guest_lecturer_text": "", 234 | "in_program": false, 235 | "program_only": false, 236 | "term_id": null, 237 | "term_name": null, 238 | "description": "This course is an introduction to writing code within the context of the visual arts. It asks two primary questions:
\nWhat is the potential of software within the visual arts?
\nAs a designer or artist, why would I want (or need) to write software?
Software influences all aspects of contemporary visual culture. Many established artists have integrated software into their process. Prominent architects and designers not only use software, they commission custom software to help them realize their…
", 239 | "start_date": "11/29/2016", 240 | "end_date": "", 241 | "date_range": "Open for Enrollment", 242 | "time_status": "Active", 243 | "course_info_path": "/courses/introduction-to-programming-for-the-visual-arts-with-p5-js-vi/info", 244 | "course_share_url": "https://www.kadenze.com/courses/introduction-to-programming-for-the-visual-arts-with-p5-js-vi/info?utm_campaign=course_card_share&utm_content=course_id%3D100&utm_medium=share&utm_source=kadenze", 245 | "course_path": "/courses/introduction-to-programming-for-the-visual-arts-with-p5-js-vi", 246 | "gallery_path": "/courses/introduction-to-programming-for-the-visual-arts-with-p5-js-vi/gallery", 247 | "profile_path": "/users/39", 248 | "is_draft": false, 249 | "is_pending": false, 250 | "is_active": true, 251 | "is_upcoming": false, 252 | "is_cloning": false, 253 | "is_denied": false, 254 | "is_locked": false, 255 | "grade_accomplishment": false, 256 | "top_one_percent": false, 257 | "top_five_percent": false, 258 | "top_ten_percent": false, 259 | "is_completed": false, 260 | "is_ended": null, 261 | "for_credit": null, 262 | "micro_course": false, 263 | "standard_course": true, 264 | "program_for_credit": null, 265 | "prerequisite_courses": [], 266 | "is_private": false, 267 | "discount": null, 268 | "title": "Introduction to Programming for the Visual Arts with p5.js", 269 | "truncated_title": "Introduction to Programming for the Visual Arts with p5.js", 270 | "subtitle": "University of California, Los Angeles, Department of Arts", 271 | "extra_info": "P 500 ", 272 | "url": "/courses/introduction-to-programming-for-the-visual-arts-with-p5-js-vi", 273 | "card_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/100/logo/thumb_p5js_coursecard__1_.jpg?Expires=1654066250&Signature=deCPajIkm-mRUSwvTUWKstVSRbIaHq8Z21wqQqBNkjOSVOJUdEJi8NGgk7m7Q2cykesZHemTayZbMt2DW-Hz-8dFScN1gKAfqFyH3x5MFkUvtrtR0xl~~SMt-6Cd9zFmiIpJlARt0w1uxayvsy~pKS4BkSwPqxB-~Kglp8oqmGU~WqXN4Pt9RJtJWijfTxCysYOJi~pzmw5-F0hm81g1zko6nRNeKxKzfmirnlrDSWp-I9ylEPvG4KgYCODhlX5OgVbpFNLCFiQ7wOPP29UhIcFaJwiI52YsC6495yFdbPvnI72CQowTQJbhN9g2nVdQZQ6ot7FJkX47QDYU1ldgqQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 274 | "enrolled_student_count": 13244, 275 | "enrolled_student_count_floored": "13K+", 276 | "instructor_string": "Instructor", 277 | "default_instructor_image": false, 278 | "instructor_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/user/39/avatar/thumb_casey.jpg?Expires=1654066250&Signature=liSMnkgNtEfdArzU~VqUn0JWKvjKV1C3fLdHKu8jHFmYI7Xhdw8qtDLGwv-EUKvwrrGWSIOyzrnQR2G54u7MJZ6~nw8AKTwUaU7sX-rV4jUstPkDeHWwP16xjbdR1sPa3uWAv8vOLNnhXGHjlaePWWJwwtlIDjxRGhpMZbF7JCXgfYOuk2UEQ15ypk5H-ktL9lcuh0NepQdvSjWfnKC6uhyeyPo0sO~JuMO05j5F68jmG~KU-J0a6EucBRO9mfydcdDqmupUe69zUJYNbKtLnj9qT4-Md0ntTx1hen7xb86Yw4LNd28PPZqHwW5T14Yjl9Y~eejmt9qjpiO1XW3rfw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 279 | "institution_logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/institution/10/logo/ucla_art_listing_primary_logo.svg?Expires=1654066250&Signature=HrqCzmANKgs0eN0bDTKOYOFi67fkSNxGm0~x3Ip7KkwxVoUb8YBmPqrPX9mREnGA3osIJ~Ec9vcCd8Eo30nehglmT9JX1AlS4FhfpCl3O4rWV36LIKgMZm3dbjl-E5Ux1zhPtFbCjwrXmg0M2xiuDyo0CkIX-YClaEgjIsFhaO4lvsrCPPNE4w~fHSYCcliLdQQnNsJvX1kk5rvCTqKGA~6wNrRattike6YatSml5BV4f4GVaMOdMuZdphi2cdbaos4NNzTtQaBgttJ6emcX5Qt-xRxFW5Id-1fhrQe6AbxQKQE9oV1VfpHrzKARrffWQZWruKz9UGiwM9wjk1lqKg__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 280 | "full_stars": 5, 281 | "gray_stars": 0, 282 | "half_star": 0, 283 | "review_all_url": "https://www.classcentral.com/course/kadenze-introduction-to-programming-for-the-visual-arts-with-p5-js-3770#reviews", 284 | "total_reviews_count": "10 STUDENT RATING", 285 | "is_cohort_locked": false, 286 | "next_cohort_occurrence": "2022-06-07T19:00:00.000+02:00", 287 | "trigger_course_action": false, 288 | "logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/100/logo/thumb_p5js_coursecard__1_.jpg?Expires=1654852724&Signature=eCOPuN3T74l1lGTW4mHCJx3Cz-AgRWbKijrR1yk4qtrBi9BRPttnvTYRgALcMdva2XXZdA2N8fdsYN-Ow4DHGdUVoo7z2Lvtwc8gjfMWWCgjdyFI6l6FwEJWeTzyTZJ2ednpvniUh2xDzyHeWFeEGcTTib7DpPPEcB3rLGob0Ca2uIQIbi8DVfh2i9SlHOMJunzS-W-JXrj6G7TXZTpv7qRLwbnkEEnTJuJOG9K3nC-fLhxo2NC6eYgfx-MAL2d9MAJxngpctHPpCUt~ygTbYirL6hD8jF78IcTVVX65xohbHnimSZGJqmk2eEg7Yka20~E1U~mStZtFEQYAAsHPCg__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 289 | "logo_retina": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/100/logo/thumb_p5js_coursecard__1_%402x.jpg?Expires=1654852724&Signature=Aufwj89yelRkbPt5TbvdJIXBxOvLH8Ff2R5cFy6Q1JecurP54NZrams~OuzQP~M~MM8ZAeEjR9pedzMoqzIdj2xiRAlgodkcXcVzyMi5vTx2qaAmUUsdCunpfw6NRFWjVJCrkUJsJe5VfjI1ECLSoYwK~3JOUfu3gBQUXFUAv~dQT4F9oEbGsDdXKRXjXWrjmh~v1NRfQBy-icumdtg6mmioLcYwTj4RZMJsz1CGj0OzIwz4~heVZBs9mETO9IuEToZyP6gzX3nxhTTI6lEKMe39JyNMDhGqpFHWDbVNovTJbw7q3q9pMJd~8~a5DUUlYW-Y6DKB3JkeIjv7ANazHA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 290 | "student_access_on_draft_course": null, 291 | "student_recently_enrolled": true, 292 | "current_user": { 293 | "is_student": true, 294 | "is_instructor": false, 295 | "is_admin": false, 296 | "is_enrolled": true, 297 | "is_for_credit": false, 298 | "is_pending": false, 299 | "is_invited": false, 300 | "is_archived": false, 301 | "is_completed": false, 302 | "is_locked": false, 303 | "is_program": false, 304 | "archived_at": "", 305 | "enroll_path": "/students/student/enroll/introduction-to-programming-for-the-visual-arts-with-p5-js-vi", 306 | "unenroll_path": "/students/student/unenroll/introduction-to-programming-for-the-visual-arts-with-p5-js-vi", 307 | "archive_path": "/courses/introduction-to-programming-for-the-visual-arts-with-p5-js-vi/archive", 308 | "clone_path": "/courses/new?copy_from=100" 309 | } 310 | }, 311 | { 312 | "id": 169, 313 | "number": "5", 314 | "name": "Real-Time Audio Signal Processing in Faust", 315 | "institution_name": "Stanford University", 316 | "restricted": false, 317 | "full_name": "Real-Time Audio Signal Processing in Faust", 318 | "skill_level": "Expert", 319 | "instructors": [ 320 | { 321 | "id": 12, 322 | "full_name": "Harmony Jiroudek", 323 | "abbr_name": "H. Jiroudek" 324 | }, 325 | { 326 | "id": 97602, 327 | "full_name": "Romain Michon", 328 | "abbr_name": "R. Michon" 329 | }, 330 | { 331 | "id": 63, 332 | "full_name": "Julius Smith", 333 | "abbr_name": "J. Smith" 334 | }, 335 | { 336 | "id": 97603, 337 | "full_name": "Yann Orlarey", 338 | "abbr_name": "Y. Orlarey" 339 | }, 340 | { 341 | "id": 30, 342 | "full_name": "Chris Chafe", 343 | "abbr_name": "C. Chafe" 344 | }, 345 | { 346 | "id": 80982, 347 | "full_name": "Jackie Aldern", 348 | "abbr_name": "J. Aldern" 349 | }, 350 | { 351 | "id": 70382, 352 | "full_name": "Richard Sheehan", 353 | "abbr_name": "R. Sheehan" 354 | } 355 | ], 356 | "first_instructor": "Romain Michon", 357 | "instructor_names": "Romain Michon, Yann Orlarey, Chris Chafe, and Julius Smith", 358 | "instructors_count": 4, 359 | "guest_lecturer_text": "", 360 | "in_program": false, 361 | "program_only": false, 362 | "term_id": null, 363 | "term_name": null, 364 | "description": "The Faust programming language provides a generic way to implement signal processing algorithms for sound synthesis and processing towards professional audio applications. Thanks to its architecture system, Faust can be used to generate a wide range of ready-to-use elements such as audio plug-ins (e.g., VST, AU, etc.), externals for other computer music environments (e.g., ChucK, Max/MSP, PD, CSOUND, SuperCollider, etc.), standalone applications, mobile apps, web apps, etc. Additionally, it is a…
", 365 | "start_date": "01/16/2019", 366 | "end_date": "", 367 | "date_range": "Open for Enrollment", 368 | "time_status": "Active", 369 | "course_info_path": "/courses/real-time-audio-signal-processing-in-faust/info", 370 | "course_share_url": "https://www.kadenze.com/courses/real-time-audio-signal-processing-in-faust/info?utm_campaign=course_card_share&utm_content=course_id%3D169&utm_medium=share&utm_source=kadenze", 371 | "course_path": "/courses/real-time-audio-signal-processing-in-faust", 372 | "gallery_path": "/courses/real-time-audio-signal-processing-in-faust/gallery", 373 | "profile_path": "/users/97602", 374 | "is_draft": false, 375 | "is_pending": false, 376 | "is_active": true, 377 | "is_upcoming": false, 378 | "is_cloning": false, 379 | "is_denied": false, 380 | "is_locked": false, 381 | "grade_accomplishment": false, 382 | "top_one_percent": false, 383 | "top_five_percent": false, 384 | "top_ten_percent": false, 385 | "is_completed": false, 386 | "is_ended": null, 387 | "for_credit": null, 388 | "micro_course": false, 389 | "standard_course": true, 390 | "program_for_credit": null, 391 | "prerequisite_courses": [], 392 | "is_private": false, 393 | "discount": null, 394 | "title": "Real-Time Audio Signal Processing in Faust", 395 | "truncated_title": "Real-Time Audio Signal Processing in Faust", 396 | "subtitle": "Stanford University", 397 | "extra_info": "5", 398 | "url": "/courses/real-time-audio-signal-processing-in-faust", 399 | "card_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/169/logo/thumb_kadenze_programs_course_card_template_Faust.jpg?Expires=1654066250&Signature=icl7HaYXaYQY-C1ws~Uxo31lpy2ptssbpfH-sYhQW1D4MACdgk1h-j3ZsBqKZ29agNTbtQcHdVoIMzhlZjv5F3bn0tJ19xwJjSBxawu0uFstzp7KHs-T9Wxz0Gi9m8Izjv4rGJxMdYp0vMpCyPwMQqkEN5Gk7Sxlybj3xafMPp5wy73Fg3FdXeitBr6pJne4bqfmDC678nkiSbYYoURXCaXrm3ycPlS4nPuA9SCJ1Ve14m3FFXCUZune-MIOv2sZa4AwK5dlfSEkkJmqXwyEUjj93OCv-40ZCuZjTOS--wUIApKzDRwgxvbNjJjkjverucV4N0DnqAjHH~JJUIOLag__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 400 | "enrolled_student_count": 3710, 401 | "enrolled_student_count_floored": "3K+", 402 | "instructor_string": "Instructor", 403 | "default_instructor_image": false, 404 | "instructor_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/user/97602/avatar/thumb_romainMichon.JPG?Expires=1654066250&Signature=kcVRupiThPVarNAwuhuxLDuXETi45CzMeKegvzpkT1req8YvlFbZROCS7vFMH~-Ul4D0Dza5wHRWwhyWMdLa7CdPo0VbVxIfAhXwU5Pid7PpuodXGbEU9UFa34Gbg-Aa11hcvFXkCyNiSecnr7eKCj9fHUjMh2BqGDIcgcvkMdP6ezQCCE2PZK7M17QbFK-hjV8M~0fcoNgTllx9c2ODLDVD4RLVz26~7q2Z2HtSO-1Fd0cLDlagOBDZZPBlzauXLEqgDkJu0ZNszJomuececuTGJfUoM0jrFyn5QYd9d4ssbaFrOXQQsWh~xJcF5uszgETqkBapqFaCY~9exCIdKg__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 405 | "institution_logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/institution/2/logo/stanford_logo_red.svg?Expires=1654066250&Signature=DEJ4lNRYEScxjomSMDEuyC2R-2btPSTMRUi7RkFJRIa12HFL4A-9Lg15-Sob68fTVkccJiNu6k~DLYIAy58op3zOhl1yMPqLwCtNCFnIIy0Yk~JRE5y92o6PDwSAqo9gHgd2LeWceAAt8BvsXH9ChYEKqSTiVSAVs6jkw-LEhQW99ErSheXLhLCu1dX--kC1F14ra1scrUubsZ9B3lUoxnf7~dFG35KoTWu8eVKFTgLZ63jU-sMcQgv0z2PpVLWlpf7N0~Z~grU1GPKkLYqTmB7M71N-Gip3vT2Nse92PTDn-c3f22TGzqZKnSB81ydtACIHgThCmW0HHpzxogTq0w__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 406 | "full_stars": 0, 407 | "gray_stars": 5, 408 | "half_star": 0, 409 | "review_all_url": null, 410 | "total_reviews_count": " STUDENT RATING", 411 | "is_cohort_locked": false, 412 | "next_cohort_occurrence": "2022-06-08T00:00:00.000+02:00", 413 | "trigger_course_action": false, 414 | "logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/169/logo/thumb_kadenze_programs_course_card_template_Faust.jpg?Expires=1654852724&Signature=jzJPfONY0keK-12niCPpMrW6YuG7pBU34m8FCR1p2OQdPk5fv6Ba-Z5FJOUrpJOHjbivPv6TXoKBK9GlX9DZINdGfU0TirunL6ftPo1pwnikmTmNGZrbi~NsbnRXKgSzjpAm3rGExhWVLoZcqDP5x733Z5fRHr8HfWFiMLfJRUFC1vW9adWyjTftXdn015IcNa9VtoD-x6PB6sX481os8gPPVqMvFajsc8L7yGsSLG1UDq3l1njtAQ-njgD7SSdfuhiTErc3KV86uAOAYXSBgp~lcFEnn1vEvNs5k3NcXvixcH4cddT9VRyU8kGzPXfwmq9mZdqBE3powMlHc5qnVw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 415 | "logo_retina": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/169/logo/thumb_kadenze_programs_course_card_template_Faust%402x.jpg?Expires=1654852724&Signature=Zbcy4ReqFbF8LHrMvTDppgYcmMUmd63PyR~EeJxkmflz5UV84eKLDG9VwjYbyCAP03BrWW1ZB0bScfrIEFujzLLwY6pk1eOAdierVc1ydic775-IErhUldDupjMOPHh1PIlnWHqi01dTPfLFCl27KkVxDcl1BID-TEvQRQEvoEXAZEK5dQfZKzczsZ~oRyEOEUb2qGSXVY7UQ~TFKDzdUm5NpeJPPZx5ets~1a~pMZkoUcsYxu4Iz1craG6GhIBb05L6Vt1UXfEj5onnUP0aGdbl7--chfsXaecuGd8mdEDamC5x8X0j8zBqbM5g2u6cR-7lXoCQorSEPJiAlObHeA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 416 | "student_access_on_draft_course": null, 417 | "student_recently_enrolled": true, 418 | "current_user": { 419 | "is_student": true, 420 | "is_instructor": false, 421 | "is_admin": false, 422 | "is_enrolled": true, 423 | "is_for_credit": false, 424 | "is_pending": false, 425 | "is_invited": false, 426 | "is_archived": false, 427 | "is_completed": false, 428 | "is_locked": false, 429 | "is_program": false, 430 | "archived_at": "", 431 | "enroll_path": "/students/student/enroll/real-time-audio-signal-processing-in-faust", 432 | "unenroll_path": "/students/student/unenroll/real-time-audio-signal-processing-in-faust", 433 | "archive_path": "/courses/real-time-audio-signal-processing-in-faust/archive", 434 | "clone_path": "/courses/new?copy_from=169" 435 | } 436 | }, 437 | { 438 | "id": 71, 439 | "number": "KA100", 440 | "name": "Creative Applications of Deep Learning with TensorFlow", 441 | "institution_name": "Kadenze Academy", 442 | "restricted": false, 443 | "full_name": "Creative Applications of Deep Learning with TensorFlow", 444 | "skill_level": "Intermediate", 445 | "instructors": [ 446 | { 447 | "id": 15614, 448 | "full_name": "Parag Mital", 449 | "abbr_name": "P. Mital" 450 | }, 451 | { 452 | "id": 42, 453 | "full_name": "Amanda Eno", 454 | "abbr_name": "A. Eno" 455 | } 456 | ], 457 | "first_instructor": "Parag Mital", 458 | "instructor_names": "Parag Mital", 459 | "instructors_count": 1, 460 | "guest_lecturer_text": "", 461 | "in_program": false, 462 | "program_only": false, 463 | "term_id": null, 464 | "term_name": null, 465 | "description": "This course introduces you to deep learning: the state-of-the-art approach to building artificial intelligence algorithms. We cover the basic components of deep learning, what it means, how it works, and develop code necessary to build various algorithms such as deep convolutional networks, variational autoencoders, generative adversarial networks, and recurrent neural networks. A major focus of this course will be to not only understand how to build the necessary components of these algorithms…
", 466 | "start_date": "07/22/2016", 467 | "end_date": "12/31/2016", 468 | "date_range": "", 469 | "time_status": "Ended", 470 | "course_info_path": "/courses/creative-applications-of-deep-learning-with-tensorflow-i/info", 471 | "course_share_url": "https://www.kadenze.com/courses/creative-applications-of-deep-learning-with-tensorflow-i/info?utm_campaign=course_card_share&utm_content=course_id%3D71&utm_medium=share&utm_source=kadenze", 472 | "course_path": "/courses/creative-applications-of-deep-learning-with-tensorflow-i", 473 | "gallery_path": "/courses/creative-applications-of-deep-learning-with-tensorflow-i/gallery", 474 | "profile_path": "/users/15614", 475 | "is_draft": false, 476 | "is_pending": false, 477 | "is_active": false, 478 | "is_upcoming": false, 479 | "is_cloning": false, 480 | "is_denied": false, 481 | "is_locked": false, 482 | "grade_accomplishment": false, 483 | "top_one_percent": false, 484 | "top_five_percent": false, 485 | "top_ten_percent": false, 486 | "is_completed": false, 487 | "is_ended": true, 488 | "for_credit": null, 489 | "micro_course": false, 490 | "standard_course": true, 491 | "program_for_credit": null, 492 | "prerequisite_courses": [], 493 | "is_private": false, 494 | "discount": null, 495 | "title": "Creative Applications of Deep Learning with TensorFlow", 496 | "truncated_title": "Creative Applications of Deep Learning with TensorFlow", 497 | "subtitle": "Kadenze Academy", 498 | "extra_info": "KA100", 499 | "url": "/courses/creative-applications-of-deep-learning-with-tensorflow-i", 500 | "card_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/71/logo/thumb_Tensorflow_CourseCard__1_.jpg?Expires=1654066255&Signature=fJ38vQ6XuFKDyhpJUAe-EdgrXgKukMWtk74D5Vda685ZWFrKqktANRuLVIZDRkCURuhB6i3eokQd0pxtT~ML~4zkPcBdz0ciiPteHpYdfu3-ZtMkDxpxQP4TH4cDGo-GjD3g4hkHpe3wQEzGMldfbmftCdIn1XPH4zZHt4yPQlqvwHYXyWo~61IblxLnBKi-MdZE3iyZFk~EHY~thC6yGJxgZPtWyIbT5-fgGxRIS4n2gKymMXz1N9Di8B4V7dsTAHcqJvvuIy3DyO-~a1Cmp64FDmxiayRqSaNk42fuE5Gq3oZcY0lsyb9UmtnS54OiBtoMuhBHGNX1ZEPVJb5Ecw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 501 | "enrolled_student_count": 5026, 502 | "enrolled_student_count_floored": "5K+", 503 | "instructor_string": "Instructor", 504 | "default_instructor_image": false, 505 | "instructor_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/user/15614/avatar/thumb_Screen_Shot_2016-04-07_at_10.23.19_AM.png?Expires=1654066255&Signature=Q8L8EiJlVIrOnaU8fk3um1DdRQrnfqLmGxKjMm~x6H4oJ84oRgCYPJ~6AQMGxzwrfWj7~h6LqA53AXCS9UJbyHiA2UQI5EwuGC7909EzJVWkYgwL8uMvvnVkKLgqY1eoz83QVxju4RB4mpdv-v7C2SEOvl71yjoqsentWSNJOXbo5NM1-RnULbRnfv5gN1ZZ7ttEbPk~g9-sVpC20vDa2KlACy5EJsnsjTxySQyX4K1--ILSb1j6Ps8C9ZHQQ8sU9qkCIH1Bzk-~kUaX2QGk2xNp6ohocrkihLscA6StvcJJDf3Yqw5Jse21q80Y8Z51G69Yn9af9OONY15WOF5G2Q__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 506 | "institution_logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/institution/43/logo/kadenze-academy-final-200pxBelow-2__1_.svg?Expires=1654066255&Signature=HSIpD1YtQOOw04RV0IE9DLqvmYLrDFy4NbCslH91iKqla6wdq5Tq3hLGkvJF0ySm5JQOIdh3AkXNSgC5dPxnN44VuFfiqPOp7ocPftOsVa2rV0rfZo4duVCu9Wc72TcEyVZydhI7H8auGuVOwOpNXa-MJVuxe3xBH1wB-5Dydyc3WeRWLyA~2Opb5W5SS9z~VK2flwxE3Rxqx9VspQnhEy6UeF~RmYSiezQYjwwbWbe5RvM8I250xBGZQtje5DZL8aN-RosF4h6dEqAzGiOTKasRkh4CcE6Zd1om9i97IsqQdRTjwf5xGGGPaOIf9nsYv9HvpLTguDE387PtLPPuGA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 507 | "full_stars": 0, 508 | "gray_stars": 5, 509 | "half_star": 0, 510 | "review_all_url": null, 511 | "total_reviews_count": " STUDENT RATING", 512 | "is_cohort_locked": false, 513 | "next_cohort_occurrence": null, 514 | "trigger_course_action": false, 515 | "logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/71/logo/thumb_Tensorflow_CourseCard__1_.jpg?Expires=1654852725&Signature=j2U0PIHfIwuAnsy~vO8mUMYKm~VxMSPz17aWVl80E03aRm68mQkbOqElWlBx1Pj-XjqJXWOmbP4o1-KWgmTaJtoJ3I1WaCPFv11o2QRbHViv1CUMDyiBI5KsUa5wMdpqM3eO9unZRvDJNv0dqc868T04Hr8zR6Fp5bjXgZIHhKNAeNFBHuHw2KcOz3yUX-x8OE~XhgyvP9iJtQLYW2wKCDp0S2CowpJVAs6FfHC-HqB~sDVtlwTBRuZ5WVnt6MUAych9qe8HFYnLULR5tlPl4MRwOZ8hxHsJPc2pMOTRpz5PPHa6dmQh3JCy5xhi5j3Z8q5TVEnh7yi~ZtapjGysCw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 516 | "logo_retina": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/71/logo/thumb_Tensorflow_CourseCard__1_%402x.jpg?Expires=1654852725&Signature=cbe9dcAbKGSR5u8ZTWVFvB5-Y3k7turPlK0Eqtn1vDgfNw5l0DqWaFcL8FJdX~pckxK1csorPb~4p63tSgWROjj6HYuFdoUGrb0XDmf~DGDNzlXPQLe2ZnMXh0Yy8EQb3Nx~MKPeqpLI7ucRCc8SVfP092xcp2pQ94mkkJUeX1zU5Hy~N-CpCSmB7DJ3UKcO-bZ1mM~uhb3lh2xEOUnXIo3ziiqne8LmHZAgsNZoFFLIIGuYJ2hi5g~KO0x-OSUFlJriSb--ylStZWOSkbcCX2p7k9rlooptV5iIUXrrm0dR5Y1ZEEccHGjaiO--Ls15sQafLYUPxVXmj60yEmnb9Q__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 517 | "student_access_on_draft_course": null, 518 | "student_recently_enrolled": false, 519 | "current_user": { 520 | "is_student": true, 521 | "is_instructor": false, 522 | "is_admin": false, 523 | "is_enrolled": true, 524 | "is_for_credit": false, 525 | "is_pending": false, 526 | "is_invited": false, 527 | "is_archived": false, 528 | "is_completed": false, 529 | "is_locked": false, 530 | "is_program": false, 531 | "archived_at": "", 532 | "enroll_path": "/students/student/enroll/creative-applications-of-deep-learning-with-tensorflow-i", 533 | "unenroll_path": "/students/student/unenroll/creative-applications-of-deep-learning-with-tensorflow-i", 534 | "archive_path": "/courses/creative-applications-of-deep-learning-with-tensorflow-i/archive", 535 | "clone_path": "/courses/new?copy_from=71" 536 | } 537 | }, 538 | { 539 | "id": 101, 540 | "number": "KA100", 541 | "name": "Creative Applications of Deep Learning with TensorFlow", 542 | "institution_name": "Kadenze Academy", 543 | "restricted": false, 544 | "full_name": "Creative Applications of Deep Learning with TensorFlow", 545 | "skill_level": "Intermediate", 546 | "instructors": [ 547 | { 548 | "id": 15614, 549 | "full_name": "Parag Mital", 550 | "abbr_name": "P. Mital" 551 | }, 552 | { 553 | "id": 12, 554 | "full_name": "Harmony Jiroudek", 555 | "abbr_name": "H. Jiroudek" 556 | }, 557 | { 558 | "id": 88, 559 | "full_name": "Ajay Kapur", 560 | "abbr_name": "A. Kapur" 561 | } 562 | ], 563 | "first_instructor": "Parag Mital", 564 | "instructor_names": "Parag Mital", 565 | "instructors_count": 1, 566 | "guest_lecturer_text": "", 567 | "in_program": false, 568 | "program_only": false, 569 | "term_id": null, 570 | "term_name": null, 571 | "description": "This first course in the two-part program, Creative Applications of Deep Learning with TensorFlow, introduces you to deep learning: the state-of-the-art approach to building artificial intelligence algorithms. We cover the basic components of deep learning, what it means, how it works, and develop code necessary to build various algorithms such as deep convolutional networks, variational autoencoders, generative adversarial networks, and recurrent neural networks.
A major focus of this course…
", 572 | "start_date": "10/25/2016", 573 | "end_date": "09/20/2019", 574 | "date_range": "", 575 | "time_status": "Ended", 576 | "course_info_path": "/courses/creative-applications-of-deep-learning-with-tensorflow-iv/info", 577 | "course_share_url": "https://www.kadenze.com/courses/creative-applications-of-deep-learning-with-tensorflow-iv/info?utm_campaign=course_card_share&utm_content=course_id%3D101&utm_medium=share&utm_source=kadenze", 578 | "course_path": "/courses/creative-applications-of-deep-learning-with-tensorflow-iv", 579 | "gallery_path": "/courses/creative-applications-of-deep-learning-with-tensorflow-iv/gallery", 580 | "profile_path": "/users/15614", 581 | "is_draft": false, 582 | "is_pending": false, 583 | "is_active": false, 584 | "is_upcoming": false, 585 | "is_cloning": false, 586 | "is_denied": false, 587 | "is_locked": false, 588 | "grade_accomplishment": false, 589 | "top_one_percent": false, 590 | "top_five_percent": false, 591 | "top_ten_percent": false, 592 | "is_completed": false, 593 | "is_ended": true, 594 | "for_credit": null, 595 | "micro_course": false, 596 | "standard_course": true, 597 | "program_for_credit": null, 598 | "prerequisite_courses": [], 599 | "is_private": false, 600 | "discount": null, 601 | "title": "Creative Applications of Deep Learning with TensorFlow", 602 | "truncated_title": "Creative Applications of Deep Learning with TensorFlow", 603 | "subtitle": "Kadenze Academy", 604 | "extra_info": "KA100", 605 | "url": "/courses/creative-applications-of-deep-learning-with-tensorflow-iv", 606 | "card_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/101/logo/thumb_Tensorflow_CourseCard__1_.jpg?Expires=1654066255&Signature=L09100w5S5n0gkjEFkS9mQWNr0u6VzUisjOrUJJ6~KbaYltQQz5SutqQsFFuO-uuyL343aDy78eEUysrpJOIa6NyrnMrmSNIFGl03uHYNmwGqSikh19TV6XvTYRtQeYOUSLwt6Wcrt6v4Z~K55Bs3EHbHcDbEndOGxx3AxnpImqufP19QVqTI87nj9slzcuxr28Eu48SGwh2xyxq77NtnvHQhzlQDN5eje-njd9y6k7dD4-fR85tEYw6XF~psSz1BRCEnqeCRFMVkSFRlOM7~txsahWO778LnFigAXQbYSVE7xuzKfQUNRxOARmxrs5jN-le33MCzZw7dOSS0oBMwg__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 607 | "enrolled_student_count": 31554, 608 | "enrolled_student_count_floored": "31K+", 609 | "instructor_string": "Instructor", 610 | "default_instructor_image": false, 611 | "instructor_image": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/user/15614/avatar/thumb_Screen_Shot_2016-04-07_at_10.23.19_AM.png?Expires=1654066255&Signature=Q8L8EiJlVIrOnaU8fk3um1DdRQrnfqLmGxKjMm~x6H4oJ84oRgCYPJ~6AQMGxzwrfWj7~h6LqA53AXCS9UJbyHiA2UQI5EwuGC7909EzJVWkYgwL8uMvvnVkKLgqY1eoz83QVxju4RB4mpdv-v7C2SEOvl71yjoqsentWSNJOXbo5NM1-RnULbRnfv5gN1ZZ7ttEbPk~g9-sVpC20vDa2KlACy5EJsnsjTxySQyX4K1--ILSb1j6Ps8C9ZHQQ8sU9qkCIH1Bzk-~kUaX2QGk2xNp6ohocrkihLscA6StvcJJDf3Yqw5Jse21q80Y8Z51G69Yn9af9OONY15WOF5G2Q__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 612 | "institution_logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/institution/43/logo/kadenze-academy-final-200pxBelow-2__1_.svg?Expires=1654066255&Signature=HSIpD1YtQOOw04RV0IE9DLqvmYLrDFy4NbCslH91iKqla6wdq5Tq3hLGkvJF0ySm5JQOIdh3AkXNSgC5dPxnN44VuFfiqPOp7ocPftOsVa2rV0rfZo4duVCu9Wc72TcEyVZydhI7H8auGuVOwOpNXa-MJVuxe3xBH1wB-5Dydyc3WeRWLyA~2Opb5W5SS9z~VK2flwxE3Rxqx9VspQnhEy6UeF~RmYSiezQYjwwbWbe5RvM8I250xBGZQtje5DZL8aN-RosF4h6dEqAzGiOTKasRkh4CcE6Zd1om9i97IsqQdRTjwf5xGGGPaOIf9nsYv9HvpLTguDE387PtLPPuGA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 613 | "full_stars": 0, 614 | "gray_stars": 5, 615 | "half_star": 0, 616 | "review_all_url": null, 617 | "total_reviews_count": " STUDENT RATING", 618 | "is_cohort_locked": false, 619 | "next_cohort_occurrence": null, 620 | "trigger_course_action": false, 621 | "logo": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/101/logo/thumb_Tensorflow_CourseCard__1_.jpg?Expires=1654852725&Signature=CxY2hYVea2pIVyl5Lew2hdoPlIIcQOPlLAsKeIYAFrVbXlra4MqNw2Jqc6SzA5sekOaOJOVoHF8eAnaTj6FVr1Us4jDZ7noUWmgDNvCsCUmgemt58Ww598Ej3hyRwDkcAhP1jHx8k~s7XqaLodmHsUsncIH5L-ilpnkjl07H4hBWi2Dl5IVIgbZA1PAt0ineJOePFtUcscxYe1LgJFyqR4h1QD61Bi4bvrZ~1-gyjzdl1pnXcLluSmLvLxe8YewUcvFZGDxnCCYlsbKpKvQYVsLjS5SKWdSUQAHzsDH9gzgDDZDwmFVXhDCPT~jPrvuCdUyaTTwuQCgW8cqAr2bxjw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 622 | "logo_retina": "https://prod-uploads-pub.useast1.kadenze.com/prod/usr/uploads/course/101/logo/thumb_Tensorflow_CourseCard__1_%402x.jpg?Expires=1654852725&Signature=UYlDIkkFT5Lp7XAnTQkmI5U3pqyIXlJ5-6Yy8xXUUmUOeE3XiB1NRqWozgIAYKFSJOU5Psby7AvPVyvjeBFXDp-3LcA-1b6ZOFrR2p00lG5YM-CBN3bIe8RXg8WCPC4ZBvMQDbZZ7HG0LmfOC6XsC7rrspY4kHLwuy3zY0q2tR~X4MUROfv9WiUZK2aqi2VPfYHSTlyvCQ1qcFLl3s5yLzIJw640SC-kV9OemnlYldBq3sJfsl0~yQlaeHfzy3U6v9u-ZZ9BZVFu-cDH5jtGC~wXHUynJ0nD26UwoPZ7KZcM34mQ~GrsSC8Rl-maUoXnS0TS-XFtPbCgz7tBtngGbg__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 623 | "student_access_on_draft_course": null, 624 | "student_recently_enrolled": false, 625 | "current_user": { 626 | "is_student": true, 627 | "is_instructor": false, 628 | "is_admin": false, 629 | "is_enrolled": true, 630 | "is_for_credit": false, 631 | "is_pending": false, 632 | "is_invited": false, 633 | "is_archived": false, 634 | "is_completed": false, 635 | "is_locked": false, 636 | "is_program": false, 637 | "archived_at": "", 638 | "enroll_path": "/students/student/enroll/creative-applications-of-deep-learning-with-tensorflow-iv", 639 | "unenroll_path": "/students/student/unenroll/creative-applications-of-deep-learning-with-tensorflow-iv", 640 | "archive_path": "/courses/creative-applications-of-deep-learning-with-tensorflow-iv/archive", 641 | "clone_path": "/courses/new?copy_from=101" 642 | } 643 | } 644 | ] 645 | } -------------------------------------------------------------------------------- /kadenze_dl/tests/data/video_json.json: -------------------------------------------------------------------------------- 1 | { 2 | "videos": [ 3 | { 4 | "id": 8294, 5 | "lecture_id": 1005, 6 | "media_src": { 7 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8294/file/Faust_C1_S1.1_V2.mov?Expires=1654854872&Signature=kqthI3ziT~hZ6n3xFD6y5MaZjHsRrTa9dpvNgRT2DSAqbNUbMw3DOn5BEaEqaOM0lt4TbytryaWjAjI1NlPBBw9dtmhzGQF2Gg6P-0~WFKm~mZ3D5Ml7VHvoS8gWbzJoUoK8l6EQ7GrpSanzPsIth2Zfivn85FyCJ4ma0YUXm183bolDuENKTGhugUbi1qEbHOwbarq4L4Wlnj8EFimZ8g47uBKtyWxkiQoCN2sHN62mzJljmR1O9fGEFRAoSMOg9erb8YyPAKBTzFNF1sl9WhmKmtR6UvxlBpLtFiYR3q6aFwcqnpJjAMXCMyV1OOYqJPt2169gq5e~i3vGm-ngyw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 8 | "thumb": { 9 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8294/file/thumb_Faust_C1_S1.1_V2.jpg?Expires=1654854872&Signature=OWXLTcNgg~HfXAzz0SuBVqQBLp9nEQeYlH7WbTxoWTNs7-kMVnMFatoCaSdb7R1f8nEzwSgC3tusetn~WT64BxcHVJKWlBfQUbXhi3qCsQov4~zpgAgocJPra~54r4IOza0sRzgUcEm1Ke1x27VNfUgetTAsvr9ad5b9a0R8-FWMMDEo3iqMnL1UMjlxpR-68dCR0z1Vtk9DWxlw9MAI3MrT0TtRyYIpoBgRupFzFPeam0bbyHWGQsk0UjiMCYoAHXmWDsVrUFnelWJrzt3VEJ5P-hT~dW4ccs08mVBBnzM5q9bZstMoU3bMUfC0AyRc8Bh88igxkDiaMnlidT51Lw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 10 | } 11 | }, 12 | "media_src_tmp": null, 13 | "media_type": "video/quicktime", 14 | "created_at": "2019-01-14T22:16:50.207+01:00", 15 | "updated_at": "2022-06-03T07:54:37.119+02:00", 16 | "order": 1, 17 | "screenshot": { 18 | "url": null, 19 | "retina": { 20 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 21 | }, 22 | "thumb": { 23 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 24 | }, 25 | "retina_thumb": { 26 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 27 | }, 28 | "cinema": { 29 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 30 | } 31 | }, 32 | "duration": "130.09", 33 | "size": 85104017, 34 | "title": "Introduction", 35 | "completed": false, 36 | "progress": "0.0", 37 | "type": "NativeMedia", 38 | "h264_360_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8294/file/Faust_C1_S1.1_V2_360.mp4?Expires=1654854871&Signature=PjeYsixLHI802my4v4tfmUSxielYzwKFYLQ1jsXZbxu2pftNhdTK-JJ1sCzR5UqQfsaMhEDdN4uYR1~1kHXq8psdPMLPYFRco3HWG-HV2jkdydv1T5K1CzNDgwsyXXbc4hAVx4vJbqPfJTTyM5-Cwz9ac8kZ7Qal1CIIBHty-cKIfxFzDZZYrmmX9XGJk-6aPlfkqiJC250sfhfSrnoRfLsNEazQzbFQie4OS7kU1fH3cnDfIq3EjfzlfYyHlnyjB9xWH5aJ8JEbhfYMi3u4GEDtxAtsVeof5UDzf3~lRnMe5KLUwTJHPhwCwmiCK67z5R9feY1Ak7crcqNAutw3IQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 39 | "h264_720_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8294/file/Faust_C1_S1.1_V2_1080_2700k.mp4?Expires=1654854871&Signature=QvB8F~I6Lijs9ll1midQhBawperY~dgvsg1hccHg0I4nhN53~Q1xX25gWuNKEcZEBNLY4ldloUSyaEGDRE5y82W886p0JA5QDIuw4-H3jkIaAAIXZO5CgiSYauxf0r7nbiQvNDja5r9ydUdPatBuLnatEY0ZUf~-7YoO5~ljt-KrPEUpiSER2cPdodXgjfrRJs96dX~KD~YsUOGD~u6mop6IShnZyU6tjB7NNlZhoZIUIxHHV7bWVysmN38tPdQJdfkOmoq1IdV61tMjRHidagAqRYgKo7Ad8DpVIpQvjHEGpwlrJaUQ0IRuAqFeOmVsr3GIjf9Rgd8nMySeV~2ZAw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 40 | "transcode_status": "completed", 41 | "transcode_error_message": null, 42 | "user_state_data": {}, 43 | "accessible": true, 44 | "premium_only": false, 45 | "downloadable": true, 46 | "subtitles": [ 47 | { 48 | "id": 16592, 49 | "src_file": { 50 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/subtitle/16592/src_file/subtitles-en.vtt?Expires=1654854872&Signature=Y1qbdQyt187TAJoUv971ivprA2~LVQkomyBMCnijbdyD4OXglRTGSRs6Lo5UJXdUrKOAVhgyJ9JYeN4dYaYuA8s-p~Thx0bSvfI8AQTWfNcZ2dk47nNAPovmW-V9SXSUvOQLBCprooE06ca4amDTr7MpKkMbs-GM4kB9u8Sta3NS2pfhT5H2fmp8pgqiq6KDLtPVnSz0QNxgG2mnvqI9KtDGhN8bT-mmsbE9NTDW77zF1AwOTs~1Q2u7fDaUGxQLO~vWW~F1lXbeddtDoBaojppjTTfejDqmk0jAoDYOMFBRKA5Ot8t6NmWYGveVaOmZEQhlHnSeaMu95xswubsvAw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 51 | }, 52 | "srclang": "en", 53 | "label": "English", 54 | "subtitleable_id": 8294, 55 | "created_at": "2019-01-15T05:37:54.799+01:00", 56 | "updated_at": "2019-01-15T05:37:54.799+01:00", 57 | "subtitleable_type": "LectureMedium" 58 | } 59 | ], 60 | "is_transcoding_completed": true, 61 | "is_transcoding_error": false, 62 | "is_transcoding_processing": false, 63 | "media_cues": [] 64 | }, 65 | { 66 | "id": 8302, 67 | "lecture_id": 1005, 68 | "media_src": { 69 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8302/file/Faust_C1_S1.2_V2.mov?Expires=1654854872&Signature=j5pwiYfzJQbdD94fa0~9idige9TdFDreegTCMaODTOvyHv3MMaEotaHlVqRW1ecFfbJp6e2xEkKR2OXry~bDE0ruPwxbPWQQT-IAVj-7wto-vYxCvRJGo2IBpw0V8LQBcZae9TtbOSb~qRZcPA6hz8yr0qE7D1WgUXt5YS86uxJgBoNW~BTOCURUApS5dklWLh6Iqpxt1qBqwJApwJAtIzlMzY3MNpC8IPiZi9AoY8SlzRUwxwYZPh6UKrBn~g5oi3FBfZuIE66U1lUo98~hCq4n4HoM~pBT5rSYgF3h0VHaCoLCbEi9huQTFAyKYHZDPz2OvgGAiLSsKBWtinx1NQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 70 | "thumb": { 71 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8302/file/thumb_Faust_C1_S1.2_V2.jpg?Expires=1654854872&Signature=lToGpCBwbBe4cCrA1HWO0RY1IlyQtBwqB~P3IoZ-tTTdsDL9wjAdRQpgdDQkxbcdgMP9sKANEyL~KgYL7e8-xXkUPD1w5qgGjLpY2f4kusugYivh6BR2Wb996UEBgFrkJnBstVxpUmksS0EPNZX9~YB8lpK0VFuUFHGM2SVHq3GxS8TbTwPcqTAkcYg0tnD1R-bCp6nTALxyT6vaQ-ZLZRXyeqfZEr1wEhdLGK8RjRCtvDY-ixPLUfkQfAveikBqZ1ZP1gijLjLsPXA8NbaVgzMjpme~-bKpAfLCk-IsAytrDfWUwa6GUXW-rm-xL4gJ8kvjUgUX0slL-ZPQgXMZzw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 72 | } 73 | }, 74 | "media_src_tmp": null, 75 | "media_type": "video/quicktime", 76 | "created_at": "2019-01-14T22:24:16.603+01:00", 77 | "updated_at": "2022-06-03T08:00:19.570+02:00", 78 | "order": 2, 79 | "screenshot": { 80 | "url": null, 81 | "retina": { 82 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 83 | }, 84 | "thumb": { 85 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 86 | }, 87 | "retina_thumb": { 88 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 89 | }, 90 | "cinema": { 91 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 92 | } 93 | }, 94 | "duration": "206.33", 95 | "size": 91018588, 96 | "title": "Faust Online Editor", 97 | "completed": false, 98 | "progress": "0.0", 99 | "type": "NativeMedia", 100 | "h264_360_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8302/file/Faust_C1_S1.2_V2_360.mp4?Expires=1654854871&Signature=XdsGAe6eFVHKK67FVucMnSMFx-N03uUJKpVBN~V4ll7yBi08JefkPgM8S-oLxSCKY5jq5rslONBFT3lmBHiVqkDxOD3avMDR~XhkwCF8kAafD9nVwWgj8-QssW51JwGtaEW-6Pm0Z2MEhJjGm1uFQLpOv4FN1GV5f17MxmrZO3OFrC4D2MNWyQXnChlw~C7LDG9Gc3bxr2qe1EL3dTD4rY~XhhDmDl1dESHU31hu8nvJa0RyUwK4GXvuu3ZqCsOfqXgxiBw2M2K-dJCVinJAc4uEYK3-tyuJNPQE842Lka9gSl0xjeS0jGbBeqRD8S0IORHO4bgQR9p1fNNaEy5guA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 101 | "h264_720_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8302/file/Faust_C1_S1.2_V2_1080_2700k.mp4?Expires=1654854871&Signature=G7fd42Kq3fsPEGoPWYAno9MDol1BUO9XszZZkevQIsczdKG0UgTAcRTLFqigcaplUsPRQSnpuf~1f5h~E-ouOjOQRnGk5sWi65AMcoIRM7jrGQqdXVk9eVstg~Ckqshr772v5qYoK8HFV6p~YDcB3N1I0gVT~1n~8uANneaxi9-SPsOvYXZu6kpMLi401~tIuIgN8I6VSuVC8RZa0kWnHsEu-AO6Or3ntaR5UVGGFypZNOQEt37ox36TJgs0jvMPHtwc3MnOIABdEBXp2YaLGp501RxHR-72fFraV2e6yWNxt6MIovFbJ29s1gTlWC4hBD8atprArNSyiMza25EN0Q__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 102 | "transcode_status": "completed", 103 | "transcode_error_message": null, 104 | "user_state_data": {}, 105 | "accessible": true, 106 | "premium_only": false, 107 | "downloadable": true, 108 | "subtitles": [ 109 | { 110 | "id": 16593, 111 | "src_file": { 112 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/subtitle/16593/src_file/subtitles-en.vtt?Expires=1654854872&Signature=g624HhXOAyvXa3AYER7r9kJomoB2kX3jgw9jZvS-k~0masQfJL8eniYMnm9v0b4LrYdN1zVyvbtFrrIo1hu9u29RuvnZw3anghIVjftBvJaxK9Wd7LdZGEA65WdZ0MLXsA3dVRZ42wAS173Zxppv9qaVbKuGe2NoEXEus1PsJnO9IkkK3TvGSum18VjxaiCzRZ4G-rcXs0oCvcxwGTtE7I3jPKs734IO6DzYXfCRLlEaIlkjeNZ8BgrFwUNbwUABuyb~5vdzt0ZiG22TkXdOIxy0ERaSbNG5vWeaWBcOVyq3ABkgFB6Z3NcnTOBeZnJ4Ptf4D~J9yNWa9Xc7XAkqDQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 113 | }, 114 | "srclang": "en", 115 | "label": "English", 116 | "subtitleable_id": 8302, 117 | "created_at": "2019-01-15T05:38:09.632+01:00", 118 | "updated_at": "2019-01-15T05:38:09.632+01:00", 119 | "subtitleable_type": "LectureMedium" 120 | } 121 | ], 122 | "is_transcoding_completed": true, 123 | "is_transcoding_error": false, 124 | "is_transcoding_processing": false, 125 | "media_cues": [ 126 | { 127 | "id": 470, 128 | "type": "MediaQuestion", 129 | "cue_start_time": "50.293", 130 | "cue_end_time": "-1.0", 131 | "cued": { 132 | "id": 10007, 133 | "coursework_id": null, 134 | "name": "WebAssembly: https://webassembly.org/WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for...", 135 | "gallery": false, 136 | "peer_review": false, 137 | "created_at": "2019-01-16T00:03:12.231+01:00", 138 | "updated_at": "2019-01-16T03:22:49.293+01:00", 139 | "required": false, 140 | "definition": [ 141 | { 142 | "attachment_ids": null, 143 | "attachments": null, 144 | "explaination": "", 145 | "question": "WebAssembly: https://webassembly.org/
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
Developer reference documentation for Wasm can be found on MDN's WebAssembly pages: https://developer.mozilla.org/fr/docs/Web/API/Web_Audio_API
", 146 | "options": [ 147 | { 148 | "answer": "Continue Watching", 149 | "selected": "true" 150 | } 151 | ], 152 | "multi_response": null, 153 | "grading_format": null, 154 | "_type": "MultipleChoiceField" 155 | } 156 | ], 157 | "_type": "MultipleChoiceField", 158 | "extra_credit": false, 159 | "autograde": null, 160 | "old_auto_grader_id": null, 161 | "order": null, 162 | "auto_grader_entry_point": null, 163 | "template_id": null, 164 | "editable": true, 165 | "auto_grader_version": null, 166 | "auto_grader_jsonapi_version": null, 167 | "auto_grader_id": null, 168 | "plagiarism_detection": false, 169 | "check_library_plagiarism": false, 170 | "student_plagiarism_visibility": false, 171 | "field_definition": [ 172 | { 173 | "attachment_ids": null, 174 | "attachments": null, 175 | "explaination": "", 176 | "question": "WebAssembly: https://webassembly.org/
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
Developer reference documentation for Wasm can be found on MDN's WebAssembly pages: https://developer.mozilla.org/fr/docs/Web/API/Web_Audio_API
", 177 | "options": [ 178 | { 179 | "answer": "Continue Watching", 180 | "selected": "true" 181 | } 182 | ], 183 | "multi_response": null, 184 | "grading_format": null, 185 | "_type": "MultipleChoiceField" 186 | } 187 | ] 188 | } 189 | }, 190 | { 191 | "id": 471, 192 | "type": "MediaQuestion", 193 | "cue_start_time": "71.533", 194 | "cue_end_time": "-1.0", 195 | "cued": { 196 | "id": 10008, 197 | "coursework_id": null, 198 | "name": "Woohoo! Open up the Faust Online Editor: https://faust.grame.fr/editor/", 199 | "gallery": false, 200 | "peer_review": false, 201 | "created_at": "2019-01-16T00:11:02.542+01:00", 202 | "updated_at": "2019-01-16T00:11:02.542+01:00", 203 | "required": false, 204 | "definition": [ 205 | { 206 | "attachment_ids": null, 207 | "attachments": null, 208 | "explaination": "", 209 | "question": "Woohoo! Open up the Faust Online Editor: https://faust.grame.fr/editor/
", 210 | "options": [ 211 | { 212 | "answer": "Continue Watching", 213 | "selected": "true" 214 | } 215 | ], 216 | "multi_response": null, 217 | "grading_format": null, 218 | "_type": "MultipleChoiceField" 219 | } 220 | ], 221 | "_type": "MultipleChoiceField", 222 | "extra_credit": false, 223 | "autograde": null, 224 | "old_auto_grader_id": null, 225 | "order": null, 226 | "auto_grader_entry_point": null, 227 | "template_id": null, 228 | "editable": true, 229 | "auto_grader_version": null, 230 | "auto_grader_jsonapi_version": null, 231 | "auto_grader_id": null, 232 | "plagiarism_detection": false, 233 | "check_library_plagiarism": false, 234 | "student_plagiarism_visibility": false, 235 | "field_definition": [ 236 | { 237 | "attachment_ids": null, 238 | "attachments": null, 239 | "explaination": "", 240 | "question": "Woohoo! Open up the Faust Online Editor: https://faust.grame.fr/editor/
", 241 | "options": [ 242 | { 243 | "answer": "Continue Watching", 244 | "selected": "true" 245 | } 246 | ], 247 | "multi_response": null, 248 | "grading_format": null, 249 | "_type": "MultipleChoiceField" 250 | } 251 | ] 252 | } 253 | }, 254 | { 255 | "id": 472, 256 | "type": "MediaQuestion", 257 | "cue_start_time": "83.07", 258 | "cue_end_time": "-1.0", 259 | "cued": { 260 | "id": 10009, 261 | "coursework_id": null, 262 | "name": "Subscribe to the faudiostream-users list, related to the usage of the FAUST language: Subscribe to the faudiostream-users list, related to the usage of the FAUST language: https://sourceforge.net/projects/faudiostream/lists/faudiostream-users", 274 | "options": [ 275 | { 276 | "answer": "Continue Watching", 277 | "selected": "true" 278 | } 279 | ], 280 | "multi_response": null, 281 | "grading_format": null, 282 | "_type": "MultipleChoiceField" 283 | } 284 | ], 285 | "_type": "MultipleChoiceField", 286 | "extra_credit": false, 287 | "autograde": null, 288 | "old_auto_grader_id": null, 289 | "order": null, 290 | "auto_grader_entry_point": null, 291 | "template_id": null, 292 | "editable": true, 293 | "auto_grader_version": null, 294 | "auto_grader_jsonapi_version": null, 295 | "auto_grader_id": null, 296 | "plagiarism_detection": false, 297 | "check_library_plagiarism": false, 298 | "student_plagiarism_visibility": false, 299 | "field_definition": [ 300 | { 301 | "attachment_ids": null, 302 | "attachments": null, 303 | "explaination": "", 304 | "question": "Subscribe to the faudiostream-users list, related to the usage of the FAUST language: https://sourceforge.net/projects/faudiostream/lists/faudiostream-users
", 305 | "options": [ 306 | { 307 | "answer": "Continue Watching", 308 | "selected": "true" 309 | } 310 | ], 311 | "multi_response": null, 312 | "grading_format": null, 313 | "_type": "MultipleChoiceField" 314 | } 315 | ] 316 | } 317 | } 318 | ] 319 | }, 320 | { 321 | "id": 8303, 322 | "lecture_id": 1005, 323 | "media_src": { 324 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8303/file/Faust_C1_S1.3_V2.mov?Expires=1654854872&Signature=l1E3ivJK78D5bJUQeKMumcTY4L6lQz2Qtrcwsbu7472cHz8p1lBdCb4f10E4vw3i7MqN17cO5VI7r2lNw-SnUTlyOn3QSmGchL7Yz21pTU8b7H2Ux-UyIQ6HLbtwxHJJ3AB5SB1QO3DQZG~xaXuwK~LEhVc~KJV2JnOJzvQbYqwUZTDHt259Ir6Brqf6OFtnokVCbx~aG1OJOwSwR6EkMdgm8Lb5HpNrUkv~10GBEbJ~F1mwDtTqA1vxXwORhQoCQVkZmXF~DpCsPOW9I7DIYMahjQPanNmW70sUxGGfhNmEjLFsMxKVfoVDJIRGQLNaeKDWLmjDwnBuhpivcqUolA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 325 | "thumb": { 326 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8303/file/thumb_Faust_C1_S1.3_V2.jpg?Expires=1654854872&Signature=k8cPBZVW2TpMdevlfdCFG2C3OS6oMKKW7J6bwMyUxlPThJuRXBjYW3K7BGRHcCGsicQERPWABNNijEEgsFzBCyj-LMBf2ig1y-UJrhSpZ8aZzGFjoquUxG8Dn2CT~LhLlzaQ-cuUuqaHLBvVRpy4UfQffk4WElIgptEBR2QjR-F2X8m8aLpCwdKrtqyAuRpptZW-hOlmJSyqKqNW96VAHaJL5hnS2bnTcg0scB6Bhkl8erSOIVIJExhVr6VKxvmFhDSpXA5RLd8l0u0UdhtaI9PpK4ZE4i42lkpQV4aQnMLk7QG9VUYYUOIhR0mGdUXkh5Pxz56iHCPntepRqoaWZg__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 327 | } 328 | }, 329 | "media_src_tmp": null, 330 | "media_type": "video/quicktime", 331 | "created_at": "2019-01-14T22:24:34.507+01:00", 332 | "updated_at": "2022-06-03T08:07:34.267+02:00", 333 | "order": 3, 334 | "screenshot": { 335 | "url": null, 336 | "retina": { 337 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 338 | }, 339 | "thumb": { 340 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 341 | }, 342 | "retina_thumb": { 343 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 344 | }, 345 | "cinema": { 346 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 347 | } 348 | }, 349 | "duration": "238.2", 350 | "size": 148500227, 351 | "title": "First Faust Program", 352 | "completed": false, 353 | "progress": "0.0", 354 | "type": "NativeMedia", 355 | "h264_360_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8303/file/Faust_C1_S1.3_V2_360.mp4?Expires=1654854871&Signature=inoQWP7vQ0d8oBrJZdbWpwHlqBgt6S2x2E3WpMp9M7O77ZzE3cVWFDyLtOjcn9BncDNpQhcNgbC74r3EiSXl2zyh3RuofZURYvGnH7hYNQWQOgckmw1oqoIk4H1yZDL-tEFrhk0Vxu3QZxUBqgqeON5k3JLbzoaxb9cUztDm3duAZ4EDVFFA39UzsR659CWjBK2WTVfMpv1XejdQz-heytDL9Wm0kOlL~1Ez6BjXOV5ySsD66V-3MS64lUKBYJrssXwiqxgDTvDgl3~FoiM14OHHDe7TvuA-eKkHRAPzKirVSXzaEItU7RJeYUGVSPlL9YJZ-fE001gLYenKK1MrdA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 356 | "h264_720_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8303/file/Faust_C1_S1.3_V2_1080_2700k.mp4?Expires=1654854871&Signature=GhV712XWKiN8WOAGWpee0-4o2CViexZ~W8GcHdRRBsK-mVViyLSKVJ-YGpk7SYYpt~JgZSKTZLX968DpHpsC3S54RvrC6TzVarGFIKp7pjgJVJLY0lorDISR8UErJIz60B58FbcgFDXqY2puWHpJzO5tBSvtOWM0DYVGDr2WxKgKkSOFZgNPO7nVB4ww5YKwgwTQ-TfrEr14T7R3DHuQnz~DEpXD77O8SwSzd0Tsy6djsFxvMukMEEPICYFFc4F9X6yQ1QZtrzi0hFiQ9o~QVC8~HYSm~AZ18RyES3nbzYxkR7qiI1c8Kxc4-o7aeHyQwZFq~nXWIIco1x-3wVe0uQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 357 | "transcode_status": "completed", 358 | "transcode_error_message": null, 359 | "user_state_data": {}, 360 | "accessible": true, 361 | "premium_only": false, 362 | "downloadable": true, 363 | "subtitles": [ 364 | { 365 | "id": 16594, 366 | "src_file": { 367 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/subtitle/16594/src_file/subtitles-en.vtt?Expires=1654854872&Signature=HQOFvXPNwtZ9O799nx692iPZQM0yiVSwsfcadXWMWZ5BQHfzUf2Zwj58-hgaLfqCISWgbWlgZg4OWJKnkaOEj6l2Asxi3ICd3EAVQB-SY87oM74q-~y8G95Gr-BFl6IiLKyYdQOJd-IQYr4Sl8Qm4pRgnOIy72SZYFBJKyg92y1gei-s7i1EjPzUyGwcUbioZwbg99rC857tl8kUfJkUA048xQA6EOhXvHPjKhlwqLwjcMRNn460saFMF3ZBRw5GXRZT~KbQryOaR5JNchZcra6ydZKWOusEp-eU~TCSzUS4W8wjmo~uRVjK~Q7PSCJoVCoW8zPo~~jSviiba174Jg__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 368 | }, 369 | "srclang": "en", 370 | "label": "English", 371 | "subtitleable_id": 8303, 372 | "created_at": "2019-01-15T05:38:25.027+01:00", 373 | "updated_at": "2019-01-15T05:38:25.027+01:00", 374 | "subtitleable_type": "LectureMedium" 375 | } 376 | ], 377 | "is_transcoding_completed": true, 378 | "is_transcoding_error": false, 379 | "is_transcoding_processing": false, 380 | "media_cues": [ 381 | { 382 | "id": 473, 383 | "type": "MediaQuestion", 384 | "cue_start_time": "237.798", 385 | "cue_end_time": "-1.0", 386 | "cued": { 387 | "id": 10010, 388 | "coursework_id": null, 389 | "name": "QUIZ: What happens when the semi-colon is removed?", 390 | "gallery": false, 391 | "peer_review": false, 392 | "created_at": "2019-01-16T00:34:55.363+01:00", 393 | "updated_at": "2019-01-16T00:34:55.363+01:00", 394 | "required": false, 395 | "definition": [ 396 | { 397 | "attachment_ids": null, 398 | "attachments": null, 399 | "explaination": "", 400 | "question": "QUIZ: What happens when the semi-colon is removed?
", 401 | "options": [ 402 | { 403 | "answer": "The program still works.", 404 | "selected": "false" 405 | }, 406 | { 407 | "answer": "A violet bunny appears on the screen. ", 408 | "selected": "false" 409 | }, 410 | { 411 | "answer": "An error message is prompted.", 412 | "selected": "true" 413 | } 414 | ], 415 | "multi_response": null, 416 | "grading_format": null, 417 | "_type": "MultipleChoiceField" 418 | } 419 | ], 420 | "_type": "MultipleChoiceField", 421 | "extra_credit": false, 422 | "autograde": null, 423 | "old_auto_grader_id": null, 424 | "order": null, 425 | "auto_grader_entry_point": null, 426 | "template_id": null, 427 | "editable": true, 428 | "auto_grader_version": null, 429 | "auto_grader_jsonapi_version": null, 430 | "auto_grader_id": null, 431 | "plagiarism_detection": false, 432 | "check_library_plagiarism": false, 433 | "student_plagiarism_visibility": false, 434 | "field_definition": [ 435 | { 436 | "attachment_ids": null, 437 | "attachments": null, 438 | "explaination": "", 439 | "question": "QUIZ: What happens when the semi-colon is removed?
", 440 | "options": [ 441 | { 442 | "answer": "The program still works.", 443 | "selected": "false" 444 | }, 445 | { 446 | "answer": "A violet bunny appears on the screen. ", 447 | "selected": "false" 448 | }, 449 | { 450 | "answer": "An error message is prompted.", 451 | "selected": "true" 452 | } 453 | ], 454 | "multi_response": null, 455 | "grading_format": null, 456 | "_type": "MultipleChoiceField" 457 | } 458 | ] 459 | } 460 | } 461 | ] 462 | }, 463 | { 464 | "id": 8301, 465 | "lecture_id": 1005, 466 | "media_src": { 467 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8301/file/Faust_C1_S1.4_V2.mov?Expires=1654854872&Signature=XzE9LMdS2Be2yjpkqIufCCyCBG62yCsmYzoqSE-XGcX1MamgNyqPlKMt~36UyJ6T6eJ5~rpTT8me7VJGAAMne~Ye7oDBhotQ873NNc2obTcvBMr2daTcTwz5Z4RxZi8avuU4QcXWU~3wlF70krqBqT~06YD7ErS1-FSCn26Hg5GJkFGvzDzB8QJRqc87lL1GjBOCu78M8D1k1VNl1q~xaWdLhfNnFieZCtNLj5xMR7kRmsNenJClPS1e4wfIr0gKTtsBx-co8FFj0sZfcqQ0NkH1ZSmjgXG7EnAF7nQiTU3-VGMhKUm27vEk7o4KfrfKfaf0qq4Gj60M103Cc1dnzQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 468 | "thumb": { 469 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8301/file/thumb_Faust_C1_S1.4_V2.jpg?Expires=1654854872&Signature=lcPOkkT~uCAUsOcTSYLQuJfDkWvkxrD1rIXoQLbE7uvBcsYr6XodBeEijqrrwR-G12MWfakKPE6hqu6JlTtq49m8vtte7qckmEVVe0LDRzNSVHeeZVR7cCtRdAn95ztFujAQDOElnewf5qn9rgKY2bEc2bo3JGJl8jH30CJTG-ODqCTzfpUdL3U7kd2-nyjhWFT5YeXJBg3cyr9D4RkwzVgjJJ2u2MHcpv81IT9N79H4OZBqqL88v3~UIcjT0EmFNYuphcesQbGnLZQwTiW5nPfgphZzIwnapVAGNe8iY1AUZtPBlx7lhtH0eIuxNRS-KQCtSMXxWVX8hZs8Nr5rRw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 470 | } 471 | }, 472 | "media_src_tmp": null, 473 | "media_type": "video/quicktime", 474 | "created_at": "2019-01-14T22:22:40.717+01:00", 475 | "updated_at": "2022-06-03T08:13:10.680+02:00", 476 | "order": 4, 477 | "screenshot": { 478 | "url": null, 479 | "retina": { 480 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 481 | }, 482 | "thumb": { 483 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 484 | }, 485 | "retina_thumb": { 486 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 487 | }, 488 | "cinema": { 489 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 490 | } 491 | }, 492 | "duration": "125.83", 493 | "size": 62431365, 494 | "title": "Adding a Reverb", 495 | "completed": false, 496 | "progress": "0.0", 497 | "type": "NativeMedia", 498 | "h264_360_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8301/file/Faust_C1_S1.4_V2_360.mp4?Expires=1654854871&Signature=Ysyl3QbWFx4M1HBsI8QHQ21gzAjmp8poV9bcmk-5czTLiKaLsmwUwOmMALdG2dADNdZzxjCcIZIdhdK6noJvXsSLlJMH6RyluiClJhRKZ8tg6BGXJHOEam3bBzUD4OGqVJo649V2ujGNvGVZl6uLHtUGymp4uEvrMnTK~yBU8bc~nF393MlgYVuHjl6mkoKlfmJyr4gSaMVsIl7qnqVy-BzsA3rro0p5Y4AGMdt1rD7AukSZCYHKR1DjZpYtHmMbvYGSfry19atQ8Aop8FXVmJvDX4jCtOQH4BQLuoi3VBD7P7ALja0a0MK4JbX3qa3vJitxncJeTf8wg1QPOeZucg__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 499 | "h264_720_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8301/file/Faust_C1_S1.4_V2_1080_2700k.mp4?Expires=1654854871&Signature=V9s4192pnfOckc1GzSvv1BS62kevfS6BQsnlYAo7If6SpHoN~viJKTiljHSsy6MdsSJxXE0DecmkOdG7Tk3wJkGi7-5zBe0dv90EjLfQ~QR-86cW3V6QcJ-iUXCzJ7h0cI7nnihm4x-Hu0P6dLbm-9MtstiayFpWjvPXhozipnSiivhTysoMX4-c384U76AkTn2btPafqkBS91dXrOdTWpfzkIaFNLQjDSdaQGbzFULQ3M2c~O-C8AMaQ2eTBgtCkwbEe3t5ApCuSNAgYEV9qInYCbl9YG8HY7XkXohd4wZptdR9mYvm4fxCRCxvyGmGyXofuLTC1KrB6y3I058F5Q__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 500 | "transcode_status": "completed", 501 | "transcode_error_message": null, 502 | "user_state_data": {}, 503 | "accessible": true, 504 | "premium_only": false, 505 | "downloadable": true, 506 | "subtitles": [ 507 | { 508 | "id": 16595, 509 | "src_file": { 510 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/subtitle/16595/src_file/subtitles-en.vtt?Expires=1654854872&Signature=JJmNFtvjjvWX9Kn4HgEgkqxD~fcznSajLA3BSu5AVAlh6LXvH21oCEn981IbkKUqCyLrkkAZE7-QiSRFgLTxTacNiyXE2zIvPho4Dm17id4CgVD2SNgd~3ha20gxqyZFKIll1krQMl74izmF2E1VXeXfzKXMl8ATWAwJ9yIQGlrMefZnexw9pWugXusnZDfUNzESEqIzpdWH-kwTGjLpu~seq5QB3OhBovRCQYpg3MIWVZzU2sGdHv0T3aROqrYoys40t9ZCFfv2F3wqFsxdNaXkKB~ofVFphqPuj4SCpsrbQFakAQSz0rgXQ4bBnhFg1ckzQfM1P39p2raXmlYlkw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 511 | }, 512 | "srclang": "en", 513 | "label": "English", 514 | "subtitleable_id": 8301, 515 | "created_at": "2019-01-15T05:38:39.555+01:00", 516 | "updated_at": "2019-01-15T05:38:39.555+01:00", 517 | "subtitleable_type": "LectureMedium" 518 | } 519 | ], 520 | "is_transcoding_completed": true, 521 | "is_transcoding_error": false, 522 | "is_transcoding_processing": false, 523 | "media_cues": [ 524 | { 525 | "id": 474, 526 | "type": "MediaQuestion", 527 | "cue_start_time": "59.705", 528 | "cue_end_time": "-1.0", 529 | "cued": { 530 | "id": 10011, 531 | "coursework_id": null, 532 | "name": "QUIZ: Why are we getting this error message?", 533 | "gallery": false, 534 | "peer_review": false, 535 | "created_at": "2019-01-16T00:37:34.397+01:00", 536 | "updated_at": "2019-01-16T00:37:34.397+01:00", 537 | "required": false, 538 | "definition": [ 539 | { 540 | "attachment_ids": null, 541 | "attachments": null, 542 | "explaination": "", 543 | "question": "QUIZ: Why are we getting this error message?
", 544 | "options": [ 545 | { 546 | "answer": "The number of inputs of dm.freeverb_demo is not the same as the number of outputs of pm.djembe.", 547 | "selected": "true" 548 | }, 549 | { 550 | "answer": "You are never allowed to connect a djembe to a reverb.", 551 | "selected": "false" 552 | }, 553 | { 554 | "answer": "dm.freeverb_demo doesn't exist.", 555 | "selected": "false" 556 | } 557 | ], 558 | "multi_response": null, 559 | "grading_format": null, 560 | "_type": "MultipleChoiceField" 561 | } 562 | ], 563 | "_type": "MultipleChoiceField", 564 | "extra_credit": false, 565 | "autograde": null, 566 | "old_auto_grader_id": null, 567 | "order": null, 568 | "auto_grader_entry_point": null, 569 | "template_id": null, 570 | "editable": true, 571 | "auto_grader_version": null, 572 | "auto_grader_jsonapi_version": null, 573 | "auto_grader_id": null, 574 | "plagiarism_detection": false, 575 | "check_library_plagiarism": false, 576 | "student_plagiarism_visibility": false, 577 | "field_definition": [ 578 | { 579 | "attachment_ids": null, 580 | "attachments": null, 581 | "explaination": "", 582 | "question": "QUIZ: Why are we getting this error message?
", 583 | "options": [ 584 | { 585 | "answer": "The number of inputs of dm.freeverb_demo is not the same as the number of outputs of pm.djembe.", 586 | "selected": "true" 587 | }, 588 | { 589 | "answer": "You are never allowed to connect a djembe to a reverb.", 590 | "selected": "false" 591 | }, 592 | { 593 | "answer": "dm.freeverb_demo doesn't exist.", 594 | "selected": "false" 595 | } 596 | ], 597 | "multi_response": null, 598 | "grading_format": null, 599 | "_type": "MultipleChoiceField" 600 | } 601 | ] 602 | } 603 | } 604 | ] 605 | }, 606 | { 607 | "id": 8300, 608 | "lecture_id": 1005, 609 | "media_src": { 610 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8300/file/Faust_C1_S1.5_V2.mov?Expires=1654854872&Signature=BelrNHPd14sBJuNhsfISsoskOuVdjdW792yVRcj~jKBVmT~8lRYumVrZa4oqm2q1t-YvUTlMwg3d3UGjx69fxkY2OIhk7WPoHj3ZcJQvtQ8lLbZgBnFDvFoNQ3xA8lmedN2GtiAjP63XQEqVplqDB0oyEeXFeAHGmRAsURKXbJE0uzOYsbm92RC5SEYgoUrO2Rrmyfn15RoeRj2lXHo9Iuc3w6dZzm6ZjtFh~CZOFkF5xNo7puKCNaYBFEWemOtF3os0AvC8qzCHHytB1uRg-E5qgnjbIv~k5XaD8vdqwGsG~DkJd2U7KJ3BuvlBx8OE5QxMMNW0zHUJGcY0vatBXQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 611 | "thumb": { 612 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8300/file/thumb_Faust_C1_S1.5_V2.jpg?Expires=1654854872&Signature=UtDIk~L~JAGEqz~F0h0wyQJs8c09kyPjd8gOcYc-AdVf9P34qimXljRWtrtQ8RTksDKy38gFYKBrtGazg25DM5R3pyCUdy4lK-lXHFScQyAk6kD5DJeh3UwI-qi4rxpOppcv7MO8~eWnZbFpdbnqGhmnxLrZp4si7GuIoMa7eaCnf08C2CkSORLxDeNDG8twaGNe0v0yHL97WRYob5gzhN9r2DOI6rxUh0ahaCsCR99S6DURjEz6nr1S86tasMv2D5XApSgRbUwd1OeP1AeChyCXtP2iYRv8E~3CROdDDrqSMPovQ22fVywKbhT4yox8KPn7OTCjAZwKkeWSm54nrQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 613 | } 614 | }, 615 | "media_src_tmp": null, 616 | "media_type": "video/quicktime", 617 | "created_at": "2019-01-14T22:21:56.608+01:00", 618 | "updated_at": "2022-06-03T08:40:12.341+02:00", 619 | "order": 5, 620 | "screenshot": { 621 | "url": null, 622 | "retina": { 623 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 624 | }, 625 | "thumb": { 626 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 627 | }, 628 | "retina_thumb": { 629 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 630 | }, 631 | "cinema": { 632 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 633 | } 634 | }, 635 | "duration": "224.39", 636 | "size": 131895711, 637 | "title": "Automating, Triggering, and Generating a Mobile App", 638 | "completed": false, 639 | "progress": "0.0", 640 | "type": "NativeMedia", 641 | "h264_360_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8300/file/Faust_C1_S1.5_V2_360.mp4?Expires=1654854871&Signature=D3AjmRR9STKiDOYwcLvS~rFW8W3pkY0sAIfkNLwEaaveUrU0CAZmBLUn3fk1pTR949Cv2FniGqI1~q5xr1fCyos~x-3i7urY2AZ6BVmxAbEUA3TDuqFuaSQHAoAjArev~BPau2apeHcwER8uOiQUThdUDmIeQaxFqrQc9NwttVrMDQEzq1SgXYfQjoCib7lCuCVYZFvpBz6tRzEvFGyqq0HDzDhgWlM4Lm0qNH0Cj6wdU3x2vBprMWSbTfPNtnY57vpeqt1Z4NXzXPRzoDThx9br~zeTwj8sCFfaEePoYiOqIf5dvrz6xeuEtt7SP4aoDJQ4LoKtWiM-nb2Jlt3ZNw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 642 | "h264_720_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8300/file/Faust_C1_S1.5_V2_1080_2700k.mp4?Expires=1654854871&Signature=XfmNdn5j36DsiWU4c9DKLySUMXKh4jEXd8fbt25BwECOuOm~~smbx~XoOun-slWKq2SjsE~yyje9viSI26VsBnzA0KYAMlqYpQzG5eU09A~P1MnoHGqJ10w6eIkGnEei48KyM1DTUr62AdURL5cw9cfrEffts9om0PO9eaUeb6RIzyvfDrm0wB79NS6oWP~75uept6lsJc7hxY3aB5bWkI0UoB1unNsBsDI7bMWy7pZ8GMKeSML~a3c9l5BLP0Gqpf5jIyNYErs-1aEvVHv6PzIkgAd1dJBvVrmgLDnUDd3EpUDc6iJViudOJplRsZjhFTlUf8mAYd~hGInC6fNctA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 643 | "transcode_status": "completed", 644 | "transcode_error_message": null, 645 | "user_state_data": {}, 646 | "accessible": true, 647 | "premium_only": false, 648 | "downloadable": true, 649 | "subtitles": [ 650 | { 651 | "id": 16596, 652 | "src_file": { 653 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/subtitle/16596/src_file/subtitles-en.vtt?Expires=1654854872&Signature=g6wO7VIER2ubLyfH9lcMcSh9ojXVhpUmmmspvcj2ageFs1r1Z4lYeUdaUM7CxpckSJzyNVDLlib~KsmXjvLu8NlMVhGvH7SYFTVc6dVTcdf~HrSwwVBVm6gOSLfYeZQp80AWelpWJBqq6KcCZJEYkZpJFmCBOzfFF8-2p3O8vBYn8K-YKhof1uz-xY9U-nkplR48jAouTmmNHZSuyfyh2vEfUSCWAaVIlehaUwHZtpro2MNF6SngGn3UU6hjKMmMjGSE3cxiO6AcEnPkpTIcjsbG-~2QR7Tnezrq6I5iqhwKe8Ik-0VlPXA~AHcr0RpSNuYRC66R0EdbQe5ZRuYaXQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 654 | }, 655 | "srclang": "en", 656 | "label": "English", 657 | "subtitleable_id": 8300, 658 | "created_at": "2019-01-15T05:38:53.548+01:00", 659 | "updated_at": "2019-01-15T05:38:53.548+01:00", 660 | "subtitleable_type": "LectureMedium" 661 | } 662 | ], 663 | "is_transcoding_completed": true, 664 | "is_transcoding_error": false, 665 | "is_transcoding_processing": false, 666 | "media_cues": [] 667 | }, 668 | { 669 | "id": 8299, 670 | "lecture_id": 1005, 671 | "media_src": { 672 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8299/file/Faust_C1_S1.6_V2.mov?Expires=1654854872&Signature=KZluLvshBF7kYWYptVRwDbNgG8IBfVDOcfka5lMz9N4NXFzbXBio3LFg-~WtKnadnuSiTHVEt8RFoPiJ7CykbeQ80BcsNSMQmn~VWDEP86NHowdfRWCUpA6o0GTpwluexhC4gud-Mupthr1NOit~LP1aQ323i6xZCjwkttJdRDFz-PkJBmY4BHvDmNTn6hyPZ6-alOJx0Wu3oBfjZMuTZa1KN8mhvLjxOz8WqB4dUa8~Rca3tZ9546YC4RIf1IEZpTBgI1-Ihq4fwq0Fz3U9AuLA9yy697lbZqdO9VSw82q~YFYjQuFOCdOchr-YrHTgB6i8B8jgeLd2UqZDsvYcwA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 673 | "thumb": { 674 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8299/file/thumb_Faust_C1_S1.6_V2.jpg?Expires=1654854872&Signature=hLkmMx9WQrQJVqWl5I8O6l4qzLSe58VGj8hfcU-Sx5Re8-3oHGU3V3EDpuiUdLbHtoji5oxWAyirfIv-Ve8xa8RpEd3i6sJlBBpReuB1gho3kKDz~UO-0CCo62Kt4UHwtCZCQAf0FwRiB2RWv~BNZr5nZq21ooXAtIKoPnQvqohILke5WAp3tpSuaL2A9S0RaZ~PQmw6S~dCjGjjl1LF00IdeXAJZYjfV9bDtmf0tLsVXoKb1NqbXXmtSgRwdqEhbOvWTRkl13yII9Y6ZYXulA-MUZcQcodnpcUprE-pNIemj2nd2s2X7IH5YaI45vAqHq~T06FfPvhd-Uo~Dvb2DA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 675 | } 676 | }, 677 | "media_src_tmp": null, 678 | "media_type": "video/quicktime", 679 | "created_at": "2019-01-14T22:21:33.512+01:00", 680 | "updated_at": "2022-06-03T10:14:35.084+02:00", 681 | "order": 6, 682 | "screenshot": { 683 | "url": null, 684 | "retina": { 685 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 686 | }, 687 | "thumb": { 688 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 689 | }, 690 | "retina_thumb": { 691 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 692 | }, 693 | "cinema": { 694 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 695 | } 696 | }, 697 | "duration": "179.64", 698 | "size": 112376238, 699 | "title": "Using a Sawtooth Oscillator", 700 | "completed": false, 701 | "progress": "0.0", 702 | "type": "NativeMedia", 703 | "h264_360_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8299/file/Faust_C1_S1.6_V2_360.mp4?Expires=1654854871&Signature=K9Dq5F6ecKN40Htmn5Ed6rnBHaLQ-ilIvdfXwr5ccZuPRcfmY-X1IAg4wK~GgfRjHHtlWayxZ-V9w1cg~4Fk08VXBYKTA0knMA3xikAsxPaDP9ihmXMFtRTevp-EfokGi0hC5OE63u4fz7zNkEgeMMtNC9D~Q4pNA4GPrPV2xOt-sug0sLoS9-bs0EjgZDUNB6gXFFEpI41wie1C-Jjt62g51blAKZIYrVlhSBN2PkK-DpiztsW4S1tFqKkhce3rqsOMtu6cmovRGmlZMEx5CbO8XKNz0SOu1~w32Bd1MuXFW3XPd6VQGv0xvxujKBQe3OHTXm5O2SofZi75P0OLsA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 704 | "h264_720_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8299/file/Faust_C1_S1.6_V2_1080_2700k.mp4?Expires=1654854871&Signature=FGHzzNJMJeflQE43Z6bPTzRQ9SRQfw2MF6wim03U7B6noI1vb9A35kTowpmZQlmCbnYe~RKt35~NI3~NBU74QyJ95JFuOVf2N62V99qccmyhdr~05z05o2f6Z9ktoCU3yW5M-kDUadcEBiGwol4k~EWfFm-jACIeEkje8Hwi5yp~eBjXUEteA1OZYSuxdodH0HHJGbmo3t8XjQMM5Drkp4MLQ9xx~s7UgddfJQ4dMYCbBLrV7eduQQzx46i-dOf6F1UEVahwP5B3UMRKV3W4Yr8PayLnPfW5EHlTkPJxasg5NeAuaadA5wDpEMhlCtCI47l3iqXM1QFJa6Vn0SmNzw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 705 | "transcode_status": "completed", 706 | "transcode_error_message": null, 707 | "user_state_data": {}, 708 | "accessible": true, 709 | "premium_only": false, 710 | "downloadable": true, 711 | "subtitles": [ 712 | { 713 | "id": 16597, 714 | "src_file": { 715 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/subtitle/16597/src_file/subtitles-en.vtt?Expires=1654854872&Signature=IZYlRJU7BzNxCJNoT5t00sFqB~MjILUqEtAODRK52eDsYTylthom6Jk2rcW7OjjI~Es2idLI7A0bJaZmqh4NIE0Wnl5Ts7KTTyMMFoVktKpaH4ov2yXsprvASy9vkejuIsaUOTvFwmCbdhOEB6gfpq4tytqjCqfQXbVFkBOqH2x2oOxdBp14lWcufxNmbkDpwj3O6AcEwZpqMXtS1waJG0YZIjZNM54pzjh3D7Vo~daY7UpBi6gZjIOJOMD3nxuYShUtgT7H16Msdq097E0jO1NBUfMLf2wzssGbCYCwrNka71QblqHtutdvhZ48TqQKN-f2fnm~nG~yCFy1jJeQgA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 716 | }, 717 | "srclang": "en", 718 | "label": "English", 719 | "subtitleable_id": 8299, 720 | "created_at": "2019-01-15T05:39:06.878+01:00", 721 | "updated_at": "2019-01-15T05:39:06.878+01:00", 722 | "subtitleable_type": "LectureMedium" 723 | } 724 | ], 725 | "is_transcoding_completed": true, 726 | "is_transcoding_error": false, 727 | "is_transcoding_processing": false, 728 | "media_cues": [ 729 | { 730 | "id": 475, 731 | "type": "MediaQuestion", 732 | "cue_start_time": "179.497", 733 | "cue_end_time": "-1.0", 734 | "cued": { 735 | "id": 10012, 736 | "coursework_id": null, 737 | "name": "QUIZ: What are the two user interface elements that we've used so far?", 738 | "gallery": false, 739 | "peer_review": false, 740 | "created_at": "2019-01-16T00:50:21.420+01:00", 741 | "updated_at": "2019-01-16T00:50:21.420+01:00", 742 | "required": false, 743 | "definition": [ 744 | { 745 | "attachment_ids": null, 746 | "attachments": null, 747 | "explaination": "", 748 | "question": "QUIZ: What are the two user interface elements that we've used so far?
", 749 | "options": [ 750 | { 751 | "answer": "the djembe and the sawtooth oscillator", 752 | "selected": "false" 753 | }, 754 | { 755 | "answer": "the hslider and the button", 756 | "selected": "true" 757 | }, 758 | { 759 | "answer": "the Romain and the Yann", 760 | "selected": "false" 761 | } 762 | ], 763 | "multi_response": null, 764 | "grading_format": null, 765 | "_type": "MultipleChoiceField" 766 | } 767 | ], 768 | "_type": "MultipleChoiceField", 769 | "extra_credit": false, 770 | "autograde": null, 771 | "old_auto_grader_id": null, 772 | "order": null, 773 | "auto_grader_entry_point": null, 774 | "template_id": null, 775 | "editable": true, 776 | "auto_grader_version": null, 777 | "auto_grader_jsonapi_version": null, 778 | "auto_grader_id": null, 779 | "plagiarism_detection": false, 780 | "check_library_plagiarism": false, 781 | "student_plagiarism_visibility": false, 782 | "field_definition": [ 783 | { 784 | "attachment_ids": null, 785 | "attachments": null, 786 | "explaination": "", 787 | "question": "QUIZ: What are the two user interface elements that we've used so far?
", 788 | "options": [ 789 | { 790 | "answer": "the djembe and the sawtooth oscillator", 791 | "selected": "false" 792 | }, 793 | { 794 | "answer": "the hslider and the button", 795 | "selected": "true" 796 | }, 797 | { 798 | "answer": "the Romain and the Yann", 799 | "selected": "false" 800 | } 801 | ], 802 | "multi_response": null, 803 | "grading_format": null, 804 | "_type": "MultipleChoiceField" 805 | } 806 | ] 807 | } 808 | } 809 | ] 810 | }, 811 | { 812 | "id": 8298, 813 | "lecture_id": 1005, 814 | "media_src": { 815 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8298/file/Faust_C1_S1.7_V2.mov?Expires=1654854872&Signature=Pshy2Ur9E47O18Civ9Nz66Wyjw78qWIR8EHMiVncqnnYSNKKWwo1NCRgf~fPIzaJ9IaoyrK0egqqeJdDA0ljOvYBLueHDt5f5YtXVnFMom28vaIrpOjO7aem4wxQyKL38tWtUi7kw7WMqZJ75Y0Hg66z8quS~ZmD19MqjhQUpAXowuNhxo-6W6sdM3jn~cfuqRr00CxyBwRPE~N3bxyaS4wk44IKdK5XL6YitbSR1GHY3fgGdwfUWIGNLGGAjDvYJBEQLkeS-rZmnaCZ6JG70qt0bZkpdzDly2VCgEoNeiMbE6VfHalN26cvLHVNsn26uC1mi98T1slmpVQ6U4Z-zA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 816 | "thumb": { 817 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8298/file/thumb_Faust_C1_S1.7_V2.jpg?Expires=1654854872&Signature=TUaU93utm6PqqS5yQ8~0LnyyD3bQi2Fb6FUz8JZVyTx39R3jVZ5oZEW006kYidVil00EJT2hL3nZvIEOVzMqex9~WnjFtz68tWYhCxWLWhNRb07jUuGTIBqSDo3eCpO3drIcMGIk46usbIk2aRFrgIm9zbfSSilw6oGwmfS13u1Lus7TXMNWR9s44mvB4HqGyvimlcFHVXR9v3K9IKnlKZKT06MbMH3o6mTbAShppp0MxNknqV9SNHO2cCw8k2sVMsULZctcr0DZHF9Qp3pmzbvs~AARptj3maifNKAumVguoPOdj02RgZAB2oNXaZrwnzKfpF523mr2-hbi0G9kig__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 818 | } 819 | }, 820 | "media_src_tmp": null, 821 | "media_type": "video/quicktime", 822 | "created_at": "2019-01-14T22:19:36.695+01:00", 823 | "updated_at": "2022-06-03T10:19:15.270+02:00", 824 | "order": 7, 825 | "screenshot": { 826 | "url": null, 827 | "retina": { 828 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 829 | }, 830 | "thumb": { 831 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 832 | }, 833 | "retina_thumb": { 834 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 835 | }, 836 | "cinema": { 837 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 838 | } 839 | }, 840 | "duration": "81.5", 841 | "size": 51874259, 842 | "title": "Breath Control", 843 | "completed": false, 844 | "progress": "0.0", 845 | "type": "NativeMedia", 846 | "h264_360_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8298/file/Faust_C1_S1.7_V2_360.mp4?Expires=1654854871&Signature=iU3Rddh~CPoIomdCZ2QPslESxd3KZY58S3uCmns3UhTcAn~SMVbyRN6-OhST6gaHbwGvEMSituj~EERrl~z3tNACczONxmlQzMfiaOxGWZXULptARiG-cKYUS~qIQI58ibKEe8oGLlCYIq6~53aFqxp~y5PPxTaagLqIoRPnFK46lac46etbPQjN4dzxTquI3bDwf~06KJNdpdiHvSiznt0HLa~RH2ySYCCPlAiWoIqLPTgd1a844V5EyqfbeSfb4v8hjyupXT57H7kNoWHya2qOU~kzm3MTr3bhajzQI2mdY5cpuUV5Ftyza98VWV8WTzDEaBfrjQrmQ1Yt33qRvQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 847 | "h264_720_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8298/file/Faust_C1_S1.7_V2_1080_2700k.mp4?Expires=1654854871&Signature=MSIponWPmb~jQlFukfYC9WMW7oJQrvY5-zQaFZCLGo5rCWv~3Iiw7U8U27Nib91y7O9G9I5eUNw4yu83lMbS1n-ix7SqPzzWOG5ultFrMFlEVg-mfVymVhsyg9bd7uwxCkV3CvQl~F6Y34hviX2Hk9S8RjEGyynDxe2McrJM7OQxjJtirE5UeQ-wVEiwvdEseCsYEQ5L7GExV9LDIzz0izVopJnhmryk17ZnYbdSrtnQ0P4TfTK9J7hMniC5ZW9VdML4~woale0Y8HLpRjlbOwCCI2ssHHrTa9Os92ZMaUOEA3EuL3tjOKwIT1XXDJh96tjK-qDpY0~MScUT-3YoFg__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 848 | "transcode_status": "completed", 849 | "transcode_error_message": null, 850 | "user_state_data": {}, 851 | "accessible": true, 852 | "premium_only": false, 853 | "downloadable": true, 854 | "subtitles": [ 855 | { 856 | "id": 16598, 857 | "src_file": { 858 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/subtitle/16598/src_file/subtitles-en.vtt?Expires=1654854872&Signature=i-hRjK5dB5f0KaEBBudBqiS3OeqSqq3TlkHU9n9Qra-kICxLNeSR4sc78V3Uw10HzbpECh~jArofzpI2nI08RJEBgwhqJiALpMkNaeDP-q9L3BL0C4VxyK9GsvVkxWeECboSDPVoZuN1XWlVzlQCSVH5VG5eBdVfJUF4eL8RZk~39HNmxajxEBZkDHcmrXf4MCFncIisbCwhEzVjDdomMrY7uwrnoXOzwP6TEv~SzyRxR~nQI1zXl4mKe48yTspunOOC25lMEhVzTOjfCv69NtGEQQRZrvYFntQBw7JwjOkHLd6kxhIp3~ayCqszyH9DGZKOZcXel2MhG-srTEz7XA__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 859 | }, 860 | "srclang": "en", 861 | "label": "English", 862 | "subtitleable_id": 8298, 863 | "created_at": "2019-01-15T05:39:18.562+01:00", 864 | "updated_at": "2019-01-15T05:39:18.562+01:00", 865 | "subtitleable_type": "LectureMedium" 866 | } 867 | ], 868 | "is_transcoding_completed": true, 869 | "is_transcoding_error": false, 870 | "is_transcoding_processing": false, 871 | "media_cues": [] 872 | }, 873 | { 874 | "id": 8296, 875 | "lecture_id": 1005, 876 | "media_src": { 877 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8296/file/Faust_C1_S1.8_V2.mov?Expires=1654854872&Signature=R-y9Ww4B3JchqDR6uVjXuXRbyndOCibrOWveKtmaqolvlGnHqGVCA4oRmg3g2EvMFDmawKNMqZgf~b1LBQYLwS1o4GfUgSYiYpZkq4cMasmjLO7I728TG8sq61-qjsc2x6NYj49aB2z~G0H7ziUlo-WVvV4Uv2iN~NZyw6vkUwiCPPgP~j63GoWPovJhOb3~hNmMTD2VNPuHpnc~aVEtnDpaoGObcEZ8m7fJvky0XyATzOM0GkyPsxUlw4yCfhx8zgfMah0rvc-KXDQvCiceOQt9FksmFejLgxvrDCe5FcMrg1uRGnGSzq~CJ3ADVAiHQ0YIJpchP1Mp0GloXk-1DQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 878 | "thumb": { 879 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8296/file/thumb_Faust_C1_S1.8_V2.jpg?Expires=1654854872&Signature=YN7PLFouwyjnMEHyXciYYDbEpxNsZR-fu5kvF2MBnxMlusXUkK35rxdC---unqYTUri4YTSZfBKT-liMphOwwHXDwsZZJrpfipFtKdSYQL3E-bc6vcI4WKv6Gj9cSbw9WMxI7vHEieXvullS20GGjyRmWMzApHY94~7RJP3-K1uH7yTAL6jWJRD8w9rzSsLRgkMOQVe32XavIF8THFZ~G7WV~YEXiQhTDOmOBX5BHy5FTrwb4hSHfdk6M26lVxmt1KiFHjLCSWwT~SBrnRxi8nifb~Le5W3B7lxCt-3jC5LMehpeX~Waw-PkSvmEwcuaIEOBQ6CsZF3~jacPiOh8~g__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 880 | } 881 | }, 882 | "media_src_tmp": null, 883 | "media_type": "video/quicktime", 884 | "created_at": "2019-01-14T22:18:40.918+01:00", 885 | "updated_at": "2022-06-03T10:30:09.221+02:00", 886 | "order": 8, 887 | "screenshot": { 888 | "url": null, 889 | "retina": { 890 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 891 | }, 892 | "thumb": { 893 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 894 | }, 895 | "retina_thumb": { 896 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 897 | }, 898 | "cinema": { 899 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 900 | } 901 | }, 902 | "duration": "169.59", 903 | "size": 83710290, 904 | "title": "Additive Synthesizer", 905 | "completed": false, 906 | "progress": "0.0", 907 | "type": "NativeMedia", 908 | "h264_360_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8296/file/Faust_C1_S1.8_V2_360.mp4?Expires=1654854871&Signature=VuMgdMWswFW4RmRexMSoYU5oIytXlU8zk~~XS0lb2x9wtAy0nTo0Hjs~ll4bC1ZWbq5-1QJ~BMAeUXpEsqbn0N38aBPNjS3QlRnmdlo-mHDV9BdeCv~QWZYCrTVcALFfZ5cYShhrYEs-uzk452qbpneSVxCs5c7TQdb3TTDqwiWfluboxxSgdFxvQZkgIYLkUm6vliCuaFuEZ4Xcu-8P~Z-qn6Q9ajc7U5xzzLRNWdEoOOWxfUln2YRwSD3e31eZInZj-lQSsSu~OyDRkfceJQRSzoF34uQmFWaJcNMnkhYFJtZBv7bu6ASAWE0F7l-jpdKGTPtg31kZMK-cqWh8ew__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 909 | "h264_720_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8296/file/Faust_C1_S1.8_V2_1080_2700k.mp4?Expires=1654854871&Signature=itsr097KPdIP2hqM4XadmKrMSv1v2rXQwHV5zBrX0NcBPEOlJE46xWhwJbsCExf1DTuBRVgKjKqP~RGAMO5UIsHnJYQu3yJ2jTanmcQt2vybeYukZV9tZ4QVCE~igFi5ezwvGP6VfI10HM2ec9hemYtGrXNUw726nu3jCKn72sf3k7rQbfzeG9yvAdK1AbmapufxEHhEjm-qp-Dbmipc1zwEquI5CbookNRlhcJoSPtubm2EbrK3JRPT0pC0pnGO4oSA1oCI6ZHRpt5v~Q7t89pi7sSYstemwoc0cWnW8EI1KQvpX2al-6bcCbtRcyaopH1GV9Q1jDfsw2puKU-08A__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 910 | "transcode_status": "completed", 911 | "transcode_error_message": null, 912 | "user_state_data": {}, 913 | "accessible": true, 914 | "premium_only": false, 915 | "downloadable": true, 916 | "subtitles": [ 917 | { 918 | "id": 16599, 919 | "src_file": { 920 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/subtitle/16599/src_file/subtitles-en.vtt?Expires=1654854872&Signature=jmQeqZGRhL0EFFFf~g~fDAjY-QCCHhhOQ0CfUo-DMgCi~-tN1RPToLe6tkr8q5By~BRUPCed9WaepXHbpUyXCV5lI3rRv1PV3givYCZfsyVXgUDhIzTcmLARVUYKobUTtoGwTmYInr54YRRlCb1MtLnwhbUPTPXUHpL7mhs-f8F7iF9OwZSflE9sDi2MoYgxxwcsyv8L8dvYRiDhG0QcDBOITBhjXp5VDuIICxDGI7yycNuMGCc3-RdT2vLKEoHClHIo5~zs2nWnsfOjHvSZJfNGnvlwPdN6KUi62zzrKOAt8z52KzU1TbmkGNdM3dtSC1R6Q4wAn8-VzGCyr1sS8A__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 921 | }, 922 | "srclang": "en", 923 | "label": "English", 924 | "subtitleable_id": 8296, 925 | "created_at": "2019-01-15T05:39:28.856+01:00", 926 | "updated_at": "2019-01-15T05:39:28.856+01:00", 927 | "subtitleable_type": "LectureMedium" 928 | } 929 | ], 930 | "is_transcoding_completed": true, 931 | "is_transcoding_error": false, 932 | "is_transcoding_processing": false, 933 | "media_cues": [] 934 | }, 935 | { 936 | "id": 8297, 937 | "lecture_id": 1005, 938 | "media_src": { 939 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8297/file/Faust_C1_S1.9_V2.mov?Expires=1654854872&Signature=JfqWPkl-Tjjm11NIvHTgvZO4LcigBLhmhWbTL9RRvhdw4ZcJQzMdV0m~dl5VYfv~0yqBoD9Y1Ro3uojsI8KnOBK~AN5idizfBaISlryqF9cUkPuybHVt40WV3u0xT9knOKUr-V-dlJ88OqZ33OlAWw3hsjjPrN9nFSUy86r0fWz4OvQDWnA8j23YAUtf0v1jQVCcUbRgL45afMFg1jqTf9gFxdQOYyI4x4hhlCZj5rlhXuuc~gUXcWb5sSecbEP0oVwnQoNdgtwjvHhPB4T0heRBek8SMah-fU2uAKudzDI9x2228r9hELY4R0Lzri9hKaeMvOVygukJL0cF3x4K7w__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 940 | "thumb": { 941 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8297/file/thumb_Faust_C1_S1.9_V2.jpg?Expires=1654854872&Signature=fC4H1bC3rC2E4VnnZ0OerjxPAW7x-hSiItzxsmdHftvmuWHuCJHcQ3rstYpalZyUQogkKNkolHLi5OmLIdgNQ3JnG0bZjEqs36szuDZ5KkMM33oANzcQNtqFWwp8UHzxfh9~b~hYQNhqW7Izx0YjI8YxOyyqb3KhnmuJprZbFdmdDvyWbqeiR-MZOo-sjSeqolhR40IB7vxDtigEnPT2wLGWPbqYy4kL~Hajfp6L62fNIcGbo-6Apk5Qlp1InsK8G--ptQpoh8Du4gDCFxhnwL5jvZXZSC1ulG3B96o-LNLe4QsvixI8vz7DDqAF99lYWvT11846btOoEb7gvoN4GQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 942 | } 943 | }, 944 | "media_src_tmp": null, 945 | "media_type": "video/quicktime", 946 | "created_at": "2019-01-14T22:19:31.093+01:00", 947 | "updated_at": "2022-06-03T10:36:46.741+02:00", 948 | "order": 9, 949 | "screenshot": { 950 | "url": null, 951 | "retina": { 952 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 953 | }, 954 | "thumb": { 955 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 956 | }, 957 | "retina_thumb": { 958 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 959 | }, 960 | "cinema": { 961 | "url": "https://prod-assets.useast1.kadenze.com/assets/courses/cinema_default-0746f01431571c2ffd4f6ddc922694e36f71a79a980b707acd1141b5151944ea.svg" 962 | } 963 | }, 964 | "duration": "260.05", 965 | "size": 152217075, 966 | "title": "Polyphonic Midi Synthesizer", 967 | "completed": false, 968 | "progress": "0.0", 969 | "type": "NativeMedia", 970 | "h264_360_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8297/file/Faust_C1_S1.9_V2_360.mp4?Expires=1654854872&Signature=AWlqZzclLco~A0tE~-CAymdfzlqdwy~sbqGWyIFYgPHjsk-Tr7HajOKvOjHgcncV91ExQFOMNBaaj5czEXQ3sZ2XvUgd6Af6kSWTBTL9rDH~Vcp0fTJarQif1Y5EMWfsZ6~ve1gZ2BkwpGdBO3nIRzobylfsqmESosZ1g5KQBCWZO7vqAwoK6V6mpuxXIJO31YG5BY-u0nHEXzibDkIgcsve7Pl2GxhgGyzoTZrRNwAGLrxEhbrYb-EUEVJCfL5COC5MXIWAKBDldAqWJkdjVbnHcYLfE4phWyavFsuaCoqDngguZBHiONPzKj-dwViMjQyTZAwi1WHxj8jEwBVs4A__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 971 | "h264_720_url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/lecture_medium/8297/file/Faust_C1_S1.9_V2_1080_2700k.mp4?Expires=1654854872&Signature=mAyeyoeMUUXgDrI8GCToYQycuobHmzfzrmm3fHcPqZ1lGZ7OGqGzOpUjcDSpi4JlPnCugY1luxeUCEWENVgL4RIM-5hSx4D2WlFJIJyzpcniPn3emTpakiwQod7pnCdq0maFOXqnvT5GGXe3VVkG82y8AsSnPCsF2yrFmw2cwJJJ-Dr5jYyX4LWMb3FA-Twzf-gzZ7cwfVKHFELk~Wg1yxkPRraI5IO7az17JhUjdE0Sq9acnjMnADXYsbikWv286oQ~8KdCI3xxkD7zZmTV2q933HqKeFdsb5QqOrg2px6OZ-cjHiICQzWUwrddVxTT~RdCMtqpkbxPcSK8eABArw__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA", 972 | "transcode_status": "completed", 973 | "transcode_error_message": null, 974 | "user_state_data": {}, 975 | "accessible": true, 976 | "premium_only": false, 977 | "downloadable": true, 978 | "subtitles": [ 979 | { 980 | "id": 16600, 981 | "src_file": { 982 | "url": "https://prod-uploads-priv.useast1.kadenze.com/prod/usr/uploads/subtitle/16600/src_file/subtitles-en.vtt?Expires=1654854872&Signature=CADxZGAmhFtfd9aWICzjKNRMvOwymznBixDU0Heve-Tja72dUktlD2PNEKK4SrYvYFPmF4FffV5rVLrycrkU4eDmfUeFxXHKqIqve4R7UsaauAlSZSUxMOUwTw~tDv6pJRgKagwesd9tDvPOF1Y50xCoDN3mJ~U1B2lkIGTHjWqxmYBl8Hg48~9opo49IGOwyoWWcNOp2byqdgAooer34m1MQlFVcEjLfXgQsdatPYQUSWEIrQGKlr1Fr5FMMRzloxmm3-sn-fVOHOVYWMhIzdSSq4Yfv3StczPXvBJp4Cv~Bsn5QiilhveJwkSWTUnNPRbhpW0mHOSJKit9hCnbJQ__&Key-Pair-Id=APKAI3WTOBWXO6VZASUA" 983 | }, 984 | "srclang": "en", 985 | "label": "English", 986 | "subtitleable_id": 8297, 987 | "created_at": "2019-01-15T05:39:39.891+01:00", 988 | "updated_at": "2019-01-15T05:39:39.891+01:00", 989 | "subtitleable_type": "LectureMedium" 990 | } 991 | ], 992 | "is_transcoding_completed": true, 993 | "is_transcoding_error": false, 994 | "is_transcoding_processing": false, 995 | "media_cues": [ 996 | { 997 | "id": 476, 998 | "type": "MediaQuestion", 999 | "cue_start_time": "121.766", 1000 | "cue_end_time": "-1.0", 1001 | "cued": { 1002 | "id": 10013, 1003 | "coursework_id": null, 1004 | "name": "MidiKeys (for Mac): http://www.manyetas.com/creed/midikeys.htmlVMPK (for Linux and Windows): MidiKeys (for Mac): http://www.manyetas.com/creed/midikeys.htmlMidiKeys (for Mac): http://www.manyetas.com/creed/midikeys.html
VMPK (for Linux and Windows): http://vmpk.sourceforge.net/