---
name: "ytfzf"
section: "5"
platform: "linux"
package: "ytfzf"
version: "2.6.2-2"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/ytfzf/5"
---

# ytfzf(5)

the configuration file for ytfzf.

## NAME

ytfzf - the configuration file for **ytfzf**.

## SYNOPSIS

*~/.config/ytfzf/conf.sh*

## DESCRIPTION

The configuration file is a *.sh* file and can be used as such. The file can be completely empty and **ytfzf** will still work with the default settings. The options should be set as environment variables and functions.

## CONFIGURATION FILES

Configuration files are stored in *$XDG\_CONFIG\_HOME/ytfzf (or $HOME/.config/ytfzf)*.

### conf.sh

A shell script that gets sourced into ytfzf when ytfzf is run.

### subscriptions

A file that is a list of links to youtube channel's video page, such as:

```
https://www.youtube.com/channel/UCtMVHI3AJD4Qk4hcbZnI9ZQ
```

Each link should be separated by a new line.

If a channel appears similar to "https://www.youtube.com/c/SomeOrdinaryGamers", run\
 ytfzf --channel-link="https://www.youtube.com/c/SomeOrdinaryGamers"\
 Before adding it to your subscriptions file

A comment can be created by having '#comment' on its own line or after a link. For example:

```
link-to-channel
#comment
link-to-channel #best channel
```

### scrapers

A folder that contains executable files that scrape websites See CUSTOM SCRAPERS for more information

## CONFIGURATION OPTIONS

### VARIABLES

conf.sh is used mainly for setting variables for **ytfzf**. If a variable has no default, that means it is set to an empty string.\
 To set a variable in conf.sh be sure to use\
 variable\_name="value"\
 leave out the $ at the start of the variable name.

Files and directories

- $**cache\_dir**

  The directory to store cache files in.\
   It is highly recommended to only change this if $\_\_is\_submenu is 0, or funky things could happen\
   *default:* $XDG\_CACHE\_HOME/ytfzf (or $HOME/.cache/ytfzf)

- $**hist\_file**

  The file to write watch history to if $enable\_hist is 1\
   It is highly recommended to only change this if $\_\_is\_submenu is 0, or funky things could happen\
   *default:* $cache\_dir/watch\_hist

- $**search\_hist\_file**

  The file to write search history to if $enable\_search\_hist is 1\
   *default:* $cache\_dir/search\_hist

How to play the selected videos.

- $**is\_detach**

  Whether or not to detach the video player from the terminal.\
   *default:* 0

- $**is\_audio\_only**

  Whether or not to only play audio.\
   *default:* 0

- $**url\_handler**

  The function/programs to handle the selected videos\
   It is recommended to not set this variable directly, but rather to use the command load\_url\_handler\
   See URL handlers for a list of built-in url handlers *default:* multimedia\_player

- $**yt\_video\_link\_domain**

  The domain to play youtube videos from (does not apply to odysee and peertube or youtube playlists)\
   If left blank, the value will be whatever invidious instance ytfzf chose\
   *default:* https://www.youtube.com

- $**info\_to\_print**

  The information to print instead of playing a video. The available options for this variable are:

  - *L* \| *l* \| *link*

    Print the URL of the selected videos.

  - *VJ* \| *vj* \| *video-json*

    Prints the json of the selected videos.

  - *J* \| *j* \| *json*

    Prints the json of all the videos in the search results.

  - *F* \| *f* \| *format*

    Prints the video format being used.

  - *R* \| *r* \| *raw*

    Prints the data of the selected videos, as appears in the menu.

- $**info\_wait\_action**

  The action to do when $info\_wait is 1.\
   Valid actions:

  - *q*

    quit (will go back to menu, if $is\_loop is 1).

  - *Q*

    quit regardless if loop is enabled or not.

  - *m*

    return to menu.\
     *default:* q

- **$**info\_wait

  Whether or not to wait for input after printing info.\
   *default:* 0

- $**video\_pref**

  The video preference to use for youtube-dl in mpv.\
   *default:* bestvideo

- $**audio\_pref**

  The audio preference to use for youtube-dl in mpv.\
   *default:* bestaudio

- $**ytdl\_pref**

  The preference to use for youtube-dl in mpv.\
   *default:* $video\_pref+$audio\_pref/best/$video\_pref/$audio\_pref

- $**url\_handler\_opts**

  Opts to pass to the url handler, by default this will pass extra opts to mpv. This can also be set in the config file with **url\_handler\_opts**

Menu options

- $**interface**

  The interface/menu to use.\
   It is recommended to not use this variable directly, instead use  **load\_interface interface-name**\
   Valid options.

  - *ext*

    same as -D

  - *scripting*

    is applied when -a, -r, or -A is used

  - *''*

    default

- $**external\_menu\_len**

  The amount of cols in interface\_ext, (-D)\
   *default:* 210

- $**fzf\_preview\_side**

  The side to show the preview in fzf.\
   Valid options:

  - *left*

    - *right*

    - *up*

    - *down*

    - *default:* left

    - $**preview\_window\_width**

  The amount of space to use for the fzf preview\
   *default:* 50%

- $**thumbnail\_viewer**

  The program to display images for thumbnail previews\
   It is recommended to not use this variable directly, instead use **load\_thumbnail\_viewer viewer**\
   Valid options:

  - *sixel*

    - *iterm2*

    - *kitty*

    - *sway*

    - *wayland*

    - *ueberzug*

    - *chafa*

    - *chafa-16*

    Uses chafa with 16 colors

  - *chafa-tty*

    Uses chafa with 4 colors

  - *catimg*

    - *catimg-256*

    Uses catimg with 256 colors

  - *mpv*

    Uses the mpv player to display the images\
     Works well with tiling window managers.

  - *imv*

    Similar to mpv, but is a dedicated image viewer

  - *swayimg*

    Only works on the sway wayland compositor

  - *swayimg-hyprland*

    Only works on the hyprland compositor. Uses swayimg to render images.

  - *default:* ueberzug

    - $**show\_formats**

  Whether or not to bring up the format selection menu.\
   *default:* 0

