t184256 / yousable

youtube downloader / podcast feed generator based on yt-dlp
GNU General Public License v3.0
4 stars 1 forks source link

Example NixOS config #1

Open baduhai opened 1 year ago

baduhai commented 1 year ago

It took me a while, but I eventually figured out how to deploy yousable using the NixOS service. I figure people may find it helpful; here's the config:

{ inputs, config, pkgs, lib, ... }:

let
  configyaml = pkgs.writeTextFile {
    name = "config.yaml";
    text = ''
      paths:
        meta: /data/yousable/meta
        out: /data/yousable/out
        tmp: /data/yousable/tmp
        live: /data/yousable/live
        x_accel: /out

      secrets: ~
      authorization: ~

      profiles:
        default:
          video: false
          container: opus
          download:
            format: 'ba[vcodec=none]'
            format_sort: [ 'acodec:opus' ]
          live:
            audio:
              format_sort: [ 'acodec:opus' ]

      feed_defaults:
        load_entries: 10                 # query only the last L videos from youtube
        keep_entries: 10                 # keep at least the last K videos on disk
        keep_entries_seconds: 1000000000 # keep videos that are less than M seconds old
        live_slice_seconds: 1200         # fill paths.live with fragments N seconds long
        poll_seconds: 21600              # look for new videos roughly P seconds often
        profiles: [ default ]

      feeds:
        TL:
          url: https://www.youtube.com/channel/UCeeFfhMcJa1kjtfZAGskOCA/videos
          sponsorblock_remove: [ sponsor ]
          overrides:
            title: TechLinked
        GL:
          url: https://www.youtube.com/channel/UCHDxYLv8iovIbhrfl16CNyg/videos
          sponsorblock_remove: [ sponsor ]
          overrides:
            title: GameLinked
        JS:
          url: https://www.youtube.com/channel/UC-2YHgc363EdcusLIBbgxzg/videos
          sponsorblock_remove: [ sponsor ]
          overrides:
            title: Answers with Joe
        HOTU:
          url: https://www.youtube.com/channel/UCtRFmSyL4fSLQkn-wMqlmdA/videos
          sponsorblock_remove: [ sponsor ]
          overrides:
            title: History of the Universe
        SEA:
          url: https://www.youtube.com/channel/UCG9ShGbASoiwHwFcLcAh9EA/videos
          sponsorblock_remove: [ sponsor ]
          overrides:
            title: SEA
        TH:
          url: https://www.youtube.com/channel/UCSwFnHpDt-lZgR_7Sqisi6A/videos
          sponsorblock_remove: [ sponsor ]
          overrides:
            title: The Histocrat
        L1T:
          url: https://www.youtube.com/channel/UC4w1YQAJMWOz4qtxinq55LQ/videos
          sponsorblock_remove: [ sponsor ]
          overrides:
            title: Level 1 News
        TSR:
          url: https://www.youtube.com/channel/UCeMcDx6-rOq_RlKSPehk2tQ/videos
          sponsorblock_remove: [ sponsor ]
          overrides:
            title: The Space Race
    '';
  };

in {
  services = {
    yousable = {
      enable = true;
      port = 8001;
      configFile = "${configyaml}";
    };

    nginx.virtualHosts."yousable.baduhai.me" = {
      useACMEHost = "baduhai.me";
      forceSSL = true;
      kTLS = true;
      locations."/".proxyPass = "http://127.0.0.1:${lib.toString config.services.yousable.port}";
      extraConfig = ''
        gzip off;
        gzip_proxied off;
        proxy_cache off;
        proxy_buffering off;
      '';
      locations."/out" = {
        root = "/data/yousable";
        extraConfig = ''
          autoindex off;
          internal;
        '';
      };
    };
  };
}

I have secrets and authorization empty because my domain is only accessible behind my VPN. Importantly, if I didn't add "/videos" to the end of urls, I kept getting errors, which took quite a while to figure out.

t184256 commented 1 year ago

For the reference, here's how I deploy it: https://github.com/t184256/nix-configs/blob/main/nixos/services/yousable.nix

I keep the whole config secret. There are several Nginx performance tweaks in there.

writeTextFile

I suppose you can rewrite that with Nix recordsets and writeJSON.

baduhai commented 1 year ago

I suppose you can rewrite that with Nix recordsets and writeJSON.

Didn't think of that, good idea.

Thanks a lot for this little program, it's great! With a little better documentation, and some advertisement in self-hosted communities, I could see it getting real steam behind it :)

I have a question, does yousable accept the new youtube urls that use the channel's handle, e.g. https://www.youtube.com/@techlinked? I chose the browse_id for all the channels I wanted to subscribe to since that's probably the most permanent option, but I can see the value in the simplicity of the human-readable urls.

t184256 commented 1 year ago

does yousable accept the new youtube urls that use the channel's handle, e.g. https://www.youtube.com/@techlinked?

I think it does. It should take anything playlist-ey yt-dlp can take, including /live links, user handles and even non-youtube stuff. I've used it with some BBC stuff, for example.

Thanks a lot for this little program, it's great! With a little better documentation, and some advertisement in self-hosted communities, I could see it getting real steam behind it :)

Thanks for the kind words. I'm really bad at advertising, and as long as it reliably scratches my own itch, I'm happy. But I'll accept MRs if there'll be any.

baduhai commented 1 year ago

But I'll accept MRs if there'll be any.

There's one feature in particular I was thinking of adding to your program; a filter for channels. By that I mean only add to the feed videos that include "XYZ" in the title, or have "ABC" in the description.

t184256 commented 1 year ago

I use my podcast app (AntennaPod) for name-based filtering.

I've at, some point, entertained an idea to allow flexible filters by taking some restricted python evaluator, dumping all video attributes into scope (age, duration, like count, watch count...) and evaluating a custom expression out of them. That'd be something I'd probably use myself.

baduhai commented 1 year ago

I use my podcast app (AntennaPod) for name-based filtering.

I did not know AntennaPod had that feature, my favourite podcast app becomes favouriter!