[Almost] Hacking Youtube videos' speed on Nyxt

Hi guys,

This is my first post here. After following the troubleshooting on the manual, I can watch youtube videos on Nyxt :slight_smile:

Sometimes, I like to watch them at 3x or 4x speed. This is not a youtube feature. It is more like a hack.

In Firefox, I achieve this with the following command on the browser’s console:

document.querySelector("video").playbackRate =3

I guess it is feasible to do something similar using Nyxt’s bookmarklets! This article was an inspiration for me.

I think I am close to do my first nyxt hacking. But I am stuck and would like to ask for your help.

This is what I did so far:

1 - After following the developer manual (git cloning, fetching, pulling, installing dependencies, et cetera), I am able to run the current master branch of Nyxt locally while doing some live coding.

2 - With Emacs and Sly (a fork from Slime), I am able to run Nyxt and use the REPL. This gives me live coding capability which I am trying to explore more.

3 - I did the following:

; SLY 1.0.43 (#<MREPL mrepl-1-1>)
CL-USER> (require :asdf)
CL-USER> (asdf:load-asd "/home/pedro/common-lisp/nyxt/nyxt.asd")
CL-USER> (ql:quickload :nyxt/gi-gtk)
To load "nyxt/gi-gtk":
  Load 1 ASDF system:
; Loading "nyxt/gi-gtk"
CL-USER> (nyxt:start)
<INFO> [20:03:30] Listening to socket "/run/user/1000/nyxt/nyxt.socket".
Nyxt version 2.0.0-9-g5fdabca9
<INFO> [20:03:30] Loading Lisp file "/home/pedro/.config/nyxt/auto-config.lisp".

Then, I used the define-bookmarklet-command in the REPL to insert the appropriate JS with:

CL-USER> (nyxt:define-bookmarklet-command hack-youtube-speed "Change youtube videos speed beyond 3x" "(function() { const rate = prompt('Set the new playback rate', 2.5); if (rate != null) { const video = document.getElementsByTagName('video')[0]; video.playbackRate = parseFloat(rate); } })();")

Apparently, I am reaching what I want since I got:



As you can see, the bookmarklet that I created is now one of the elements of the bookmarklets’ list. Notice the first element on the list above.

Finally, this is the point that I am struggling with.

When I go to the GUI, after pressing M-x, I cannot see my bookmarklet as one of the options. I just see the built-in ones. Apparently, my hack did not work for some reason. It is only in the REPL’s evaluation.

Thus, I decided to try to overcome the GUI failure with the REPL. I tried:

CL-USER> (nyxt: hack-youtube-speed)
CL-USER> (hack-youtube-speed)

Unfortunately, it did not work too. I just receive error messages from the compiler.

Actually, I am unable to use the REPL to set some of the commands. It goes beyond my bookmarklet function call.

I noticed this problem while trying to mimic the commands done by Pierre on this presentation. When I tried to replicate the commands on my environment they did not work.

He did this presentation something like 15 months ago. Maybe things changed. The project’s name changed for instance.

Exactly the same does not work for me:

CL-USER> (set-url “https://ambrevar.xyz”)

Slightly changing it also does not work:

CL-USER> (nyxt:set-url “https://ambrevar.xyz”)

In Pierre’s PC, it is not CL-USER but NEXT (Nyxt’s old name). Not sure if this is the key point or just a name. I am new to Common Lisp, Emacs, Slime/Sly, and et cetera…

Awkwardly enough, this works:

CL-USER> (nyxt:current-buffer)
#<NYXT:USER-WEB-BUFFER {1001A59193}>

Do you guys see what I am missing?

I am really excited about Nyxt!

Thanks for your attention.

Does it work any better if you start the swank server in Nyxt and then connect to the server and run your commands that way?
When I connect to nyxt’s swank server, my repl prompt shows “nyxt-user”…

1 Like


Thanks for the suggestion, @johnhilts! I have already seen mentions to the swank server reading about Common Lisp/Slime. I even saw the concept in a few articles about Nyxt. However, I have never tried them and did not understand them well. I will study it and have a try on my problem. Thanks.

1 Like

Several things to work with here:

  • Bookmarklet I can tell nothing about, that’s weird :dizzy_face:
  • Maybe you can try (nyxt:hack-youtube-speed) in the REPL? Notice the absence of the space in between the colon and bookmarklet name—it’s meaningful. It means that you use hack-youtube-speed from the nyxt package.
  • The presentation is outdated, yes. Lots of things have changed since then.
    • One of the changes is that set-url is no longer taking a URL argument. Use nyxt:buffer-load instead.
  • Yes, NEXT (or NYXT in current state) instead of CL-USER is meaningful. It’s the name of the package you’re in. To change it, do (in-package :nyxt).

As something that can resolve your bookmarklet issue, try defining it in your initfile. This way it’s defined in the right package and should be accessible by the time you do M-x.

1 Like

Thanks, @aartaka. After following one of your advices, I was able to do it! :1st_place_medal: :zap: :checkered_flag:

As you can see below, I did the (in-package :nyxt). Moreover, I also inserted:

NYXT> (define-bookmarklet-command live-hack-youtube-speed "Change youtube videos speed beyond 3x" "(function() { const rate = prompt('Set the new playback rate', 2.5); if (rate != null) { const video = document.getElementsByTagName('video')[0]; video.playbackRate = parseFloat(rate); } })();")

After that, I was able to find the hack-youtube-speed on the execution prompt! Then, I used the new command and set the youtube speed. Finally, it worked perfectly :grinning: . I was able to watch youtube videos with 3x and 4x speed.

These numbers (e.g. 19300) returned/printed by the REPL after evaluating the expression (hack-youtube-speed) intrigue me. What are they? Are they something like pointers to objects?

(I have not reached CLOS yet in my studies).

The image below is the prompt generated by the bookmarklet after executing in another video:

Unfortunately, things only worked after changing to use NYXT in current state. Even If I respected the absence of the space between the colon and the bookmarklet’s name mentioned by you it did not work on CL-USER> state.

I got this as an error message:

   CL-USER> (nyxt:hack-youtube-speed)

   Symbol "HACK-YOUTUBE-SPEED" not found in the NYXT package.

  Line: 1, Column: 23, File-Position: 23

  Stream: #<SB-IMPL::STRING-INPUT-STREAM {1002F2A453}>
   ; Evaluation aborted on #<SB-INT:SIMPLE-READER-PACKAGE-ERROR "Symbol ~S not found in the ~A package." {1002F2A573}>.

In addition, changing the config file also did not work. This would be my first change on it. This is my auto-config.file

There was no init.lisp. Hence, I decided to create one in the same directory which auto-config.lisp is located. This is my init.lisp.

Not sure if I did something wrong. But I was not able to find the bookmarklet among the Execute command options.

This gets really weird because although it is not an option if I try to define in the REPL another bookmarklet using the same name hack-youtube-speed the REPL indicates an error:

#<PACKAGE "NYXT-USER"> between the following symbols:
   [Condition of type SB-EXT:NAME-CONFLICT]
See also:
  Common Lisp Hyperspec, [:section]

I guess this means that it is not working as an optional bookmarklet but it is there since the REPL loaded the init-file in some way. This seems odd. If you know why, please share with me.

I am affraid I might have messed up with something. Hence, I won’t consider this a bug.

Thanks for helping!

Okay, I found the source of the problem. Bookmarklets are not set as global commands, thus they are not usualy shown in execute-command. I’ve pushed the fix to master. Meanwhile, what you can do is add a package prefix in front of the bookmarklet command name, i.e.:

(define-bookmarklet-command nyxt:live-hack-youtube-speed 
"Change youtube videos speed beyond 3x" 
"(function() { const rate = prompt('Set the new playback rate', 2.5); if (rate != null) { const video = document.getElementsByTagName('video')[0]; video.playbackRate = parseFloat(rate); } })();")

@pedro-delfino how you got youtube videos working on nyxt browser I am unable to watch any videos …
Any detailed documentation or guide would be helpful .

1 Like

Hi @noobAAK,

I am glad to help!

This a “documented” problem. Take a look on the manual built-in inside Nyxt.

By the end of the Manual’s document there is a section called Troubleshooting. There you will find instructions about additional programs needed in order to play videos on Nyxt.

Nyxt delegates video support to third-party plugins.

You can access the Manual pressing (Control+space) and then typing “manual” on the Execute Command prompt.

I will post here the current content (6th of June, 2021) just to illustrate. However, it is always the best practice to read the most updated version of the manual.

If it does not work, feel free to come back here to discourse and I will try to help you. If you run into problems following the manual, maybe it would be better to open a new thread and read the community guidelines.

If you think something might be a bug or a clear problem, it is good to checkout the issues on the project’s github (even the closed ones). This video problem was pointed out in the issues a few months ago. And there people mentioned the troubleshooting on the manual.

Finally, I recently read this text (how to ask questions) recommend by @ambrevar on his blog. I think you should take a look too.

Despite being almost unfriendly, the author gives pratical advice and has an elegant writing style. He is a well-known hacker.


Playing videos

Nyxt delegates video support to third-party plugins.

When using the WebKitGTK backends, GStreamer and its plugins are leveraged. Depending on the video, you will need to install some of the following packages:

On Debian-based systems, you might be looking for (adapt the version numbers):

For systems from the Fedora family:

After the desired plugins have been installed, clear the GStreamer cache at ~/.cache/gstreamer-1.0 and restart Nyxt.

Input method support (CJK, etc.)

Depending on your setup, you might have to set some environment variables or run some commands before starting Nyxt, for instance

ibus --daemonize --replace --xim
You can persist this change by saving the commands in your .xprofile or similar.