A small bash/Python script
that fetches your latest unread video feeds from a specific feed category in your TinyTinyRSS account
and plays them in
and also marks the feed articles as read in TTRSS, one by one as you watch them.
Installation and config
Clone this repo and enter its directory
git clone https://codeberg.org/taha/ttrss-video-mpv.git cd ttrss-video-mpv
Create a Python venv and install the
ttrss-python library and its dependencies
using the shell script I've prepared for that
Now make sure you reset the variables in
ttrss-video-mpv.sh to your own values.
And with that, feel free to run the bash script:
You will be prompted for your TTRSS account password (either via Password Store or as a bash prompt) and then you should see mpv text output in the terminal immediately followed by the first video opening in mpv.
To stop the bash script and all playback, kill the terminal (close it, or
Ctrl-c in the terminal).
To mark a video as read and skip to the next video in the list, close the playing video window (for example by using the mpv shortcut
q, or otherwise close the window).
Integration with GNOME/KDE/others desktop entries (optional, but advisable)
.desktop file has been included in this repo.
Make sure to replace the nonsense paths with the path to where you cloned this project.
Note that the
TryExec line will hide the desktop entry from your menu if the file it points to
does not exist or if the file it points to is not executable.
Integration with i3 window manager (optional)
We can make use of the fact that we set the
--x11-name=<string> argument to
mpv in our Python script,
no_focus [instance="<string>"] to our i3 config file to ensure that the mpv window does
not keep taking keyboard/mouse focus every time a new video starts.
By setting the
x11-name (corresponds to the first part of
WM_CLASS, which you can inspect using
we make sure that any i3 rules we set only affect the
mpv windows playing our TTRSS videos, and
not any other mpv instances.
While we are at it, we could also set these mpv windows to open at a specific position and with a predefined size, so all together:
no_focus [instance="<string>"] for_window [instance="ttrss-video-mpv"] floating enable, resize set 840 500, sticky enable, move position 1380 700
NOTE! (excerpt from the i3 manual):
When using multiple commands, separate them by using a
,(a comma) instead of a semicolon. Criteria apply only until the next semicolon, so if you use a semicolon to separate commands, only the first one will be executed for the matched window(s).
Also, you will of course have to adjust the size and position coordinates to suit your monitor.
Notes during development
Some notes I recorded while putting this together. My machine: Ubuntu 18.04.5, Python 3.6.9, pip 20.2.3, i3 4.19, rofi 1.6.0.
I chose to use Python
venv rather than
since it appears to be the new default.
I had to
pip3 install wheel before installing the
ttrss module, otherwise the latter failed with
invalid command bdist_wheel.
Here's a list of the methods the
ttrss-python.client command makes available (thanks to autocomplete in
>>> client. client.assign_label( client.get_pref( client.share_to_published( client.catchup_feed( client.get_unread_count( client.sid client.get_articles( client.http_auth client.subscribe( client.get_categories( client.logged_in( client.toggle_unread( client.get_feed_count( client.login( client.unsubscribe( client.get_feed_tree( client.logout( client.update_daemon_running( client.get_feeds( client.mark_read( client.update_feed( client.get_headlines( client.mark_unread( client.url client.get_headlines_for_label( client.password client.user client.get_labels( client.refresh_article(
To create/update the requirements file:
pip freeze > requirements.txt
To exit the Python venv:
This project would not have been possible without the fantastic
ttrss-python library by Markus Wilk. Thank you, Markus!
I also found a Gist that integrates TRSS with Calibre, which seems to contain its own custom-made TTRSS Python code.
I did test to use
umpv instead of
mpv. Here's my notes:
Enterdid move down the playlist, but the playlist naturally contained only the previously played videos (so all videos in a session where still there in the playlist, which was nice),
- volume was still reset in mpv with every new video (same as without
- the big drawback was that starting another
./ttrss-video-mpv.shinstance while the first was still running (easy enough to do, by mistake or otherwise), caused the second instance to just add videos to the current
umpvplaylist without playing them, meaning our loop in the Python script would run through every video fetched from TTRSS and mark them as read. I considered this very dangerous behaviour in combination with this script, and thus opted to stay with vanilla