Yapfast

12 min read

Yapfast 0.3.0 is out

Go Live on your graphics card, the soundboard, proper Markdown, Discord's links opening in the app, and channels that open a lot faster.

This is everything since 0.2.0 came out on October 24, 105 commits, with thirteen pull requests from seven people who aren't me in there (thank you!!). Downloads are on the releases page, as always.

Go Live on your graphics card

Go Live in 0.2.0 looked great on a calm screen, and then you'd start a game and it just fell apart lol. A 60 fps Minecraft clip came out at 6 to 20 frames a second, which is perfect if you're presenting slides. Now every frame goes out, and when your connection can't keep up, the picture gets blurrier instead.

Your graphics card probably has a whole ass chip just for encoding video, and it was sitting there doing NOTHING, so Yapfast streams on that now (or on your CPU if it can't). There's nothing to set up, and if you'd rather it left your GPU alone, it's Settings → Advanced → Encode streams with the GPU.

Sharing a 1080p screen, in a call Memory CPU
Vesktop 1,013 MB 2.15%
Yapfast 0.2.0 145 MB 2.9%
Yapfast 0.3.0 on an RTX 3090 113 MB 1.1%

So yeah, 0.2.0 took more CPU than Vesktop here (oops), and 0.3.0 takes about half :D On a bad connection, the stream also breaks up into blocks less than half as often on the graphics card as on the CPU.

Newer cards can also stream in AV1 or H265, which look better at the same bitrate (AV1 is thanks to ke7in-zz, #51), and Yapfast can watch both. If someone watching can't play them, Discord just switches the stream to H264.

My graphics card can't encode AV1 though (lame ass RTX 3090 huh), so AV1 has never actually gone out from a whole Yapfast yet.. I also have no clue which of Discord's own apps can watch H265 and AV1, and under Wine the Windows build can only fall back to the CPU. So if you stream from Windows or have a newer card, please tell me what happens.

While you're live, the call's details have a new Stream tab, so you can see how your stream is actually going out (Discord's app only shows you that in developer mode).

The call's details over a voice channel in Outer Heaven, on the Stream tab: encoder NVENC on the GPU, codec H265, 640×360 at 30 fps, the bitrate being sent and the one aimed for, keyframes asked for and packets resent. Behind it, the shared screen is a test pattern of colored bars.

Yes, that's 640×360 at 58 kbit/s, it's a test pattern, calm down :p

truelecter also made cameras shareable (#52), so OBS's virtual camera can go out as a real stream now, from CAMERAS in the share menu.

For nerds

The encoders are NVENC on NVIDIA, VA-API for AMD and Intel on Linux and AMF for AMD on Windows. If none of them opens, or one dies mid-stream, x264 takes over. Intel on Windows stays on x264 for now. NVENC needs NVIDIA's driver 520 or newer, and AMF an AMD driver from about May 2026 or newer. It's still one file, since FFmpeg's encoders are compiled right into the binary, and the drivers only load when an encoder opens.

Sharing a 1080p30 screen, in a call Memory CPU
Yapfast 0.2.0, OpenH264 145 MB 2.9%
Yapfast 0.3.0, x264 126 MB 2.5%
Yapfast 0.3.0, NVENC H264 113 MB 1.1%

For quality I used VMAF, Netflix's score from 0 to 100. Xiph's Minecraft clip at 9 Mbit/s went from 38 with OpenH264 to 66 with x264. On the busiest minute of an action trailer at 1080p30 and 2.5 Mbit/s, x264 dipped under 60 (about where you start seeing blocks) 47 times and NVENC 22 times, at 0.26 of a core against 0.02 of a core. NVENC's H265 scored 92.9 there against its H264's 88.3.

Watching takes about 0.1 of a core for 1080p30 H265 and 0.07 of a core for AV1. The codec order is AV1, H265, H264, and Discord picks the first one every viewer decodes.

For AV1, ke7in-zz ran native/hwenc.c on its own on an RX 7900 XTX, and that's as far as it got. AMD's RX 7000 cards round 1080 lines up to 1082 lines in AV1, so viewers may see a couple of extra rows at the bottom (thanks AMD).

Soundboard

Until now, Yapfast people missed every airhorn, since a client without soundboard support just hears nothing when someone plays a sound (tragic). There's a button for it in the call's controls now, with your favorites, the server's sounds, Discord's own and (with Nitro) your other servers' sounds. Hover over one to hear it just for yourself, or star it; the stars are your Discord favorites, so they follow your account.

A call in Outer Heaven's Lounge with Solid Snake, Jinx, L and others, and the soundboard open over it: airhorn under Favorites, and quack, airhorn, cricket, golf clap, sad horn and ba dum tss under Default.

Settings → Voice & video has its volume and your entrance sounds (Nitro again), and someone's menu in a voice channel has Mute Soundboard, for that one friend.

Fast..er af?

These are all against my fake Discord with 100 ms of latency:

Before Now
Starting Yapfast again, until Discord answers 314 ms 225 ms
Opening an unread channel you've never loaded 272–288 ms 134–170 ms
Going back to a channel you just had open 103–104 ms 4–5 ms
Sending a message with three 200 KB files 707–724 ms 303–305 ms

Some of that was just dumb, honestly. Opening a channel asked Discord for older messages before you'd scrolled at all, each file in a message waited for the one before it, and going back to a channel asked for its messages AGAIN, even though Yapfast had been following them live the whole time.

For nerds

Previews show up in the same frame as the channel now, where they came 3 frames later at 60 fps before (52 ms down to 6 ms, going back to a channel whose previews had left the cache). Saved avatars don't wait behind the ones still downloading, which after a fast scroll at 1000 ms of latency took them 5–6 seconds, and now takes under a millisecond. Reading a server with 500 channels at startup went from 10.7 ms to 0.33 ms, since each channel sorted the whole list again (yep). The build number also stays on disk now, so a start doesn't wait on a fetch from discord.com before connecting.

Busy channels

With a crowd posting 50 messages a second in the channel you're looking at (a totally normal amount), Yapfast's heap went from 27 MiB to 110 MiB in 30 seconds, and just stayed there. Almost all of that was avatars.

Now it only keeps the avatars near what's on screen, and a channel you're following lets go of its oldest messages (they load again when you scroll up). Same crowd, about 40 MiB.

For nerds

All of this is on my big fake account, 100 servers and 300 DMs, with heap in use from glibc's own numbers. 101 MiB of that 110 MiB was decoded avatars at 64 KB each. A trim now counts the rows on screen and 30 either side, and a followed channel keeps its newest 200 messages, or the ones in view and 50 above them if that's more.

Each time the Discord side told the app what's new, up to ten times a second, it also built every DM and friend list again, 3,870 allocations a time (?????). It's 38 now, because those lists are shared until one of them changes. Heap at idle on the same account went from 31.1 MiB to 27.5 MiB.

Markdown

A message with a heading, a quote or a code block would give up and show as plain text, bold and links gone too (#17). They all show like they do in Discord now, subtext included, in messages, embeds, pins and search :D

A message from raiden: the heading Mission briefing, the small line do not tell the Patriots, the quote Kept you waiting, huh?, and a code block where ram_needed returns "40 MB" with the comment correct.

MesSecV4 is behind all of this, in five whole pull requests (#53, #55, #56, #57, #58). Click a link to a server, channel, message or person and it opens right there in Yapfast now. Anything it can't show, like a server you're not in, still goes to your browser.

Scheduled events open in a dialog where you can mark yourself interested. Gift links show what the gift is and let you redeem it, except the ones that need a payment method or come from a promotion, which go to Discord. Links that add an app or a bot get a dialog that spells out what it's asking for in Discord's own words, with a big red warning for the scary stuff.

The Authorize Alien App dialog: a red warning that its bot asks for Administrator, every permission in the server, then the list of what it asks for and a server picker, with Cancel and Authorize buttons.

After you authorize, Yapfast only ever opens a web page, so a link in a message can't start some other program on your computer.

Want Discord links from other apps to come here too? It's Settings → Advanced → Open Discord links in Yapfast. It won't take them until you turn that on, and turning it off (or uninstalling, on Windows) gives them back to whatever had them before.

Calls

You can set your microphone's and speakers' volume now, 0% to 200%, for every call (#43). Boosting a quiet mic won't clip on every shout either, since it never goes past 90% of full scale.

Two sliders in Voice & video settings: Microphone volume at 137% and Speaker volume at 100%.

Bluetooth headphones dropping out left the call silent until you left and joined again (fun). Now Yapfast goes back to them within about 2 seconds of them returning, and settings show "Headphones (not connected)" in the meantime. I only tested this by unplugging fake devices in a private audio session, not real headphones, so if yours do something dumb, tell me.

Other people's cameras looked awful (#63), and that one's on me; Yapfast was asking Discord for the potato version. It asks the way Discord's desktop app does now. I haven't tried this against a real Discord client yet, or measured what the bigger pictures cost, so let me know if your friends still look like Minecraft :p

Noise suppression takes about half the CPU now while nobody's talking, and sends the same speech as before. It does stay loaded while you're muted though, where unmuting used to load it all over again, so that's 39 MiB it used to give back (leaving the call still frees it). I think that's the right trade, but if you sit muted all day and disagree, yell at me in the GitHub issues :D

For nerds

Cameras go by Discord's quality value. Yapfast asked for 50 on any tile under 360 pixels tall, which is 416×234 at up to 264 kbit/s (potato confirmed), and when you were the only one watching, that's what you got. Two cameras in a channel now ask for 90, 896×504 at up to 1.2 Mbit/s.

DeepFilterNet stops running its two decoders in a pause, past the voice gate's hold, so a block with no speech takes 162–211 µs on average against 334–345 µs on my Ryzen 9 9900X. While push to talk is idle it's about 125 µs against 296–338 µs. Unmuting took 0.2 s of a core to load the model.

Quick switcher and the rest of chat

Ctrl+K opens the quick switcher now (#47, thanks mortan!), with the conversations you opened lately before you type, and Discord's @, #, ! and * prefixes when you search.

The quick switcher with me typed in it, listing #memes and #movie-night in Outer Heaven, the server NixOS: works on my machine, and the voice channel Summoner's Rift in ff15.

mortan also got media channels to show up at all (#44), and they open like forums for now, without Discord's gallery. Animated Lottie stickers play now thanks to pkejval (#23), and blockgameentity made the GIF picker stretch from its left edge (#62), so there's more room for the GOATed GIFs, and it remembers how wide you left it.

Some videos from OBS and cameras only showed their poster, and videos from phones skipped their sound. Both fixed :D

For nerds

The videos stuck on their poster were 10- and 12-bit ones and 4:2:2 and 4:4:4 ones. All of those play now except 12-bit 4:2:2 and 4:4:4. Phone videos' sound trails the picture by up to a second, and the player stopped reading too early. In a 20 second test video, the sound ran short in 1540 of 2005 steps, and now in 2.

Smaller stuff, in no particular order:

  • Settings → Discord lists the people you blocked, with an Unblock button.
  • You can leave a group DM from its menu, with Discord's box for leaving without telling anyone (sneaky).
  • People you share a server with show their status in DMs, instead of showing offline unless they're your friend.
  • A channel whose newest message doesn't show (deleted, or from someone blocked) doesn't stay unread forever anymore (#45).
  • Accepting a friend request from a stranger just failed, and those are most of what that screen holds. It works now (#71, thanks ExperiencesXP!).
  • Slint doesn't fill your log with warnings on every frame anymore (#66).

Windows

With GPU rendering on, NVIDIA cards kept about one whole core busy just waiting for the screen (?????), so that setting draws with Direct3D 12 now. Wine can't show me NVIDIA's CPU use though, so if you have an NVIDIA card, tell me if that core is free now.

Pasting a screenshot with Ctrl+V just did nothing on Windows (#59), thanks to a bug in a library Yapfast used. Yapfast reads the clipboard itself now, and pictures keep the format they were copied in, so a GIF stays animated. I tested this under Wine, not on real Windows or with its clipboard history, so fingers crossed..

Building it yourself

A plain cargo build links on Linux now, without the Nix shell (#49), and blockgameentity made cargo build --release work on Windows itself (#70), about 11 minutes from cold, where it could only cross-build from Linux before.

The releases are Discord-only, so this one's just for people who build with Matrix. Matrix's SDK was renewing a lock in its database 20 times a second, idle or not, which came to about 8 GB written to your disk a day (#60). It's 180 MB now.

Nine of the things above started as someone's issue, so thank you, and keep them coming, on the Discord server or in an issue.

Thanks for reading, and stay blazingly fast <3

More posts

Download Yapfast for Windows

The installer isn't signed yet, so Windows SmartScreen may warn you. Choose More info, then Run anyway.

Download Yapfast for Linux

Make the AppImage executable (chmod +x, or "Allow executing" in its properties), then run it. On Nix, it's nix profile add github:yapfast/yapfast#yapfast.

No build for your platform yet :(

But you can build it yourself; the README walks you through it.

Build it yourself

Getting it for another PC? Here's the Windows installerand portable ZIP, and the LinuxAppImage.