/ytel

Youtube "front-end" for Emacs

Primary LanguageEmacs LispGNU General Public License v3.0GPL-3.0

ytel

ytel is an experimental YouTube "frontend" for Emacs. It's goal is to allow the user to collect the results of a YouTube search in an elfeed-like buffer and then manipulate them with Emacs Lisp. The gif below shows that ytel can be used to play videos in an external player, to learn how to emulate it refer to the usage section below.

This project was inspired by elfeed and Invidious (it does indeed use the Invidious APIs).

Installation

This project is on MELPA: you should be able to M-x package-install RET ytel. Another option is to clone this repository under your load-path.

Dependencies

While ytel does not depend on any Emacs package it does depend on curl so, if you happen not to have it, install it through your package manager (meme distros aside it is probably in your repos).

Usage

Once everything is loaded M-x ytel creates a new buffer and puts it in ytel-mode. This major mode has just a few bindings (for now):

key binding
n next-line
p previous-line
q ytel-quit
s ytel-search
> ytel-search-next-page
< ytel-search-previous-page

Pressing s will prompt for some search terms and populate the buffer once the results are available. One can access information about a video via the function ytel-get-current-video that returns the video at point. Videos returned by ytel-get-current-video are cl-structures so you can access their fields with the ytel-video-* functions. Currently videos have four fields:

field description
id the video's id
title the video's title
author name of the author of the video
authorId id of the channel that updated the video
length length of the video in seconds
views number of views
published date of publication (unix-style timestamp)

With this information we can implement a function to stream a video in mpv (provided you have youtube-dl installed) as follows:

(defun ytel-watch ()
    "Stream video at point in mpv."
    (interactive)
    (let* ((video (ytel-get-current-video))
     	   (id    (ytel-video-id video)))
      (start-process "ytel mpv" nil
		     "mpv"
		     (concat "https://www.youtube.com/watch?v=" id))
		     "--ytdl-format=bestvideo[height<=?720]+bestaudio/best")
      (message "Starting streaming..."))

And bind it to a key in ytel-mode with

(define-key ytel-mode-map "y" #'ytel-watch)

This is of course just an example. You can similarly implement functions to:

  • open a video in the browser,
  • download a video,
  • download just the audio of a video,

by relying on the correct external tool.

It is also possible to customize the sorting criterion of the results by setting the variable ytel-sort-criterion to one of the following symbols relevance, rating, upload_date or view_count. The default value is relevance.

Potential problems and potential fixes

ytel does not use the official YouTube APIs but relies on the Invidious APIs (that in turn circumvent YouTube ones). The variable ytel-invidious-api-url points to the invidious instance (by default https://invidio.us) to use; you might not need to ever touch this, but if invidio.us goes down keep in mind that you can choose another instance. Moreover the default Invidious instance is generally speaking stable, but sometimes your ytel-search might hang; in that case C-g and retry.

Currently some wide unicode characters (such as Chinese/Japanese/Korean characters) are very likely to mess up the *ytel* buffer. The messing up is not that bad but things will not be perfectly aligned. Fixing this problem will most likely require a rewrite of how the ytel buffer is actually drawn. We're (somewhat) working on it.

Extra

There's an extension to browse comments and video information.

Contributing

Feel free to open an issue or send a pull request. I'm quite new to writing Emacs packages so any help is appreciated.

FAQ

Why?

One can easily subscribe to YouTube channels via an RSS feed and access it in Emacs via elfeed but sometimes I want to search YouTube for videos of people I don't necessarily follow (e.g. for searching a tutorial, or music, or wasting some good time) and being able to do that without switching to a browser is nice.

What about helm-youtube and ivy-youtube?

First of all those packages require you to get a Google API key, while ytel uses the Invidious APIs that in turn do not use the official Google APIs.

Moreover those packages are designed to select a YouTube search result and play it directly in your browser while ytel is really a way to collect search results in an elfeed-like buffer and make them accessible to the user via functions such as ytel-get-current-video so the user gets to decide what to to with them.