{"id":13631947,"url":"https://github.com/lewangdev/youtube-drive","last_synced_at":"2025-04-08T03:14:41.162Z","repository":{"id":37561094,"uuid":"496679964","full_name":"lewangdev/youtube-drive","owner":"lewangdev","description":"Store files as YouTube videos == infinite disk space. youtube-drive is totally inspired by YouTubeDrive.","archived":false,"fork":false,"pushed_at":"2023-02-27T05:01:34.000Z","size":547,"stargazers_count":202,"open_issues_count":1,"forks_count":17,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-04-26T08:04:02.282Z","etag":null,"topics":["youtube","youtube-api-v3","youtube-dl","youtube-drive","youtube-upload"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lewangdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-05-26T15:47:32.000Z","updated_at":"2024-04-02T11:28:24.000Z","dependencies_parsed_at":"2024-01-14T06:54:07.814Z","dependency_job_id":"f864c085-c858-43a1-bf52-84ad03df86fd","html_url":"https://github.com/lewangdev/youtube-drive","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewangdev%2Fyoutube-drive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewangdev%2Fyoutube-drive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewangdev%2Fyoutube-drive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewangdev%2Fyoutube-drive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lewangdev","download_url":"https://codeload.github.com/lewangdev/youtube-drive/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247767236,"owners_count":20992548,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["youtube","youtube-api-v3","youtube-dl","youtube-drive","youtube-upload"],"created_at":"2024-08-01T22:02:45.963Z","updated_at":"2025-04-08T03:14:41.143Z","avatar_url":"https://github.com/lewangdev.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# youtube-drive\n\nyoutube-drive is totally inspired by [YouTubeDrive](https://github.com/dzhang314/YouTubeDrive), a Wolfram Language (aka Mathematica) package. I read the source code of **YouTubeDrive** and write a Python version with a little change for fun.\n\n**youtube-drive** is a Python library encodes/decodes arbitrary data to/from simple RGB videos which are automatically uploaded to/downloaded from YouTube. Since YouTube imposes no limits on the total number or length of videos users can upload, this provides an effectively infinite but extremely slow form of file storage.\n\nyoutube-drive is a silly proof-of-concept, and I do not endorse its high-volume use either.\n\n## Usage Example\n\n**Upload**: Encode a file to video and upload to YouTube:\n\n```sh\npython -m youtube_drive upload examples/BesselJ.png\nYouTube Video ID: EzqstWlMXyk\nYouTube: https://youtu.be/EzqstWlMXyk\n\n```\n\n**Retrieve**: Download the video from YouTube and decode to a file:\n\n```sh\npython -m youtube_drive retrieve --video-id=EzqstWlMXyk -o BesselJ-retrieved.png\n/var/folders/md/dnr_ryfs2_x128p26xx2pnnc0000gn/T/tmp6qfm_msc.mp4\n[youtube] EzqstWlMXyk: Downloading webpage\n[youtube] EzqstWlMXyk: Downloading MPD manifest\n[download] Destination: /var/folders/md/dnr_ryfs2_x128p26xx2pnnc0000gn/T/tmp6qfm_msc.f136.mp4\n[download] 100% of 1.74MiB in 00:25\n[download] Destination: /var/folders/md/dnr_ryfs2_x128p26xx2pnnc0000gn/T/tmp6qfm_msc.mp4.f140\n[download] 100% of 58.70KiB in 00:03\n[ffmpeg] Merging formats into \"/var/folders/md/dnr_ryfs2_x128p26xx2pnnc0000gn/T/tmp6qfm_msc.mp4\"\nDeleting original file /var/folders/md/dnr_ryfs2_x128p26xx2pnnc0000gn/T/tmp6qfm_msc.f136.mp4 (pass -k to keep)\nDeleting original file /var/folders/md/dnr_ryfs2_x128p26xx2pnnc0000gn/T/tmp6qfm_msc.mp4.f140 (pass -k to keep)\n```\n\nThe video, video ID is **EzqstWlMXyk**, youtube-drive produces in this example can be viewed at https://youtu.be/EzqstWlMXyk. The video is encoded from the image [BesselJ.png](https://github.com/lewangdev/youtube-drive/blob/main/examples/BesselJ.png). A 62KB image file will produce a video of size 10+MB.\n\nAnother file I uploaded to YouTube is [painting.jpg](https://github.com/lewangdev/youtube-drive/blob/main/examples/painting.jpg), it produces a video of size 127.5MB, and the original size is 476KB. The video can be viewed at https://youtu.be/gKhXk3IGW2s.\n\nI use opencv to produce mp4 video, if use ffmpeg with optimizing directly, the video maybe compress to a more smaller size.\n\n**AGAIN:** It is a silly idea, just for fun.\n\n## Installation\n\n**Notice**:\n\n- I only test with **Python 3.8 \u0026 3.9 \u0026 3.10** on **MacOS** with ffmpeg installed.\n- If it works on your system, please feel free to let me know. Thanks.\n\nFor development:\n\n```sh\ngit clone https://github.com/lewangdev/youtube-drive.git\ncd youtube-drive\npython -m venv .venv\n. .venv/bin/activate\npip install -r requirements.txt\n```\n\nOr run directly from sources:\n\n```sh\ngit clone https://github.com/lewangdev/youtube-drive.git\ncd youtube-drive\npython -m venv .venv\n. .venv/bin/activate\npython setup.py install\n```\n\n## Setup\n\nThe first time you try to upload a video to YouTube, you will be asked to follow a URL in your browser to get an authentication token. If you have multiple channels for the logged in user, you will also be asked to pick which one you want to upload the videos to.\n\nYou now need to create and use your own OAuth 2.0 file, it's a free service. Steps:\n\nGo to the [Google Cloud Console](https://console.cloud.google.com/).\n\n- Create project.\n- Side menu: APIs \u0026 Services -\u003e OAuth consent screen: Create app and add the test user you will updoad videos to.\n- Side menu: APIs \u0026 Services -\u003e Enabled API \u0026 services -\u003e ENABLED API AND SERVICES -\u003e Search `youtube` -\u003e Choose `YouTube Data API v3` and enable it.\n- Side menu: APIs \u0026 Services -\u003e Credentials -\u003e Create Credentials -\u003e OAuth client ID: Application type choose `Desktop app`.\n- Download JSON: Under the section \"OAuth 2.0 client IDs\". Save the file to your local system.\n  Use this JSON as your credentials file: copy it to ~/.client_secrets.json.\n  Note: client_secrets.json is a file you can download from the developer console, the credentials file is something auto generated after the first time the script is run and the google account sign in is followed, the file is stored at ~/.youtube-upload-credentials.json.\n\nIf you feel any difficulty to create OAuth 2.0 file, here is the video I made for you: https://youtu.be/kL2oFZt2xHM\n\n## Usage\n\n**Commands:**\n\n```sh\npython -m youtube_drive -h\nusage: youtube-drive [-h] {encode,en,decode,de,upload,up,retrieve,r} ...\n\noptions:\n  -h, --help            show this help message and exit\n\ncommands:\n  {encode,en,decode,de,upload,up,retrieve,r}\n    encode (en)         encode a file to mp4 video\n    decode (de)         decode a video to a file\n    upload (up)         upload a file to YouTube\n    retrieve (r)        retrieve a video from YouTube save as \u003cfilename\u003e\n\n```\n\nIf you install from source, you can run the script directly:\n\n```sh\nyoutube-drive -h\nusage: youtube-drive [-h] {encode,en,decode,de,upload,up,retrieve,r} ...\n\noptions:\n  -h, --help            show this help message and exit\n\ncommands:\n  {encode,en,decode,de,upload,up,retrieve,r}\n    encode (en)         encode a file to mp4 video\n    decode (de)         decode a video to a file\n    upload (up)         upload a file to YouTube\n    retrieve (r)        retrieve a video from YouTube save as \u003cfilename\u003e\n\n```\n\n**Upload:**\n\n```sh\npython -m youtube_drive up -h\nusage: youtube-drive upload [-h] filename\n\npositional arguments:\n  filename    encode file \u003cfilename\u003e to a video and upload to YouTube\n\noptions:\n  -h, --help  show this help message and exit\n\n```\n\n**Retrieve:**\n\n```sh\npython -m youtube_drive r -h\nusage: youtube-drive retrieve [-h] [--video-id video_id] [-o filename]\n\noptions:\n  -h, --help           show this help message and exit\n  --video-id video_id  download YouTube video with \u003cvideo_id\u003e\n  -o filename          save file to \u003cfilename\u003e\n\n```\n\n**Local Encode:**\n\n```sh\npython -m youtube_drive en -h\nusage: youtube-drive encode [-h] [-i input_filename] [--video-fps video_fps] video_filename\n\npositional arguments:\n  video_filename        save the video to this filename\n\noptions:\n  -h, --help            show this help message and exit\n  -i input_filename     encode file \u003cinput_filename\u003e to a video\n  --video-fps video_fps\n                        set video fps, default value is 20\n\n```\n\n**Local Decode:**\n\n```\npython -m youtube_drive de -h\nusage: youtube-drive decode [-h] [-i input_video_filename] filename\n\npositional arguments:\n  filename              Save the output file to this filename\n\noptions:\n  -h, --help            show this help message and exit\n  -i input_video_filename\n                        decode the video \u003cinput_video_filename\u003e to a file\n```\n\n## The difference between **youtube-drive** and **YouTubeDrive**\n\nI add 4 bytes for representing data length at the beginning for the file for easily padding to video frames\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flewangdev%2Fyoutube-drive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flewangdev%2Fyoutube-drive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flewangdev%2Fyoutube-drive/lists"}