- $**format\_selection\_screen**

  The format that selection screen will use. Types:

  *simple* *normal*\
   *default:* simple

- $**format\_selection\_sort**

  The --format-sort to use in ytdl.\
   *default:* height

- $**enable\_submenus**

  Whether or not to enable submenus,\
   A submenu is a menu that appears after a playlist or channel is selected. (Currently only supported with youtube/invidious scraper) *default:* 1

- $**enable\_actions**

  Whether or not to enable actions such as submenus, and the back button.\
   *default:* 1

- **$**keep\_vars

  Whether or not options passed into ytfzf also get passed into submenus

- $**enable\_back\_button**

  Whether or not to enable back button in submenus. *default:* 1

- $**submenu\_opts**

  Options to use in submenus. *default:*

- $**submenu\_scraping\_opts**

  **DEPRECATED (use submenu\_opts instead)** Does the same thing as $submenu\_opts *default:*

- $**is\_sort**

  Whether or not to sort scraped videos by date in the menu *default:* 0

- $**fancy\_subs**

  Whether or not to have a separator between each subscription *default:* 0

- $**fancy\_subs\_left**

  The text to display on the left of the channel name when fancy\_subs is 1. *default:* -------------

- $**fancy\_subs\_right**

  The text to display on the right of the channel name when fancy\_subs is 1. *default:* $fancy\_subs\_left

- $**show\_thumbnails**

  Whether or not to show thumbnails in fzf.\
   *default:* 0

  **$**async\_thumbnails Whether or not to download thumbnails asynchronously.\
   Downloading asynchronously will open the menu before all thumbnails are downloaded. *default:* 0

- $**skip\_thumb\_download**

  Whether or not to skip thumbnail download.\
   *default:* 0

- $**thumbnail\_quality**

  Select the quality of the thumbnails. Currently only supports youtube (uses invidious api).\
   This does not work for the '**-cS**' scraper as it scrapes youtube not invidious (use '**SI**' instead).\
   For lower internet speeds it is recommended to use default.\
   Available options:

  - *maxres*

    - *maxresdefault*

    - *sddefault*

    - *high* (default)

    - *medium*

    - *default*

    - *start*

    The first frame of the video (low quality)

  - *middle*

    The middle frame of the video (low quality)

  - *end*

    The end frame of the video (low quality)

- $notify\_playing

  Whether or not to send a notification when a video is about to be played.\
   *default:* 0

- $**is\_loop**

  Whether or not to show the menu after the selected videos have stopped playing.\
   *default:* 0

- $**search\_again**

  Whether or not to make another search after fzf is closed.\
   *default:* 0

- $**selection\_meta\_key**

  The meta key for shortcuts that select a video.\
   *default:* alt

- $**download\_shortcut**

  The shortcut to download the selected videos.\
   *default:* $selection\_meta\_key-d

- $**video\_shortcut**

  The shortcut to watch the selected videos.\
   *default:* $selection\_meta\_key-v

- $**audio\_shortcut**

  The shortcut to listen to the selected videos.\
   *default:* $selection\_meta\_key-m

- $**detach\_shortcut**

  The shortcut to use the detach player.\
   *default:* $selection\_meta\_key-e

- $**print\_link\_shortcut**

  The shortcut to use to print the link.\
   *default:* $selection\_meta\_key-l

- $**show\_formats\_shortcut**

  The shortcut to show formats before playing the video.\
   *default:* $selection\_meta\_key-f

- $**info\_shortcut**

  The shortcut to get all info about the selected video.\
   *default:* $selection\_meta\_key-i

- $**search\_again\_shortcut**

  The shortcut to make another search.\
   *default:* $selection\_meta\_key-s

- $**action\_meta\_key**

  The meta key for shorcuts that do something\
   *default:* ctrl

- next\_page\_action\_shortcut

  The shortcut to scrape the next page.\
   *default:* $action\_meta\_key-p

- $**shortcut\_binds**

  The keys to listen for in fzf.\
   *default:* Enter,double-click,$download\_shortcut, $video\_shortcut,$detach\_shortcut,$print\_link\_shortcut,$show\_formats\_shortcut, $info\_shortcut,$search\_again\_shortcut,$custom\_shortcut\_binds"

- $**custom\_shortcut\_binds**

  The custom shortcut keys. Automatically appended to $shortcut\_binds\
   If $shortcut\_binds is set manually, this must also manually be appended.

Auto selecting

- $**is\_auto\_select**

  Whether or not to auto select the first -n videos. (only works if $interface=scripting)\
   *default:* 0

- $**is\_random\_select**

  Whether or not to randomly select -n videos. (only works if $interface=scripting)\
   *default:* 0

- $**is\_specific\_select**

  Whether or not to select a specific video (use $ scripting\_video\_count to specify which) (only works if $interface=scripting)\
   *default:* 0

- $**scripting\_video\_count**

  The amount of videos to get with -a or -r.\
   *default:* 1

Scrapers

