Misc
A section dedicated to other applications and tools worth getting to know.
FFmpeg
Installing ffmpeg on macOS
brew install ffmpeg
Filetype Conversions
Conversions between filetypes is usually as easy as the following example
Encode an MP3 audio file
input.mp3as an AIFF file, and save it asoutput.aiffffmpeg -i 'input.mp3' 'output.aiff'Convert an MP3 file
song.mp3into M4A format:Using
avconvert:avconvert -p 'PresetAppleM4A' -s 'song.mp3' -o 'song.m4a'Using
ffmpeg:ffmpeg -i 'song.mp3' -c:a aac -c:v copy 'book.m4a'
Encode an MP4 video file
input.mp4as a GIF file, and save it asoutput.gifffmpeg -i 'input.mp4' 'output.gif'Encode an audiobook AAX file
input.aaxas a M4B file, and save it asoutput.m4b# Assuming you know the activation bytes of your file... ffmpeg -activation_bytes ACTIVATION_BYTES -i BOOK.aax -c copy BOOK.m4bConvert an audiobook from MP3 to M4B:
ffmpeg -i BOOK.mp3 -c:a aac -c:v copy BOOK.m4bmp3='book.mp3' m4a=${mp3:r}.m4a m4b=${m4a:r}.m4b jpeg=${mp3:r}.jpeg # Extract the cover art from an MP3 file ffmpeg \ -i ${mp3} \ -map 0:v \ -map -0:V \ -c copy \ ${jpeg} # https://stackoverflow.com/questions/18710992/how-to-add-album-art-with-ffmpeg # Convert the audiobook from MP3 to M4B # preserving the existing cover art ffmpeg \ -i ${mp3} \ -i ${jpeg} \ -map 0:0 \ -map 1:0 \ -c:a aac \ -c:v copy \ -id3v2_version 4 \ -metadata:s:v title="Album cover" \ -metadata:s:v comment="Cover (front)" \ ${m4b}Convert each MP3 audio file in the current folder as an M4A file, save it with the same name, (i.e.,
example.mp3→example.m4a)# For each audiobook in the folder for audiobook in *.mp3; do ffmpeg -i ${audiobook} -c:a aac -c:v copy ${audiobook:r}.m4a; doneDownload an M3U file, and convert all the binary chunks into an MP4 file:
ffmpeg -i LINK.m3u -bsf:a aac_adtstoasc -vcodec copy -c copy -crf 50 FILENAME.mp4
Useful Arguments
-f <format>: Forcibly specify the input/output format, (usually set automatically)-y: Automatically overwrite files without asking-i <ifile>: Specify an input filename-loglevel panic: Reduce the verbosity offfmpeg(in this case, silence it)loglevel quiet -stats: Don't print any output other than the a one-line "progress report" of the conversion that's currently underway-activation_bytes <hash>: The hexadecimal activation bytes used to decrypt Audible's DRMOverwrite the file
exists.mp4without prompting for confirmationtouch exists.mp4 ffmpeg -i 'input.mp4' -y 'exists.mp4'
Merging audio files
Concatenate multiple MP3 files together, into a single merged MP3 file
Example 1
ls *.mp3 | sort | sed 's/^/file /g' > 'files.txt' ffmpeg -f 'concat' -i 'files.txt' -c copy 'merged.mp3'Example 2
# Create a string to specify which files to concatenate ifile="concat:one.mp3|two.mp3|three.mp3" # Concatenate the files ffmpeg -i ${ifile} -c:a copy -map_metadata 0:1 ofile.mp3
Extract the cover art from music file
ffmpeg -i MUSIC_FILE.m4a -map 0:v -map -0:V -c copy 'cover_art.jpg'Convert every MKV file in a folder to MP4 format
for file in ~/episodes/*.mkv; do ffmpeg -i ${file} ${file:0:(-4)}.mp4; doneUse the built-in camera to take a photo
ffmpeg \ -f 'avfoundation' \ -video_size '1280x720' \ -framerate 30 \ -i 0 \ -vframes 1 \ './output.jpg'Use the built-in microphone to record audio
# `-f` force the use of AVFoundation format # `-i :1` record audio from the built-in microphone # `-t 10` record audio for 10 seconds ffmpeg -f avfoundation -i ":1" -t 10 'output.mp3'Use the system default camera and microphone to record a video
typeset -i duration=4 typeset -i framerate=30 ffmpeg -f 'avfoundation' \ -video_size '1280x720' \ -framerate ${framerate} \ -i '0:0' \ -vframes $((${framerate}*${duration})) \ './output.mkv'Re-encode video file into H.265 with minimal loss
ffmpeg \ -i 'input.mkv' \ -c:a 'copy' \ -c:v 'libx265' \ -preset 'slow' \ -crf 18 \ -aq-mode 3 \ -pix_fmt 'yuv420p10le' \ 'output.mkv'
gifski
Stumbled upon this cool utility called Gifski, an open source tool for converting videos into GIFs. It's written in Rust, and is notably faster at converting videos into GIFs than ffmpeg is on its own. It also allows a lot of flexibility in the quality/framerate of the final GIF, and can produce much smaller file size. I'm a huge fan.
Here's an example of using the gifski CLI.
First, extract the frames from a video (in this case, 24 frames per second) into a temporary folder:
ffmpeg -i INFILE.mp4 -vf fps=24/1 /tmp/FRAMES-%04d.png
Next, collect all of those frames and compile them into a GIF using gifski:
gifski /tmp/FRAMES-*.png --fps=24 --quality=80 --output OUTFILE.gif
Lastly, clean up those intermediary frame-files that we made in the first step:
rm -f /tmp/FRAMES-*.png
keka
Keka is an amazing application, that was suggested to me by one of my IT professors at USC.
Getting Started
brew cask install keka kekadefaultapp
Then, open keka, configure your preferences, and set keka to be your default app. Now you can compress and decompress any file on your computer by pressing ⌃ ⇧ K
keka will automatically know which action to perform based on the file it received as input. It will use the configurations you specified in the app. I recommend GNU's .gzip files because they use an algorithm that is superior in compression to the one used in Microsoft's .zip filetype. Also, because tar uses gzip so it's a good idea to get started.
figlet
figlet I/O
You can use figlet to convert any string into a lovely piece of ASCII art.
figlet 'Hello World'
Output:
_ _ _ _ _
| |__ ___| | | ___ __ _____ _ __| | __| |
| '_ \ / _ \ | |/ _ \ \ \ /\ / / _ \| '__| |/ _` |
| | | | __/ | | (_) | \ V V / (_) | | | | (_| |
|_| |_|\___|_|_|\___/ \_/\_/ \___/|_| |_|\__,_|
Window Management Applications
This is a great app that my friend Russel Wakugawa showed me. If you work on a laptop, managing your screen space is important. Unfortunately there aren't many built-in keybindings to resize and maximize applications. Although the gesture-based resizing is graceful and pretty, they aren't very useful because the animations are so slow.
An important update: Spectacle is no longer maintained. I encourage you to use Moom as an alternative instead. I've found it to be even better than Spectacle
lsyncd
The lsyncd program allows bi-directional syncing of files between a local and remote host. If you have a folder that you make changes to often, it would be useful to just change once, update everywhere.
Installing
lsyncd# macOS brew install lsyncd # Debian distro apt install lsyncd
Mutt
Installing
mutt# Using Mutt brew install mutt # Using NeoMutt brew install neomuttExample configuration file
set realname = "Tommy Trojan" set smtp_url = "smtp://tommytrojan@smtp.mail.me.com:587/" set smtp_pass = "1234-abcd-1234-abcd" set smtp_authenticators = 'gssapi:login' set imap_user = "tommytrojan" set imap_pass = "1234-abcd-1234-abcd" set from = "tommytrojan@icloud.com" set folder = "imaps://tommytrojan@imap.mail.me.com:993" set spoolfile = "+INBOX" set postponed = "+Drafts" set record = "+Sent Messages" set trash = "+Trash" unset beep_new # Don't beep for new messages set imap_pipeline_depth = 0 set header_cache = "$XDG_CACHE_HOME/mutt/headers" set message_cachedir = "$XDG_CACHE_HOME/mutt/bodies" set certificate_file = "$XDG_CACHE_HOME/mutt/certificates" set sort=reverse-date-sent set assumed_charset="utf-8" set attach_charset="utf-8" set charset="utf-8" # Don't try to add a copy to sent folder (throws error in batch mode) set copy = no # Don't include original message in reply unset include # Don't show the help menu at the top of the screen unset help # Configure keybindings bind index = noop bind index g first-entry bind pager g top bind index * noop bind index G last-entry bind pager G bottom bind pager <Down> next-line bind pager j next-line bind pager <Up> previous-line bind pager k previous-line bind index o display-message bind index n noop bind index m mail bind index,pager \Cwq quit # Configure inbox style color indicator brightblue default
ImageMagick
Compress a PDF to a smaller size file
convert 'input.pdf' -format 'PDF' -quality 10 'output.pdf'Combine multiple images into a single PDF
magick *.jpg combined.pdf
Hugo
Generate bash autocompletions for Hugo
sudo hugo gen autocomplete --type bash --completionfile /usr/local/etc/bash_completion.d/hugo.sh
JetBrains
The jetbrains:// URL scheme
There's a hidden, undocumented feature in JetBrains that allows you to open
up an existing project via Jetbrains Toolbox using the jetbrains:// URL scheme. Here's an example:
jetbrains://idea/navigate/reference?project=PROJECT
Clicking on this link will open up a project named PROJECT in the IDE if it is found. For instance, if you have a project named dotfiles, you can open it up by clicking on this link:
jetbrains://idea/navigate/reference?project=dotfiles
CLI Subcommands
Useful subcommands exist for the following IDE command-line interfaces:
If you specify a directory with an existing project, the IDE opens this project.
If you open a directory that is not a part of a project, the IDE adds the .idea directory to it, making it a project.
Open a project (this one) in Webstorm without showing the splash loading screen
webstorm ~/.wiki --nosplash --wait
Path Variables
Pre-defined path variables include
$USER_HOME$,$PROJECT_DIR$, and$MODULE_DIR$
TinyPNG
REST APIs
An Application Programming Interface or API is a set of rules that lets programs talk to each other, exposing data and functionality across the internet in a consistent format.
APIs accessed through HTTP typically use Representational State Transfer or REST. This is an architectural pattern that describes how distributed systems can expose a consistent interface. When people use the term ‘REST API,’ they are generally referring to an API accessed via HTTP protocol at a predefined set of URLs.
These URLs represent various resources - any information or content accessed at that location, which can be returned as JSON, HTML, audio files, or images. Often, resources have one or more methods that can be performed on them over HTTP, like GET, POST, PUT and DELETE.
Add the HTTP header
Authorization: Basic ${token}Generate HTTP header for basic authentication by base64 encoding the username and password
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==username='Alladin' password='open sesame' token=$(base64 -w 0 < =(<<<${username}:${password})) auth="Authorization: Basic ${token}"- Copy it to clipboard immediately
pbcopy < =(<<<"Basic $(base64 -w 0 < =(<<<${username}:${password}))")
Twilio
How to look up a phone number using the Twilio CLI
twilio api:lookups:v1:phone-numbers:fetch --phone-number '+15551234567' --type=carrier --type=caller-name
GitHub
When creating a linking a file hosted on GitHub, you can add a highlight to the relevant lines of code using a
Selenium
Enabling the safari webdriver:
safaridriver --enableBasic procedure to create a webdriver using Selenium:
#Simple assignment from selenium.webdriver import Safari driver = Safari() driver.get('https://google.com') print(driver.current_url)Quitting the webdriver:
driver.quit()
WebP
WebP is a new image format for the web. Well, new-ish. The standard that succeeds WebP is called AVIF, which is already supported by both Chrome and Firefox.
Getting Started
Installation
Homebrew installation
Installing
cwebpanddwebpusing Homebrew:brew install webp
Manual installation
The version installed from Homebrew opts out of some fun features. For instance, it doesn't include the option to convert GIF files into WebP. For this reason, I've decided to learn how to build this library from source, and have included the instructions below for others to follow along:
Install latest version of
libwebp:mkdir -p ~/.local/opt/libwebp url='https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.1.0-mac-10.15.tar.gz ' curl ${url} > ~/Downloads/libwebp.tgz tar xf ~/Downloads/libwebp.tgz -C ~/.local/opt mv ~/.local/opt/libwebp{*(/),} < =(<<<'path=(~/.local/opt/libwebp/bin ${path})') >> ~/.zshrcEnable optional packages in the
libwebpinstallation:./configure --prefix=${HOME}/.local --enable-everything
cwebp Encoder
Compress PNG file
image.pngto WebP fileimage.webp(with quality range of 80)cwebp -q 80 image.png -o image.webpCompress PNG file
image.pngto WebP fileimage.webp# quality: 100 # width: 1920 # height: auto-fit cwebp -q 100 -resize 1920 0 image.png -o image.webpCompress JPG file
image.jpgto WebP fileimage.webpcwebp \ -noalpha \ -hint 'photo' \ -jpeg_like \ -m 6 \ -q 90 \ -alpha_filter 'best' \ -metadata 'all' \ -mt \ 'image.jpg' \ -o 'image.webp'
Crop a
500x1000photo so that10pxare cut off from all four sidescwebp \ -crop 10 10 480 980 \ image.jpg \ -o image.webp
dwebp Decoder
Decode WebP file
image.webpto PNG fileimage.pngdwebp image.webp -o image.png
Utility Commands
Convert a file to WebP, with the same filename, but with
.webpextensioncwebp ~/Downloads/file.jpg -o !{#^:r}.cwebpConvert the most recently created file
cwebp ~/Downloads/*(om[1]) -o image.cwebp
Looping
Compress a series of images into the animated WebP format
img2webp -lossy -d 1000 -m 6 -loop 0 'one.jpg' 'two.jpg' -o ~/Downloads/mowgli.webp
AVIF
Instead of WebP, you can use AVIF. AVIF is an image file format specification for storing images compressed with AV1 in the HEIF container format. AVIF competes with HEIC, which uses the same container format (built upon ISOBMFF), but uses HEVC for compression instead of AV1.
Converting an image from PNG to AVIF:
image.png -o image.avif avifenc input.png output.avif
Slack
Slack supports URL Schemes, which they document on their developer API site
Link to a conversation with a specific user, in a particular workspace
user_id=W01543F37L3 workspace_id=T019B257FQT open "slack://user?team=${workspace_id}&id=${user_id}"
Fonts
Decompress WOFF2 font face into its original file format (TTF or OTF)
brew install woff2 woff2_decompress 'font.woff2'
Firefox
Hidden Keyboard Shortcuts
To copy the location behind a hyperlink, do the following:
- Hover the cursor over the link
- Right click (or ⌃ Left-Click)
- Type a
Google Chrome uses c, which is what you would normally expect to select a command titled Copy Link Address. If you're curious, you can check out why a was chosen. Personally, I feel it's a discussion worth reading.
Search Operators
Mozilla Firefox
When using the address bar to search, you can filter the results suggested using a set of special characters separated by spaces
| Operator | Searches for results in... |
|---|---|
^ | browsing history |
* | bookmarks |
+ | bookmarks with matching tags |
% | currently open tabs |
$ | in the URL |
? | in search suggestions |
# | with every term matching title/tag |
Search bookmarks for
mozilla* mozillaSearch browsing history for
react^ reactSearch for results containing
giphyin the URL$ giphy
about:config
These are some helpful settings to navigate webpages more quickly:
browser.display.focus_ring_on_anything = true
browser.display.focus_ring_style = 0
browser.display.focus_ring_width = 3
browser.display.show_focus_rings = true
accessibility.typeaheadfind = true
accessibility.typeaheadfind.flashBar = 0
accessibility.typeaheadfind.linksonly = true
accessibility.typeaheadfind.startlinksonly = true
Google Chrome
The shortcuts above require a little more configuration in order to be usable on Google Chrome. To be able to search bookmarks, you'll want to visit chrome://settings/searchEngines, add a search engine, and provide it with the URL chrome://bookmarks/?#q=%s. The %s should be provided as-is, but it will expand to contain the contents of your query when you are performing a search using this search engine.
You can search history as well. The process is very similar: simply repeat the steps outlined above, and provide the following URL: chrome://history/?#q=%s.
Quick Find
Some websites use / as the keyboard shortcut to focus the cursor on the main search bar of the page. The problem, however, is that Firefox uses / as the keyboard shortcut for Quick Find, and intercepts a user when they press /.
To disable the usage of / by Firefox
- Go to
about:config - Search for
accessibility.typeaheadfind.manual - Set its value to
false
youtube-dl
Custom config file location
youtube-dl --config-location FILE
yt-dlp
yt-dlp is a fork of youtube-dl with additional features and bug fixes.
Download a specific section of a video:
yt-dlp 'https://www.youtube.com/watch?v=HwyFHPTetPM&t=8943s' --download-sections '*2:28:00-2:33:00'My current config file (
~/.config/yt-dlp.conf):# Use a 16 Kilobyte buffer --buffer-size 16K # Use cookies from Google Chrome # --cookies-from-browser chrome # Download 10 fragments at a time --concurrent-fragments 10 # # Save all videos in the Downloads directory within the home directory --output ~/Downloads/%(title)s.%(ext)s # Prefer mp4/m4a over other formats # --format-sort res,ext:mp4:m4a # --force-overwrites # https://old.reddit.com/r/youtubedl/comments/163t8hj/ytdlp_settings_to_more_consistently_support_macos/ --format-sort vcodec:h264,res,acodec:m4a
QR Code Generator
Stumbled upon the amzqr project and I found it absolutely delightful.
Installing
amzqrpip install amzqrCreating a QR code with an image embedded inside of it:
amzqr -p IMAGE 'https://URL'
Visual Studio Code
Last year, Visual Studio Code made it possible for developers to open workspaces via application links. The syntax of the URL scheme is detailed below:
vscode://file/PATH
Convert an XLS file to CSV
The alasql command provides the capability of converting an XLS file into a CSV file.
You can invoke alasql using npx, since the underlying library is built in Node.
Convert an XLS file to CSV:
npx alasql "SELECT * INTO CSV('INPUT.csv', {headers:true}) FROM XLS('OUTPUT.xls', {headers:true})"
Reduce PDF File Size
gs \
-sDEVICE=pdfwrite \
-dCompatibilityLevel=1.4 \
-dDownsampleColorImages=true \
-dColorImageResolution=150 \
-dNOPAUSE \
-dBATCH \
-sOutputFile=OUTPUT.pdf \
INPUT.pdf