Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions Info.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@
"version": "0.9.8",
"ghRepo": "iina/plugin-online-media",
"ghVersion": 10,
"description": "Official plugin for playing online media via yt-dlp / youtube-dl. The built-in youtube-dl support will be disabled when this plugin is enabled.",
"description": "Official plugin for playing online media via yt-dlp.",
"author": {
"name": "IINA Developers",
"email": "[email protected]",
"url": "https://iina.io"
},
"entry": "dist/index.js",
"globalEntry": "dist/global.js",
"permissions": ["show-osd", "file-system", "network-request"],
"allowedDomains": ["github.com"],
"permissions": ["show-osd", "file-system"],
"preferencesPage": "pref.html",
"preferenceDefaults": {
"ytdl_path": "",
Expand Down
73 changes: 27 additions & 46 deletions downloads.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Status and Downloads</title>
<title>Online Media</title>
<style>
body {
color-scheme: light dark;
Expand Down Expand Up @@ -40,40 +40,34 @@
}

.no-task {
padding: 10px;
padding: 5px;
}

h4 {
margin: 0;
padding: 8px;
padding: 5px;
background: rgba(200, 200, 200, .6);
}

.info-container {
padding: 10px 10px 0 10px;
button {
padding: 5px;
margin: 0px 0px 10px 10px;
}

.binary-msg,
.download-container {
padding: 8px 0;
}

.binary-msg {
color: rgba(0, 0, 0, .6);
pre {
margin: 0px;
display: inline-block;
white-space: pre-wrap;
}

#downloading {
.spinner-container {
display: none;
text-align: center;
padding: 20px 10px 10px 10px;
}

#downloading .message {
margin-bottom: 6px;
}

#download-error {
color: #ff3b30;
.result-container {
padding: 5px;
display: none;
}

@media (prefers-color-scheme: dark) {
Expand All @@ -94,10 +88,6 @@
h4 {
background: rgba(100, 100, 100, .6);
}

.binary-msg {
color: rgba(255, 255, 255, .7);
}
}
</style>
<style>
Expand Down Expand Up @@ -172,33 +162,24 @@
</head>

<body>
<section id="status">
<h4>Status</h4>
<div class="info-container">
<button id="check-binary">Verify yt-dlp binary</button>
<div class="binary-msg" id="binary-desc"></div>
<div class="binary-msg" id="binary-version"></div>
<button id="download-binary">Download latest yt-dlp</button>
<div class="download-container">
<div id="downloading">
<div class="message">
Downloading yt-dlp. This may take minutes depending on your connection speed.
</div>
<div class="spinner">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<div id="download-error"></div>
<div id="download-info"></div>
<section id="yt-dlp">
<h4>Yt-dlp</h4>
<button id="verify-binary">Verify Installation</button>
<button id="update-binary">Update Now</button>
<div id="ytdlp-spinner-container" class="spinner-container">
<div id="ytdlp-spinner-message" class="spinner-message"></div>
<div class="spinner">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<div id="ytdlp-result" class="result-container"></div>
</section>
<section id="downloads">
<h4>Downloads</h4>
<div id="content"></div>
<div id="download-content" class="result-container"></div>
</section>
</body>

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 15 additions & 20 deletions pref.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,13 @@

<body>
<div class="pref-section">
Use custom youtube-dl/yt-dlp:
<label>
Custom yt-dlp path:
<input type="text" data-pref-key="ytdl_path" style="width: 100%; margin-top: 2px" />
</label>
<p class="small secondary pref-help">
Enter the path to the youtube-dl or yt-dlp binary.
If you are using Homebrew, the path is usually <code>/opt/homebrew/bin/yt-dlp</code> for Apple Sillion Macs and
<code>/usr/local/bin/yt-dlp</code> for Intel Macs.
Path to the executable. If in $PATH, just its name.
</p>
<div style="margin-top: 2px">
<input type="text" data-pref-key="ytdl_path" style="width: 100%; margin-top: 2px" />
</div>
</div>
<div class="pref-section">
Default video and audio quality:
Expand All @@ -67,19 +65,19 @@
<div>
<label><input type="radio" name="video_quality" value="use_max" data-pref-key />
Video not larger than:</label>
<input type="number" data-pref-key="max_video_height" style="width: 4em" />
<input type="number" data-pref-key="max_video_height" style="width: 4.5em" />
p
</div>
<div>
<label><input type="radio" name="video_quality" value="custom" data-pref-key />
Custom youtube-dl format:</label>
Custom yt-dlp format:</label>
<input type="text" data-pref-key="custom_ytdl_format" />
</div>
</div>
</div>
<div class="pref-section">
<label>
Excluded URLs:
URL blacklist:
<div style="margin-top: 2px">
<input type="text" data-pref-key="excluded_urls" style="width: 100%; margin-top: 2px" />
</div>
Expand All @@ -88,32 +86,30 @@
<div class="pref-section">
<label>
<input type="checkbox" data-type="bool" data-pref-key="include_subs" />
Include subtitles
Include subtitle(s)
</label>
<div style="margin-top: 4px;"></div>
<label style="margin-left: 16px;">
<input type="checkbox" data-type="bool" data-pref-key="include_auto_subs" />
Also include auto-generated subtitles
Also include auto-generated subtitle
</label>
</div>
<div class="pref-section">
<label>
<input type="checkbox" data-type="bool" data-pref-key="try_ytdl_first" />
Try youtube-dl first
Try yt-dlp first
</label>
<p class="small secondary pref-help">
Try parsing the URL with youtube-dl first, instead of the default where
it's only after mpv failed to open it.
Parse the URL with yt-dlp first, instead of (the default) mpv.
</p>
</div>
<div class="pref-section">
<label>
<input type="checkbox" data-type="bool" data-pref-key="use_manifest" />
Use manifest URL
Use master manifest URL
</label>
<p class="small secondary pref-help">
Use the master manifest URL for formats like HLS and DASH, if available,
allowing for video/audio selection at runtime.
Access the master manifest URL, if available, to fetch all available video/audio qualities.
</p>
</div>
<div class="pref-section">
Expand All @@ -123,8 +119,7 @@
spellcheck="false" style="width: 100%; margin-top: 2px" />
</label>
<p class="small secondary pref-help">
Additional raw options to pass to youtube-dl/yt-dlp, for example:<br>
<code>--write-auto-sub --sub-langs en</code>
Additional options to pass to yt-dlp.
</p>
</div>
</body>
Expand Down
60 changes: 8 additions & 52 deletions src/binary.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,18 @@
import { opt } from "./options";

const { core, console, http, file, utils } = iina;
const { core, console, utils } = iina;

const YTDLP_URL = "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos.zip";

export async function downloadYTDLP() {
const tempID = new Date().getTime();
const downloadedZip = utils.resolvePath(`@data/yt-dlp_${tempID}.zip`);
const unzipFolder = utils.resolvePath(`@data/yt-dlp_${tempID}`);
const destFolder = utils.resolvePath(`@data/yt-dlp`);
let errorMessage = null;
try {
console.log(`Downloading yt-dlp to ${downloadedZip}`);
await http.download(YTDLP_URL, downloadedZip);
const res = await utils.exec("/bin/bash", [
"-c",
`
TARGET="${destFolder}";
rm -rf "${destFolder}_*";
if [ -e "$TARGET" ] && [ ! -d "$TARGET" ] && [ -f "$TARGET" ]; then
rm -rf "$TARGET";
fi;
if [ ! -e "$TARGET" ]; then
mkdir -p "$TARGET";
fi;
unzip "${downloadedZip}" -d "${unzipFolder}" &&
rm -rf "$TARGET"/* &&
mv "${unzipFolder}"/* "$TARGET"/ &&
rm "${downloadedZip}" &&
xattr -cr "$TARGET"
`,
]);
if (res.status !== 0) {
throw new Error(`Failed to unzip yt-dlp: ${res.stderr}`);
}
} catch (e) {
console.error(e.toString());
errorMessage = e.toString();
} finally {
try {
if (file.exists(downloadedZip)) file.delete(downloadedZip);
if (file.exists(unzipFolder)) file.delete(unzipFolder);
} catch (e1) {
console.error("Failed to delete temp files: " + e1.toString());
}
}
return errorMessage;
export async function updateBinary() {
return await utils.exec("iina-ytdl", ["-U"]);
}

export function findBinary(): string {
let path = "youtube-dl";
const searchList = [opt.ytdl_path, "@data/yt-dlp/yt-dlp_macos", "yt-dlp", "youtube-dl"];
export function findBinary(): string | null {
const searchList = [opt.ytdl_path, "iina-ytdl"];
for (const item of searchList) {
if (utils.fileInPath(item)) {
console.log(`Found youtube-dl; using ${item}`);
path = item;
break;
console.log(`Found binary at ${item}`);
return item;
}
}
return path;
return null;
}
Loading