- $**scrape**

  The website to scrape by default. The currently supported options are:

  - *youtube*,

    - *youtube-trending*,

    - *youtube-subscriptions*,

    - *peertube*,

    - *odysee*/*lbry*.

    - *youtube-playlist*,

    - *youtube-channel*,

    - *invidious-channel*,

    - *video-recommended*,

    - *playlist/json-file*,

    The search will be a path to a json file laid out as described in VIDEO JSON FORMAT

  - *history*,

    - *url/U*,

    - *u*,

    - *M*/*multi*,

    - *comments*

    *default:* youtube

- $**multi\_search**

  Whether or not to enable multi search. *default:* 0

- $**search\_sort\_by**

  The attribute to sort by when searching.

  - *relevance* (default)

    - *rating* (youtube only)

    - *upload\_date*

    - *oldest\_first* (odysee only)

    - *view\_count* (youtube only)

    - $**search\_upload\_date**

  Search for videos within the last:

  - *hour*

    - *today*

    - *week*

    - *month*

    - *year*

    - $**search\_video\_duration**

  Whether or not to search for long or short videos. Possible options:

  - *short*

    - *long*

    - $**search\_result\_type**

  The type of results to get.

  - *video* (default)

    - *playlist*

    - *channel*

    - *all* (may not work on some instances)

    - $**nsfw**

  Whether or not to search for nsfw videos in odysee/O.\
   *default:* false

- $**search\_result\_features**

  The features to have on a video (comma separated).

  - *hd*

    - *subtitles*

    - *creative\_commons*

    - *3d*

    - *live*

    - *4k*

    - *360*

    - *location*

    - *hdr*

    - $**search\_region**

  The region (country code) to search. *default:* US

- $**invidious\_instance**

  The instance of invidious to use.\
   *default:* https://vid.puffyan.us

- $**pages\_to\_scrape**

  The amount of pages to scrape on youtube/invidious.\
   *default:* 1

- $**pages\_start**

  The starting page to scrape.\
   *default:* 1

- $**max\_thread\_count**

  The amount of threads that can be used while scraping youtube search, playlists, and channels. (this does not apply to the subscription scraper)\
   *default:* 20

- $**odysee\_video\_search\_count**

  The amount of videos to scrape on odysee.\
   *default:* 30

- $**sub\_link\_count**

  The amount of videos to scrape per channel when getting subscriptions.\
   *default:* 2

Misc

- $**gap\_space**

  The amount of space after the title in the thumbnail viewer menu. *default:*'                             '

- $**scrape\_search\_exclude**

  The scrapers to not ask for a search query.\
   Be sure to have a space at the end and beginning of the string.\
   *default:* youtube-subscriptions S SI T youtube-trending H history

- $**custom\_scrape\_search\_exclude**

  Extra scrapers to not ask for a search query.\
   This will automatically be appended to $ scrape\_search\_exclude.\
   In addition, you do not need spaces at the start, and end, only between scrapers. *default:*

- $**gap\_space**

  A number of spaces equal to half the width of your terminal\
   *default:* 115 spaces

- $**enable\_hist**

  Whether or not to keep track of history\
   *default:* 1

- $**enable\_search\_hist**

  Whether or not to keep track of search history\
   *default:* 1

- $**search\_source**

  How to get the search query. The builtin values for this are:

  - args

    Use commandline arguments as the search (default)

  - prompt

    Ask for a search via a prompt

  - hist

    Use search history.

  - next

    Used internally to use the next search in the list when **multi\_search** is enabled.

  - fn-args

    Used internally to use the function arguments passed to the function as the source.

- $**log\_level**

  How much debug information to log.

  - *2*

    Log everything

  - *1*

    Log only warnings and errors

  - *0*

    Log only errors

  - *default:* 2

    - $**thumbnail\_debug\_log**

  The log file for thumbnail debug information. *default:*/dev/null

- $**useragent**

  The useragent to use when scraping websites.\
   *default:* "Mozilla/5.0 (X11; Linux x86\_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.152 Safari/537.36"

- $**ytdl\_opts**

  The command-line options to pass to youtube-dl when downloading.

- $**ytdl\_path**

  Path to youtube-dl or a fork of youtube-dl for downloading.\
   If *yt-dlp* is installed that will be preferred over *youtube-dl*\
   *default:* youtube-dl

Option Parsing

- $**long\_opt\_char**

  The char to use for long opts.\
   *default:* -

- $**optstring**

  The string of options to use for the **getopts** function.\
   It is highly unrecommended to change this variable, unless you know what you are doing.\
   *default:* ac:de:fhi:lmn:qrstu:xADHI:LS:T:W:*$long\_opt\_char*:

- $**YTFZF\_CHECK\_VARS\_EXISTS**

  Whether or not to check if variables in the environment already exist when setting default options.\
   This option can not be set in the config, it must be set in your startup shell with export, or before running ytfzf such as: *YTFZF\_CHECK\_VARS\_EXISTS=0 ytfzf ...*\
   *default:*1

State\
 State values are **NOT** meant to be modified by the user.

- $**\_\_is\_submenu**

  Whether or not the script is in a submenu.

- $**\_\_is\_fzf\_preview**

  Whether or not the script is running to display an fzf preview

- \_\_scrape\_count

  The current scrape count starting at 1.

### FUNCTIONS

Sometimes a variable is not good enough, instead functions should be defined. To find the default value of these, check the source code by searching for *function\_exists "\<function\_you\_are\_looking\_for\>"*.

Menu related functions

- **external\_menu**()

  When $**interface** is *ext\_menu*, call this function instead of fzf.\
   This function takes 1 argument, a prompt string.

- **get\_sort\_by**()

  This function is called to get the value to sort by when $**is\_sort** is *1*.\
   This function takes in a line in the form of *"title    \|channel    \|duration    \|views    \|date    \|id"*.

- **data\_sort\_fn**()

  This function sorts the data that is being piped into it.\
   This function takes no arguments, all data is piped into it.

- **custom\_info\_wait\_action\_\<text\>**()

  This function is called if an unknown $info\_wait\_action is given or read.\
   \<text\> should be replaced with the text wanted from $info\_wait\_action, eg: *custom\_info\_wait\_e*.\
   This function takes no arguments.

- **video\_info\_text**()

  This function prints the text for the selection menu.\
   Must end with a new line,\
   The url must be the last thing printed.\
   This function takes no arguments, the relevant variables are listed here:

  ```
  title
  channel
  duration
  views
  date
  url
  ```

  It is recommended to check the script to see how each thing is printed.

- **thumbnail\_video\_info\_text**()

  This function prints text in the preview area of fzf when thumbnails are enabled.\
   Everything can be printed however you like.\
   This function takes no arguments, the relevant variables are listed here:

  ```
  title
  channel
  duration
  views
  date
  url
  ```

- **thumbnail\_video\_info\_text\_\<scraper\>**()

  This function is the same as thumbnail\_video\_info\_text() for the scraper specified.

- **on\_no\_thumbnail**()

  This function is run when no thumbnail is found

- **get\_ueberzug\_positioning\_left**()

  This function sets the variables, $width, $height, $x, and $y. $x, and $y, should represent cols and lines not pixels.\
   These variables will be used to position and size the image in the fzf preview when $fzf\_preview\_side is left.\
   This function takes 2 arguments:

  ```
  max_width
  max_height
  ```

- **get\_ueberzug\_positioning\_right**()

  This function sets the variables, $width, $height, $x, and $y. $x, and $y, should represent cols and lines not pixels.\
   These variables will be used to position and size the image in the fzf preview when $fzf\_preview\_side is right.\
   This function takes 2 arguments:

  ```
  max_width
  max_height
  ```

- **get\_ueberzug\_positioning\_up**()

  This function sets the variables, $width, $height, $x, and $y. $x, and $y, should represent cols and lines not pixels.\
   These variables will be used to position and size the image in the fzf preview when $fzf\_preview\_side is up.\
   This function takes 2 arguments:

  ```
  max_width
  max_height
  ```

- **get\_ueberzug\_positioning\_down**()

  This function sets the variables, $width, $height, $x, and $y. $x, and $y, should represent cols and lines not pixels.\
   These variables will be used to position and size the image in the fzf preview when $fzf\_preview\_side is down.\
   This function takes 2 arguments:

  ```
  max_width
  max_height
  ```

- **get\_swayimg\_positioning\_left**()

  This function sets the variables, $x, $y, $img\_w, and $img\_h. $x, and $y, should represent pixels.\
   These variables will be used to position and size the image in the fzf preview when $fzf\_preview\_side is left.\
   This function takes 8 arguments:

  ```
  img_w
  img_h
  max_width
  max_height
  max_height
  term_x
  term_y
  col_px_width
  line_px_height
  ```

- **get\_swayimg\_positioning\_right**()

  This function sets the variables, $x, $y, $img\_w, and $img\_h. $x, and $y, should represent pixels.\
   These variables will be used to position and size the image in the fzf preview when $fzf\_preview\_side is right.\
   This function takes 8 arguments:

  ```
  img_w
  img_h
  max_width
  max_height
  max_height
  term_x
  term_y
  col_px_width
  line_px_height
  ```

- **get\_swayimg\_positioning\_up**()

  This function sets the variables, $x, $y, $img\_w, and $img\_h. $x, and $y, should represent pixels.\
   These variables will be used to position and size the image in the fzf preview when $fzf\_preview\_side is up.\
   This function takes 8 arguments:

  ```
  img_w
  img_h
  max_width
  max_height
  max_height
  term_x
  term_y
  col_px_width
  line_px_height
  ```

- **get\_swayimg\_positioning\_down**()

  This function sets the variables, $x, $y, $img\_w, and $img\_h. $x, and $y, should represent pixels.\
   These variables will be used to position and size the image in the fzf preview when $fzf\_preview\_side is down.\
   This function takes 8 arguments:

  ```
  img_w
  img_h
  max_width
  max_height
  max_height
  term_x
  term_y
  col_px_width
  line_px_height
  ```

- **search\_prompt\_menu**()

  This function asks the user to make a search query, and sets the variable $\_search to the query.\
   This function is called if ytfzf is started without a search. (and is using the default interface)\
   This function takes no arguments.

- **search\_prompt\_ext**()

  This function asks the user to make a search query, and sets the variable $\_search to the query.\
   This function is called if ytfzf is started without a search. (and is using the -D flag)\
   This function takes no arguments.

- **quick\_menu**()

  This function should take user input and echo it back\
   This function is called with -f, and -q. Or any other time a generic menu is needed. (and the default interface is being used)\
   This function takes 1 argument, and takes input from stdin\
   1: The prompt to use.\
   stdin: the items to choose from (separated by new lines)

- **quick\_menu\_ext**()

  This function should do the same thing as quick\_menu()\
   This function is called when quick\_menu() would be called, but when -D is enabled.\
   This function takes 1 argument, and takes input from stdin\
   1: The prompt to use.\
   stdin: the items to choose from (separated by new lines)

- **info\_wait\_prompt**()

  The prompt to use when **info\_wait** is enabled.\
   This function takes no arguments.

- **info\_wait\_prompt\_ext**()

  Same as **info\_wait\_prompt()** when -D is used.\
   This function takes no arguments.

- **info\_wait\_prompt\_wrapper**()

  Call info\_wait\_prompt\_\<interface\_name\>\
   This function takes no arguments.

- **display\_text**()

  Print text to standard out.\
   This function takes an unlimited number of arguments to print.

- **display\_text\_ext**()

  Print text to standard out.\
   This function takes an unlimited number of arguments to print.

- **display\_text\_wrapper**()

  Call display\_text\_\<interface\_name\>\
   This function takes an unlimited number of arguments to print.

URL handlers

A URL handler is a function that handles the urls given,\
 URL handlers should take into account these modifier values, **$video\_pref ,**  **$is\_audio\_only ,**  and **$is\_detach**

Modifier variables will be piped into a URL handler to allow for URL handlers to be written in any language.\
 They will be piped in the order shown above separated by spaces.

- **multimedia\_player**()

  The handler that is called by default.\
   This function opens either video\_player() or audio\_player() depending on whether or not\
   $is\_audio\_only (-m) is enabled.\
   This function takes in an unlimited amount of arguments, each of which is a link to a video.

- **video\_player**()

  Plays the urls with a video player\
   This function takes in an unlimited amount of arguments, each of which is a link to a video.

- **audio\_player**()

  Plays the urls with an audio player\
   This function takes in an unlimited amount of arguments, each of which is a link to a video.

- **downloader**()

  Downloads the urls\
   This function takes in an unlimited amount of arguments, each of which is a link to a video.

- **get\_video\_format\_\<name\>()**

  A custom format selection screen\
   \<name\> should be the the wanted value of $format\_selection\_screen\
   This function should set ytdl\_pref\
   This function takes all urls as separate arguments.

- **on\_open\_url\_handler\_\<ext\>()**

  This function is run when **open\_url\_handler** is called, but before the url handler is actually opened.\
   This function takes an unlimited number of arguments, each argument is a url that was opened.

- **close\_url\_handler\_\<name\>**

  \<name\> should be the name of the url handler with - replaced with \_.\
   A function that happens after the url handler has finished playing.\
   The point of this function is to clean up anything that the url handler did.

- **after\_close\_url\_handler\_\<ext\>**

  A function that happens after the url handler has finished playing, and after **close\_url\_handler\_\<name\>** has happened.\
   If **is\_detach** is *1* this function may be called immediately after **url\_handler** opens.

Search History

- **handle\_search\_history()**

  This function handles appending the search to the given search file.\
   This function takes 2 arguments:

  - *1*

    The search to write

  - *2*

    The file to append to.

- **parse\_search\_hist\_file()**

  This function should parse the search history file, and print out each search separated by new lines.\
   The search history file will be fed through stdin.

- **get\_search\_from\_\<src\>()**

  If search\_source is set to \<src\> this function will be called. This function is expected to set the variable **\_search** to a search query.\
   This function takes no arguments.

- **on\_search**()

  This function gets called each time a website is scraped.\
   This function takes 2 arguments:

  ```
  1
      The search query
  2
      The current scrape
  ```

- **on\_search\_\<search\_query\>**()

  This function gets called each time a website is scraped if the current search matches \<search\_query\>.\
   This function takes 1 argument.

  - *1*

    The current scrape

Misc

- **get\_requested\_info\_\<name\>()**

  If \<name\> is in **info\_to\_print** this function will be run.\
   This function takes no arguments.

- **handle\_playing\_notifications()**

  This function sends a notification for the videos that are about to be played.\
   This function takes an unknown amount of urls as arguments.

- **post\_scrape()**

  This function happens after all scraping is complete

- **post\_scrape\_\<extension-name\>()**

  Same as post\_scrape() but for each extension

- **on\_opt\_parse**()

  This function gets called after an option is parsed, and sets variables based the options passed into it. A non 0 exit code will override the default behavior of a specific option.\
   This function takes 4 arguments:

  ```
  1
      The current option being parsed
  2
      The current option argument being parsed
  3
      The unmodified option being parsed.
      For an option such as -a, this value will be the same as $1.
      However, for every --long-option this value will be "-".
  4
      The unmodified option argument being parsed.
      For an option such as -c S, this value will be the same as $2.
      However, for every --long-option=value, this value will be -long-option=value.
  ```

- **on\_opt\_parse\_\<opt\_name\>**()

  This function gets called before an option is parsed. A non 0 exit code will override the default behavior of a specific option.\
   This function takes 3 arguments:

  - *1*

    The the optarg

  - *2*

    The raw opt

  - *3*

    The raw optarg

- **on\_post\_set\_vars**()

  This function gets called after all vars are set, and all opts are parsed.\
   This function takes no arguments.

- **on\_clean\_up**()

  This function is called when the script is cleaning up files from the search, or when the script exits.\
   This function takes no arguments.

- **usage**()

  This function calls the print\_help\_\<ext\> for each loaded extension.\
   This function takes no arguments.

- **handle\_custom\_keypresses**()

  This function gets called in the internal handle\_keypress() function. This function should return 0 to not override the default handle\_keypress() function.\
   This function takes 1 argument:

  ```
  1
      The key pressed.
  ```

- **handle\_custom\_post\_keypresses**()

  This function gets called in the internal handle\_post\_keypress() function, this function should return 0 to not override the default handle\_post\_keypress() function.\
   The job of this function is to undo the changes of the last keypress.\
   This function takes no arguments, it must get the keypress from $keypress\_file

- **handle\_keypress\_\***()

  The name of this function should replace the "\*" with the name of the shortcut, eg: *alt\_d*\
   in addition replace any "-" with "\_".\
   This function is called after handle\_custom\_keypresses() if it returned 0, and the shortcut is not a built-in shortcut.\
   This function takes 0 arguments.

- **handle\_post\_keypress\_\***()

  The name of this function should replace the "\*" with the name of the shortcut, eg: *alt\_d*\
   in addition replace any "-" with "\_".\
   This function is called after handle\_custom\_post\_keypresses() if it returned 0, and the shortcut is not a built-in shortcut.\
   this function takes 0 arguments.

- **handle\_custom\_action**()

  This function is called when an unknown action (as described in VIDEO JSON FORMAT) is given.\
   This function takes 1 argument:

  ```
      The action.
  ```

  Exit Codes:

  - *1*

    go back to menu

  - *2*

    exit

## CUSTOM THUMBNAILS

Custom thumbnails are located in $YTFZF\_CUSTOM\_THUMBNAILS\_DIR. The name of the image must be *\<video-id\>.jpg*

To see an example, make a search with *ytfzf* and locate the *thumbnails* folder in $cache\_dir/search

Custom thumbnails are going to try to be loaded before the official thumbnail.\
 If a custom thumbnail, and the official thumbnail doesn't exist, ytfzf will try to use *$YTFZF\_CUSTOM\_THUMBNAILS\_DIR/YTFZF:DEFAULT.jpg .*

## VIDEO JSON FORMAT

This is the format used for playlists, and custom scrapers.\
 Videos should be objects in a list.

Required object keys:

```
ID (string): a unique id to the video
url (string): the url to the video
title (string): the title of the video
scraper (string): The scraper that created the json (used for thumbnails)
```

```
thumbs (string): a url to a thumbnail/image
channel (string): the channel name
duration (string): length of the video (standard: [HH:]MM:SS)
views (string): amount of views a video has
date (string): upload date (standard: date is relative to current day, eg: 3 days ago)
action (string): an action in the format of "action [key=value key2=value2...]"
```

Example JSON:

```
[
    {
	"ID": "dQw4w9WgXcQ",
	"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
	"title": "definitely not never gonna give you up"
    }
]
```

## PLAYLISTS

A playlist is a json file in the format of VIDEO JSON FORMAT, To easily get the formatted json for a video, run *ytfzf -I VJ \<search*

## SORT NAMES

A sort name is a function in your config file, or a shell script in $YTFZF\_SORT\_NAMES\_DIR that defines the following functions:\
 *data\_sort\_fn()*\
 *get\_sort\_by()*

## CUSTOM SCRAPERS

Custom scrapers shell scripts located in $YTFZF\_CUSTOM\_SCRAPERS\_DIR.\
 A scraper is responsible for scraping videos from a website and APPENDING them to "$ytfzf\_video\_json\_file".\
 The shell script must be the same shell as your /bin/sh.

Other functions this script may define:

*on\_startup\_\<name\_of\_scraper\>*

This function will be called when the scraper is sourced (which is when the user asks for it).

This function takes no arguments.

*thumbnail\_video\_info\_text\_\<name\_of\_scraper\>*

This function shall print information for the thumbnails interface.

This function is effectively the same as thumbnail\_video\_info\_text().

*scrape\_next\_page\_\<scraper\>*

This function shall scrape more videos from \<scraper\>.\
 In order for this function to be called properly with alt-p, or ctrl-p, the page it left off on must be written to ${session\_cache\_dir}/\<scraper\>-current-page.\
 Where scraper is the name of the scraper with \_ instead of -

\<scraper\> should be the name put in the "scraper" attribute in VIDEO JSON FORMAT

This function will happen if the user presses alt-p in fzf.

This function takes no arguments.

*handle\_custom\_action\_\<action\_name\>*

This function shall handle a custom action.

\<action\_name\> should be the name of the action replacing any "-" with "\_".

This function takes 1 argument.

- *1*

  The action arguments

Exit Codes:

- *1*

  go back to menu

- *2*

  exit

## CUSTOM INTERFACES

Custom interfaces are shell scripts located in $YTFZF\_CUSTOM\_INTERFACES\_DIR.\
 An interface is responsible for letting the user pick a video from "$ytfzf\_video\_json\_file", then writing the url(s) to "$ytfzf\_selected\_urls"\
 The shell script must be the same shell as your /bin/sh.\
 In addition, the script must also define the function *interface\_\<name\_of\_interface\>*\
 With \_ replacing -.\
 This function could handle everything itself, or call another program written in any language to handle it.

interface\_\<name\_of\_interface\> will take a path to the json file holding all data about all the videos as the first argument.\
 The second argument will be a path to a file to store the selected url in, separated by new lines.

Other functions the scraper may define:

- **search\_prompt\_menu\_\<name\_of\_interface\>**()

  This function should do the same thing as search\_prompt\_menu(). This function takes no arguments.\
   If this function is not defined, search\_prompt\_menu\_ext() will be called instead.

- **quick\_menu\_\<name\_of\_interface\>**()

  This function should do the same thing as quick\_menu(). This function takes no arguments.\
   If this function is not defined, quick\_menu\_ext() will be called instead.

- **display\_text\_\<name\_of\_interface\>**()

  This function should display text in a way that is copy and pasteable. This function takes an unlimited number of arguments.

  - *...*

    The text to display

- **info\_wait\_prompt\_\<name\_of\_interface\>**()

  This function should ask the user to pick an **info\_wait\_action** option. It should then set the variable **info\_wait\_action** equal to the user's choice. This function takes no arguments.

## THUMBNAIL VIEWERS

Custom thumbnail viewers are programs in $YTFZF\_THUMBNAIL\_VIEWERS\_DIR. Arguments:

- *1*

  An action, there are 3 actions, start, stop, view, no-img

- *2*

  The path to the thumbnail.

- *3*

  x position (in columns) of the image

- *4*

  y position (in lines) of the image

- *5*

  width of image (in columns)

- *6*

  height of image (in lines)

- *7*

  max width of image (in columns) (width already accounts for this)

- *8*

  max height of image (in lines) (height already accounts for this)

- *9*

  side of the terminal to display the image (x, y, width, height already account for this)\
   this will be either *up* *down* *left* *right*

## EXTENSIONS

Extensions are essentially extra config files that you can load in your own config file.

Extensions should either be in $YTFZF\_EXTENSIONS\_DIR or $YTFZF\_SYSTEM\_ADDON\_DIR/extensions

An extension can do anything a config file can, this includes modifying the default utility functions in ytfzf (which could break the script)

Extensions will be given a variable called **$\_\_loaded\_path** which is the full path to the extension that is loaded.\
 This is helpful when needing to determine the current runtime path for the extension.

To load an extension add *load\_extension name-of-extension* to $YTFZF\_CONFIG\_FILE

There are two automatically loaded extensions, *\_\_ytfzf\_\_* and *\_\_ytfzf\_multisearch\_\_*\
 \_\_ytfzf\_multisearch\_\_ is only loaded if **$multi\_search** is *1*

Functions for extensions, where \<ext\> is replaced with the name of the extension, and all - are replaced with \_.

- **on\_clean\_up\_\<ext\>**()

  Runs when the script exits. This function takes no arguments.

- **on\_no\_thumbnail\_\<ext\>**()

  Runs when no thumbnail is found. This function takes no arguments.

- **after\_close\_url\_handler\_\<ext\>**()

  Runs after the url handler is closed. This function takes no arguments.

- **on\_post\_set\_vars\_\<ext\_name\>**()

  Replace ext\_name with the name of an extension (with - replaced with \_). This function is the same as **on\_post\_set\_vars**

- **ext\_on\_search\_\<ext\>**()

  Runs for before the website is scraped, for every search query. This function takes two arguments.

  - *1*

    The current search

  - *2*

    The current scrape type

- **post\_scrape\_\<ext\>**()

  Runs after scraping is complete. This function takes no arguments.

- **on\_init\_search\_\<ext\>**()

  Runs when the search is being initialized. This function takes one argument.

  - *1*

    The search

## UTILITY FUNCTIONS

A utility function is any function that can be used in *configuration files,* *extensions,* *thumbnail viewers,* *interfaces,* *search-names,*

- **refresh\_inv\_instances**()

  This function writes the response from "https://api.invidious.io/instances.json?sort\_by=type,health,api" to $cache\_dir/instances.json. This function takes no arguments.

- **get\_invidious\_instances**()

  This function grabs invidious instances that have an api and prints them separated by a new line. This function takes no arguments.

- **create\_sorted\_video\_data**()

  This function prints a sorted jsonl string of the scraped videos that can be used in an interface This function takes no arguments.

- **run\_interface**()

  Runs the function **interface\_\<interface\_name\>**, and passes **$ytfzf\_video\_json\_file**, and **$ytfzf\_selected\_urls** This function takes no arguments.

- **download\_thumbnails**()

  If **$skip\_thumb\_download** is 0, this function downloads thumbnails. This function takes an unlimited number of arguments formatted in the following way:

  ```
  <url_name>;<id>
  ```

  This function should download \<url\_name\> and save it as \<id\>.jpg in the **$thumb\_dir** folder.

- **prepare\_for\_set\_args**()

  This function sets the variable **$OLD\_IFS** to **$IFS**, then sets **$IFS** to the first argument, lastly it runs **set -f**. This function takes one argument.

  - *1*

    The new **IFS**.

- **end\_of\_set\_args**()

  This function sets **IFS** to **OLD\_IFS**. This function takes no arguments.

- **modify\_ifs**()

  This function sets **IFS** to the first argument. This function takes one argument.

  - *1*

    The value to set **IFS** to.

- **end\_modify\_ifs**()

  This function unsets $IFS**.** **This function takes no arguments.**

- **mul\_str**()

  **This function does string multiplication, then prints the result to stdout.** **This function takes two arguments.**

  - *1*

    **The string.**

  - *2*

    **The amount to duplicate the string.**

- **remove\_ansi\_escapes**()

  **This function removes ansi escape sequences from a string passed to this function through stdin.** **This function then prints the final string to stdout.** **This function takes no arguments.**

- **do\_an\_event\_function**()

  **This function runs an event if it exists, then runs event\_\<ext\> for every loaded extension $loaded\_extensions**, if they exist. This function takes an unlimited number of arguments.

  - *1*

    The name of the event.

  - *...*

    The arguments to pass to event

- **detach\_cmd**()

  This function detaches a command from the terminal. This function takes an unlimited number of arguments.

  - *1*

    The command to run

  - *...*

    The arguments to pass to the command.

- **source\_scrapers**()

  This function goes through each scraper listed in **$scrape**, and sources the appropriate file. After sourcing the file, it runs the **on\_startup\_\<scrape\>** function, if **$\_\_is\_fzf\_preview** is *0***.** **This function checks the following locations for the file to source.**

  - ***$YTFZF\_CUSTOM\_SCRAPERS\_DIR***

    - ***$YTFZF\_SYSTEM\_ADDON\_DIR/scrapers***

    - ***$YTFZF\_CUSTOM\_SCRAPERS\_DIR***

    - ***$YTFZF\_SYSTEM\_ADDON\_DIR/scrapers***

    - **add\_commas**()

  **This function adds commas to a number (in the standard english way).** **This function gets a number from stdin, and prints the result to stdout.** **This function takes no arguments.**

- **command\_exists**()

  **This function checks if a command exists.** **This function exits with status code** *0* if it exists, and *1* if it does not. This function takes 1 argument.

  - *1*

    The command to check

- **get\_key\_value**()

  This function gets the value by a key in a key\_value string.\
   A key\_value string is formatted in the following way:

  ```
  <sep>key=value<sep>...
  where <sep> is argument 3, by default a space.
  ```

  If there is only one key\_value pair, there must still be \<sep\> on each side.\
   After printing the value to stdout, this function sets the variable **$KEY\_VALUE** to the value of the key.\
   This function exits with status code *0* if the value is not empty, and *1* if it is empty.\
   This function takes three arguments.

  - *1*

    The key\_value string.

  - *2*

    The key to find the value for.

  - *3 (optional)*

    The separator that separates each key\_value pair. By default this is a space.

- **title\_str**()

  This function capitalizes the first letter of a string, and prints it to stdout. This function takes one argument.

  - *1*

    The string to title.

- **shuf**()

  This function is only created if **shuf** is not installed. This function should act the same as the base functionality of **shuf**

- **print\_info**()

  This function prints information to stderr, if **$log\_level** is greater than or equal to *2*. This function takes one argument.

  - *1*

    The text to print

- **print\_warning**()

  This function prints a warning to stderr, if **$log\_level** is greater than or equal to *1*. This function takes one argument.

  - *1*

    The text to print

- **print\_error**()

  This function prints a warning to stderr, if **$log\_level** is greater than or equal to *0*. This function takes one argument.

  - *1*

    The text to print

- **clean\_up**()

  This function kills all **[ytfzf(1)](/ytfzf/1.md)** subprocesses, and removes **$session\_cache\_dir** if **$session\_cache\_dir** exists, and if **$keep\_cache** equals *0***.**\
   **Lastly, it runs the on\_clean\_up** event. This function takes no arguments.

- **is\_relative\_dir**()

  Checks if a string is a relative path. This function exits with status code *0* if it is relative, and *1* if it is not. This function takes one argument.

  - *1*

    The path to check

- **die**()

  This function runs **print\_error** with a string, then exits with a status code. This function takes two arguments.

  - *1*

    The exit status

  - *2*

    The text to print with **print\_error**.

- **trim\_url**()

  This function reads lines from stdin, and prints the url from them to stdout. The lines should be formatted in the following way:

  ```
  text....|url
  ```

  This function takes no arguments.

- **get\_search\_from\_source**()

  This function sets **\_search** to a search depending on the source. This function takes an unlimited number of arguments.

  - *1*

    The source to get the search from.

  - *...*

    The arguments to use as the search if **$1** is *fn-args*, or if **1** is not matched, ... is given to **get\_search\_from\_\<1\>**.

- **load\_extension**()

  This function adds an extension to the **$loaded\_extensions** variable, and sources the extension. This function checks the following locations for the extension

  ```
  $YTFZF_EXTENSIONS_DIR
  $YTFZF_SYSTEM_ADDON_DIR/extensions
  $PATH
  ```

  This function exits with the same exit code as when the extension was loaded. This function takes one argument.

  - *1*

    The extension to load

- **extension\_is\_loaded**()

  This function checks if an extension is loaded. This function takes one argument.

  - *1*

    The extension to check

- **load\_sort\_name**()

  This function loads a sort-name. This function checks the following locations for the sort-name.

  ```
  $YTFZF_SORT_NAMES_DIR
  $YTFZF_SYSTEM_ADDON_DIR/sort-names
  ```

  This function exits with status code *1* if the sort-name does not exist, otherwise it exits with the same status code as when the sort-name was loaded. This function takes one argument.

  - *1*

    The sort-name to load

- **load\_url\_handler**()

  This function sets **$url\_handler** to a url-handler. This function checks the following locations for the url-handler.

  ```
  $PATH, and functions in config file
  $YTFZF_URL_HANDLERS_DIR
  $YTFZF_SYSTEM_ADDON_DIR/url-handlers
  If the url-handler does not exist, this function runs die.
  This function takes one argument.
  ```

  - *1*

    The url-handler to load

- **load\_interface**()

  This function sets **$interface** to an interface. If **$1** is equal to *ext*, *scripting*, or "", **$interface** is set to **1**. This function checks the following locations for the interface.

  ```
  $1
  $YTFZF_CUSTOM_INTERFACES_DIR
  $YTFZF_SYSTEM_ADDON_DIR/interfaces
  ```

  This function takes one argument.

  - *1*

    The interface to load

- **load\_thumbnail\_viewer**()

  This function sets **$thumbnail\_viewer** to a thumbnail-viewer. If **$i** is equal to a built-in thumbnail-viewer, **$thumbnail\_viewer** is set to that. Otherwise, the following locations are checked.

  ```
  $1
  $YTFZF_THUMBNAIL_VIEWERS_DIR
  $YTFZF_SYSTEM_ADDON_DIR
  ```

  This function takes one argument.

  - *1*

    The thumbnail viewer to load

- **\_get\_request**()

  This function sends a request to a server and prints the response. This function takes Unlimited arguments.

  - *1*

    The url to send a request to

  - *...*

    Arguments to pass to **[curl(1)](/curl/1.md)**

- **\_get\_real\_channel\_link**()

  This function converts a youtube channel link in the form of

  ```
  @user
  https://www.youtube.com/user/<channel-name>
  https://www.youtube.com/c/<channel-name>
  ```

  This function takes one argument.

  - *1*

    The link to convert
