aboutsummaryrefslogtreecommitdiffstats
path: root/YouTube_to_WebDAV.ipynb
diff options
context:
space:
mode:
authorPinapelz <donaldshan1@outlook.com>2026-03-02 13:10:25 -0800
committerGitHub <noreply@github.com>2026-03-02 13:10:25 -0800
commite6f39efe00f6d35e6485e19f1a37d74236cddf9d (patch)
tree8f17a76a62d79696b6c0cdd91caf8d9eb0faac36 /YouTube_to_WebDAV.ipynb
init commit
Diffstat (limited to 'YouTube_to_WebDAV.ipynb')
-rw-r--r--YouTube_to_WebDAV.ipynb188
1 files changed, 188 insertions, 0 deletions
diff --git a/YouTube_to_WebDAV.ipynb b/YouTube_to_WebDAV.ipynb
new file mode 100644
index 0000000..ba7bfb0
--- /dev/null
+++ b/YouTube_to_WebDAV.ipynb
@@ -0,0 +1,188 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "provenance": []
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# YouTube to WebDAV\n",
+ "This script allows for a YouTube video to be downloaded and then automatically uplaoded via WebDAV\n",
+ "\n",
+ "Usecase is useful for running Syncplay or similar software in situations where running yt-dlp may not be viable\n",
+ "\n",
+ "This approach can still fail in cases where JS solver is required\n",
+ "\n",
+ "# What this does?\n",
+ "- Downloads vidoe via yt-dlp\n",
+ "- Downloads all official subtitles (non-auto-generated)\n",
+ "- Mux into single MKV file\n",
+ "- Upload via WebDav\n",
+ "\n",
+ "Optionally if you are using Nextcloud you can also automatically generate a share\n",
+ "\n",
+ "# Usage\n",
+ "Fill in all the fields below. Then `Run all`"
+ ],
+ "metadata": {
+ "id": "L9cXBP9OPmFt"
+ }
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "vHGZttQWK8QJ"
+ },
+ "outputs": [],
+ "source": [
+ "# Install the dependencies needed\n",
+ "!pip install yt-dlp webdavclient3"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from webdav3.client import Client\n",
+ "webdav_url = \"\" #@param {type:\"string\"}\n",
+ "username = \"\" #@param {type:\"string\"}\n",
+ "password = \"\" #@param {type:\"string\"}\n",
+ "options = {\n",
+ " 'webdav_hostname': webdav_url,\n",
+ " 'webdav_login': username,\n",
+ " 'webdav_password': password\n",
+ "}\n",
+ "client = Client(options)\n",
+ "try:\n",
+ " client.list()\n",
+ " print(\"Success! Connection successful\")\n",
+ "except:\n",
+ " print(\"Login failed. Please check that your login and WebDAV url are correct\")"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "GAdz5SlkOIJO"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "youtube_url = \"\" #@param{type:\"string\"}\n",
+ "\n",
+ "!yt-dlp -f 'bv*+ba/best' \\\n",
+ " --merge-output-format mkv \\\n",
+ " --embed-subs \\\n",
+ " --write-subs \\\n",
+ " --sub-langs all \\\n",
+ " \"$youtube_url\""
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "GtiPVBYSQ1_6"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Uploads the file to the path specified\n",
+ "download_path = \"\" #@param{type:\"string\"}\n",
+ "\n",
+ "import glob\n",
+ "\n",
+ "mkv_files = glob.glob(\"/content/*.mkv\")\n",
+ "sub_files = glob.glob(\"/content/*.vtt\") + glob.glob(\"/content/*.srt\")\n",
+ "if not mkv_files:\n",
+ " raise FileNotFoundError(\"MKV file not found! Did the download fail?\")\n",
+ "original_mkv_path = mkv_files[0]\n",
+ "remote_filename = f\"{download_path}/\" + original_mkv_path.split(\"/\")[-1]\n",
+ "client.upload_sync(remote_path=remote_filename, local_path=original_mkv_path)\n",
+ "\n",
+ "print(f\"Done! Your file has been uploaded to {remote_filename}\")"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "3xYJpTl5SeVz"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# OPTIONAL NEXTCLOUD AUTO SHARE\n",
+ "- This uses Nextcloud API to create a public share URL automatically. Completes the workflow"
+ ],
+ "metadata": {
+ "id": "uabtse49Vy-L"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "import requests\n",
+ "nextcloud_url = \"\" #@param {type:\"string\"}\n",
+ "api_url = f\"{nextcloud_url}/ocs/v2.php/apps/files_sharing/api/v1/shares\"\n",
+ "payload = {\n",
+ " \"path\": remote_filename,\n",
+ " \"shareType\": 3, # 3 = public link\n",
+ " \"permissions\": 31 # optional, full permissions (read/write/share)\n",
+ "}\n",
+ "\n",
+ "headers = {\n",
+ " \"OCS-APIRequest\": \"true\"\n",
+ "}\n",
+ "response = requests.post(api_url, auth=(username, password), headers=headers, data=payload)\n",
+ "if response.status_code == 200:\n",
+ " import xml.etree.ElementTree as ET\n",
+ " root = ET.fromstring(response.content)\n",
+ " ns = {\"ocs\": \"http://open-collaboration-services.org/ns\"}\n",
+ " url_elem = root.find(\".//url\")\n",
+ " if url_elem is not None:\n",
+ " share_link = url_elem.text\n",
+ " print(\"Share link:\", share_link+\"/download\")\n",
+ " else:\n",
+ " print(\"Could not find share URL in response\")\n",
+ "else:\n",
+ " print(\"Error:\", response.status_code, response.text)"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "MSmhsS6PUxaG"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Cleanup/Delete old files\n",
+ "import os\n",
+ "mkv_files = glob.glob(\"/content/*.mkv\")\n",
+ "sub_files = glob.glob(\"/content/*.vtt\") + glob.glob(\"/content/*.srt\")\n",
+ "for f in mkv_files + sub_files:\n",
+ " os.remove(f)\n",
+ " print(f\"Deleted local file: {f}\")"
+ ],
+ "metadata": {
+ "id": "xBprVc4OUCor"
+ },
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+} \ No newline at end of file
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage