Skip to content

Instantly share code, notes, and snippets.

@nneonneo
Last active October 1, 2024 02:32
Show Gist options
  • Save nneonneo/f6b2d659ba76542e7d27e13598a6859c to your computer and use it in GitHub Desktop.
Save nneonneo/f6b2d659ba76542e7d27e13598a6859c to your computer and use it in GitHub Desktop.
YouTube-DL for Pythonista - download YouTube videos on your iPhone/iPad!
#!python3
'''
Directions:
- install yt-dlp via Pip (e.g. using (StaSh)[https://github.com/ywangd/stash] - `pip install yt-dlp`)
- add this script as a Share extension through Settings -> Share Extension Shortcuts
- while watching a video in the YouTube site or app, just share the video to Pythonista and select this script
- the video will download, and when it's done you can share the video file itself with any app (e.g. VLC)
Advanced usage:
- if you specify -audio as the script argument, this script will download audio only
- if you specify -stream as the script argument, this script will just grab the actual video URL and redirect you
to VLC, which will stream the video (without interruptions or ads!)
'''
from __future__ import unicode_literals
import yt_dlp as youtube_dl
import appex
import console
import clipboard
import os
import sys
try:
# We cannot use ffmpeg on iOS
from yt_dlp.postprocessor import FFmpegPostProcessor
FFmpegPostProcessor.available = False
except ImportError as e:
pass
outdir = os.path.expanduser("~/Documents/Downloads")
try:
os.mkdir(outdir)
except FileExistsError:
pass
if appex.get_attachments():
# e.g. share from YouTube app
url = appex.get_attachments()[0]
elif appex.get_urls():
# e.g. share from Safari
url = appex.get_urls()[0]
elif appex.get_text():
url = appex.get_text()
elif clipboard.get():
url = clipboard.get()
print("URL: ", url)
if not url or not url.startswith("http"):
url = input("No URL found - enter URL to download: ")
ydl_opts = {'outtmpl': os.path.join(outdir, '%(title)s.%(ext)s')}
if '--audio' in sys.argv[1:] or '-audio' in sys.argv[1:]:
ydl_opts['format'] = 'bestaudio'
if '--stream' in sys.argv[1:] or '-stream' in sys.argv[1:]:
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=False)
from objc_util import UIApplication, nsurl
from urllib.parse import urlencode
app = UIApplication.sharedApplication()
params = urlencode({'url': info['formats'][-1]['url']})
#app.openURL_(nsurl('vlc-x-callback://x-callback-url/stream?' + params))
#app.openURL_(nsurl('infuse://x-callback-url/play?' + params))
app.openURL_(nsurl(info['formats'][-1]['url']))
else:
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=True)
filepath = ydl.prepare_filename(info)
console.open_in(filepath)
@nneonneo
Copy link
Author

Yes, unfortunately we cannot use ffmpeg as we can’t add native binaries on iOS. There may be third party apps that can merge and/or convert the video and audio file if downloaded separately.

@sixplus0
Copy link

Well understood! Appreciate your GREAT help and the script enlightens me A LOT!!! THANKS echos~~~

@gaetschwartz
Copy link

gaetschwartz commented Jul 14, 2022

Hi, I was wondering if we could access the ~/Documents/Downloads folder somehow, is it just a temporary folder or a permanent one ? If permanent, then sharing the file to VLC would mean we have twice the file isn't it ?

@nneonneo
Copy link
Author

Yes, it should be accessible directly in Pythonista, via the script library file browser under This iPhone. The file will be copied from here to VLC, but you may delete the copy in Pythonista afterwards.

@ysiegel29
Copy link

How can you change the format to MP3 when using the -audio extension? Thank you! Great script!

@ysiegel29
Copy link

Fyi I could not find a way to convert to mp3 (no support for ffmpeg on iOS) but if you replace bestaudio by m4a you get an mpeg4 audio file that worked for my use case.

@nneonneo
Copy link
Author

Yeah, unfortunately we can't support ffmpeg, and as far as I understand it, YouTube does not encode their audio in MP3 format. Glad to hear that m4a worked for your case.

@rafcontreras
Copy link

I've found the best format to send to VLC or Infuse is:

ydl_opts['format'] = 'bv+ba'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment