-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
41 changed files
with
439 additions
and
43 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
--- | ||
title: "Minimalistic SwiftUI GUI for Yt-dlp" | ||
date: 2024-01-13T14:00:23+02:00 | ||
description: This post is about my new SwiftUI tool that makes it easier to download from websites using yt-dlp. | ||
draft: false | ||
tags: [swift, swiftui, macos] | ||
--- | ||
|
||
## Introduction | ||
|
||
Yt-dlp and ffmpeg and two of my favorite command-line tools. But I keep having to look up how to use them! For this reason, I made a simple SwiftUI GUI that has three simple commands built-in. The user only has to choose and output folder and a file type (mp3 [audio only], opus [audio only] and mkv [audio and video]) and click the download button. The binaries for yt-dlp and ffmpeg are downloaded from the most official sources I could find at runtime. My GUI is open-source and available at my [GitHub repo](https://github.com/downIoads/swiftui-ytdl), but you have to build it yourself in Xcode. It supports light/dark mode (system setting) and is designed to be as minimalistic as possible. | ||
|
||
## Screenshots | ||
![targets](/images/ytdl/light1.png "Light mode pic 1") | ||
![targets](/images/ytdl/light2.png "Light mode pic 2") | ||
![targets](/images/ytdl/light3.png "Light mode pic 3") | ||
![targets](/images/ytdl/dark1.png "Dark mode pic 1") | ||
![targets](/images/ytdl/dark2.png "Dark mode pic 2") | ||
![targets](/images/ytdl/dark3.png "Dark mode pic 3") | ||
|
||
## Conclusion | ||
|
||
In just a few lines of code, you can make nice looking GUIs on macOS. I did this project to get a bit better at basic SwiftUI, and it was lots of fun! The main challenge was sandboxing which is required if anyone would want to publish a macOS app on the App Store (which I do not intend as it makes use of ffmpeg with its complicated LGPL license and various codecs etc.): I disabled sandboxing, because you are not allowed to run a binary (e.g. yt-dlp) at runtime, if the sandbox created this binary (e.g. by downloading). This was not obvious to me, as the hash of the binary was the same as if you had normally downloaded. But macOS keeps track of which files the sandbox touches and then does not allow execution of these files. Only the command | ||
```bash | ||
spctl --assess --type execute ./filename | ||
``` | ||
gave the info I needed: "File created by an AppSandbox, exec/open not allowed". I did not even know that this is a thing, as the hash and file permissions of the binary are the same as if you had downloaded outside the sandbox. The difference only becomes clear when you run | ||
```bash | ||
stat ./filename | ||
``` | ||
on the binary that the sandbox downloaded and the binary that you downloaded manually. Only then, you can see that the file sizes are different. This is interesting, as running | ||
```bash | ||
shasum -a 256 ./filename | ||
``` | ||
will result in the same hash for both files. After removing the sandbox permission (which I do not need for private use), everything worked perfectly. Below you can see some testing I did: | ||
![targets](/images/ytdl/sandbox-noExec1.png "Hashes and permissions are the same, but one can not be executed") | ||
![targets](/images/ytdl/sandbox-noExec2.png "Spctl and stats commands made me understand why this is happening") | ||
|
||
I did learn a lot about sandboxing on macOS (in fact it took more time than writing the actual GUI code) but it was interesting to learn something new. I know that you can bundle/embed the binaries into the application, but then I would have to distribute the binaries myself, which I want to avoid. All in all, a cool project with a resulting program that I am already frequently using! :) |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<!DOCTYPE html> | ||
<html><head> | ||
<meta charset="utf-8" /> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Minimalistic SwiftUI GUI for Yt-dlp - Blog for Tech Enjoyers</title><link rel="icon" type="image/png" href=https://www.pngmart.com/files/23/Nerd-Emoji-PNG.png /><meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<meta name="description" content="This post is about my new SwiftUI tool that makes it easier to download from websites using yt-dlp." /> | ||
<meta property="og:image" content=""/> | ||
<meta property="og:title" content="Minimalistic SwiftUI GUI for Yt-dlp" /> | ||
<meta property="og:description" content="This post is about my new SwiftUI tool that makes it easier to download from websites using yt-dlp." /> | ||
<meta property="og:type" content="article" /> | ||
<meta property="og:url" content="https://example.com/posts/swiftui-ytdl/" /><meta property="article:section" content="posts" /> | ||
<meta property="article:published_time" content="2024-01-13T14:00:23+02:00" /> | ||
<meta property="article:modified_time" content="2024-01-13T14:00:23+02:00" /> | ||
|
||
<meta name="twitter:card" content="summary"/><meta name="twitter:title" content="Minimalistic SwiftUI GUI for Yt-dlp"/> | ||
<meta name="twitter:description" content="This post is about my new SwiftUI tool that makes it easier to download from websites using yt-dlp."/> | ||
<script src="https://example.com/js/feather.min.js"></script> | ||
|
||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@1,500&display=swap" rel="stylesheet"> | ||
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans&display=swap" rel="stylesheet"> | ||
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet"> | ||
|
||
|
||
<link rel="stylesheet" type="text/css" media="screen" href="https://example.com/css/main.af0932513936b0cde7d4a0d5917aa65438df9a57b01fb2769e2be4bdc492944f.css" /> | ||
<link id="darkModeStyle" rel="stylesheet" type="text/css" href="https://example.com/css/dark.726cd11ca6eb7c4f7d48eb420354f814e5c1b94281aaf8fd0511c1319f7f78a4.css" disabled /> | ||
|
||
|
||
|
||
</head><body> | ||
<div class="content"><header> | ||
<div class="main"> | ||
<a href="https://example.com/">Blog for Tech Enjoyers</a> | ||
</div> | ||
<nav> | ||
|
||
<a href="/posts">Posts</a> | ||
|
||
<a href="/about">About</a> | ||
|
||
<a href="/tags">Tags</a> | ||
|
||
| <a id="dark-mode-toggle" onclick="toggleTheme()" href=""></a> | ||
<script src="https://example.com/js/themetoggle.js"></script> | ||
|
||
</nav> | ||
</header> | ||
<main> | ||
|
||
<article> | ||
<div class="title"> | ||
<h1 class="title">Minimalistic SwiftUI GUI for Yt-dlp</h1> | ||
<div class="meta">Posted on Jan 13, 2024</div> | ||
</div> | ||
|
||
|
||
<aside> | ||
<hr> | ||
Table of Contents: | ||
<nav id="TableOfContents"> | ||
<ul> | ||
<li><a href="#introduction">Introduction</a></li> | ||
<li><a href="#screenshots">Screenshots</a></li> | ||
<li><a href="#conclusion">Conclusion</a></li> | ||
</ul> | ||
</nav> | ||
<hr> | ||
</aside> | ||
|
||
|
||
<section class="body"> | ||
<h2 id="introduction">Introduction</h2> | ||
<p>Yt-dlp and ffmpeg and two of my favorite command-line tools. But I keep having to look up how to use them! For this reason, I made a simple SwiftUI GUI that has three simple commands built-in. The user only has to choose and output folder and a file type (mp3 [audio only], opus [audio only] and mkv [audio and video]) and click the download button. The binaries for yt-dlp and ffmpeg are downloaded from the most official sources I could find at runtime. My GUI is open-source and available at my <a href="https://github.com/downIoads/swiftui-ytdl">GitHub repo</a>, but you have to build it yourself in Xcode. It supports light/dark mode (system setting) and is designed to be as minimalistic as possible.</p> | ||
<h2 id="screenshots">Screenshots</h2> | ||
<p><img src="/images/ytdl/light1.png" alt="targets" title="Light mode pic 1"> | ||
<img src="/images/ytdl/light2.png" alt="targets" title="Light mode pic 2"> | ||
<img src="/images/ytdl/light3.png" alt="targets" title="Light mode pic 3"> | ||
<img src="/images/ytdl/dark1.png" alt="targets" title="Dark mode pic 1"> | ||
<img src="/images/ytdl/dark2.png" alt="targets" title="Dark mode pic 2"> | ||
<img src="/images/ytdl/dark3.png" alt="targets" title="Dark mode pic 3"></p> | ||
<h2 id="conclusion">Conclusion</h2> | ||
<p>In just a few lines of code, you can make nice looking GUIs on macOS. I did this project to get a bit better at basic SwiftUI, and it was lots of fun! The main challenge was sandboxing which is required if anyone would want to publish a macOS app on the App Store (which I do not intend as it makes use of ffmpeg with its complicated LGPL license and various codecs etc.): I disabled sandboxing, because you are not allowed to run a binary (e.g. yt-dlp) at runtime, if the sandbox created this binary (e.g. by downloading). This was not obvious to me, as the hash of the binary was the same as if you had normally downloaded. But macOS keeps track of which files the sandbox touches and then does not allow execution of these files. Only the command</p> | ||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>spctl --assess --type execute ./filename | ||
</span></span></code></pre></div><p>gave the info I needed: “File created by an AppSandbox, exec/open not allowed”. I did not even know that this is a thing, as the hash and file permissions of the binary are the same as if you had downloaded outside the sandbox. The difference only becomes clear when you run</p> | ||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>stat ./filename | ||
</span></span></code></pre></div><p>on the binary that the sandbox downloaded and the binary that you downloaded manually. Only then, you can see that the file sizes are different. This is interesting, as running</p> | ||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>shasum -a <span style="color:#ae81ff">256</span> ./filename | ||
</span></span></code></pre></div><p>will result in the same hash for both files. After removing the sandbox permission (which I do not need for private use), everything worked perfectly. Below you can see some testing I did: | ||
<img src="/images/ytdl/sandbox-noExec1.png" alt="targets" title="Hashes and permissions are the same, but one can not be executed"> | ||
<img src="/images/ytdl/sandbox-noExec2.png" alt="targets" title="Spctl and stats commands made me understand why this is happening"></p> | ||
<p>I did learn a lot about sandboxing on macOS (in fact it took more time than writing the actual GUI code) but it was interesting to learn something new. I know that you can bundle/embed the binaries into the application, but then I would have to distribute the binaries myself, which I want to avoid. All in all, a cool project with a resulting program that I am already frequently using! :)</p> | ||
|
||
</section> | ||
|
||
<div class="post-tags"> | ||
|
||
|
||
<nav class="nav tags"> | ||
<ul class="tags"> | ||
|
||
<li><a href="/tags/swift">swift</a></li> | ||
|
||
<li><a href="/tags/swiftui">swiftui</a></li> | ||
|
||
<li><a href="/tags/macos">macos</a></li> | ||
|
||
</ul> | ||
</nav> | ||
|
||
|
||
</div> | ||
</article> | ||
|
||
|
||
|
||
</main> | ||
<footer> | ||
<div style="display:flex"></div> | ||
<div class="footer-info"> | ||
2024 <a | ||
href="https://github.com/athul/archie">Archie Theme</a> | Built with <a href="https://gohugo.io">Hugo</a> | ||
</div> | ||
</footer> | ||
|
||
|
||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.