Hacker Newsnew | past | comments | ask | show | jobs | submit | bruce343434's favoriteslogin

My first instinct for a poorly predicted branch would be to use a conditional move.

This isn't always a win, because you prevent the CPU from speculating down the wrong path, but you also prevent it from speculating the correct path.

If you really don't care about the failure path and really don't mind unmaintainable low-level hacks, I can think of a few ways to get creative.

First there's the whole array of anti uarch-speculation-exploit tricks in the Kernel that you can use as inspiration to control what the CPU is allowed to speculate. These little bits of assembly were reviewed by engineers from Intel and AMD, so these tricks can't stop working without also breaking the kernel with it.

Another idea is to take inspiration from anti-reverse engineering tricks. Make the failure path an actual exception. I don't mean software stack unwinding, I mean divide by your boolean and then call your send function unconditionally. If the boolean is true, it costs nothing because the result of the division is unused and we just speculate past it. If the boolean is false, the CPU will raise a divide by 0 exception, and this invisible branch will never be predicted by the CPU. Then your exception handler recovers and calls the cold path.


The behavior of C macros is actually described by a piece of pseudocode from Dave Prosser and it is not in the standard:

* https://www.spinellis.gr/blog/20060626/

* https://www.spinellis.gr/pubs/jrnl/2006-DDJ-Finessing/html/S...

* https://gcc.gnu.org/legacy-ml/gcc-prs/2001-q1/msg00495.html


My thoughts on this are to add a third keyword alongside `break` and `continue` to loops that allow you to push another (loop) stack frame and descend into a tree-like data structure.

For exposition, lets seperate loop initialization from the rest, make `continue` mandatory to repeat the loop with another specified value (i.e. the loop implicitly ends without a continue) and lets say `descend` to recurse into the tree.

    sum = 0;
    loop (node = tree.root) {
        sum += node.value;
        if (node.left) descend node.left;
        if (node.right) descend node.right;
    }
Compare with a linear loop:

    sum = 0;
    loop (i = 0) {
        if (i >= array.length) break;
        sum += array[i];
        continue i + 1;
    }
The `descend` keyword differs from `continue` in that its more of a continuation - control flow will continue from that point once it is done.

You could make this more functional and less imperative (and I'd be surprised if such things don't exist as libraries in some functional languages). Yes ultimately we can transform this to recursive functions and compile it that way... but for imperative languages (especially those without closures) something like the above might be useful.

Arguably the above loops are _more_ imperative and less declaritive than the standard ones from the C family. You could add a functional twist by breaking with a value (which is the result of the overall `loop` expression).


every websocket setup is painless when running on a single server or handling very few connections...

I was on the platform/devops/man w/ many hats team for an elixir shop running Phoenix in k8s. WS get complicated even in elxir when you have 2+ app instances behind a round robin load balancer. You now need to share broadcasts between app servers. Here's a situation you have to solve for w/ any app at scale regardless of language

app server #1 needs to send a publish/broadcast message out to a user, but the user who needs that message isn't connected to app server #1 that generated the message, that user is currently connected to app server #2.

How do you get a message from one app server to the other one which has the user's ws connection?

A bad option is sticky connections. User #1 always connects to server #1. Server #1 only does work for users connected to it directly. Why is this bad? Hot spots. Overloaded servers. Underutilized servers. Scaling complications. Forecasting problems. Goes against the whole concept of horizontal scaling and load balancing. It doesn't handle side-effect messages, ie user #1000 takes some action which needs to broadcast a message to user #1 which is connected to who knows where.

The better option: You need to broadcast to a shared broker. Something all app servers share a connection to so they can themselves subscribe to messages they should handle, and then pass it to the user's ws connection. This is a message broker. postgres can be that broker, just look at oban for real world proof. Throw in pg's listen/notify and you're off to the races. But that's heavy from a resources per db conn perspective so lets avoid the acid db for this then. Ok. Redis is a good option, or since this is elixir land, use the built in distributed erlang stuff. But, we're not running raw elixir releases on linux, we're running inside of containers, on top of k8s. The whole distributed erlang concept goes to shit once the erlang procs are isolated from each other and not in their perfect Goldilocks getting started readme world. So ok, in containers in k8s, so each app server needs to know about all the other app servers running, so how do you do that? Hmm, service discovery! Ok, well, k8s has service discovery already, so how do I tell the erlang vm about the other nodes that I got from k8s etcd? Ah, a hex package cool. lib_cluster to the rescue https://github.com/bitwalker/libcluster

So we'll now tie the boot process of our entire app to fetching the other app server pod ips from k8s service discovery, then get a ring of distributed erlang nodes talking to each other, sharing message passing between them, this way no matter which server the lb routes the user to, a broadcast from any one of them will be seen by all of them, and the one who holds the ws connection will then forward it down the ws to the user.

So now there's a non trivial amount of complexity and risk that was added here. More to reason about when debugging. More to consider when working on features. More to understand when scaling, deploying, etc. More things to potentially take the service down or cause it not to boot. More things to have race conditions, etc.

Nothing is ever so easy you don't have to think about it.


The last generation of Psion's in-house C++ Arm32 OS, Symbian, is now FOSS:

https://github.com/SymbianSource

Please, please, someone revive this. It was a pleasure to use.

Junk as much as possible of the idiosyncrasies and slap a standard GUI toolkit on top, like Qt or Gtk or something.

It already has a POSIX layer:

https://en.wikipedia.org/wiki/P.I.P.S.

It's as if BeOS had been open sourced and nobody noticed.

It's more complete and more functional than Genode, for instance. It runs on bare metal, unlike Serenity OS.


I think the true term for this phenomenon is "decoherence" rather than "decoupling". Your components are still as coupled as they ever were, but the coupling has moved from compile-time (e.g. function calls) to runtime. The component that "handles events" decoheres the entire system because it's now responsible for the entire messaging layer between components, rather than the individual components being responsible for their slice of the system.

Short explanation:

1. The largest power of 2 that divides x is just 2^(number of trailing zeros in x)

2. Crucial observation: -x == ~x + 1

3. ~x flips all the bits of x bits, so none of the bits of ~x match those of x. (i.e. (x & ~x) == 0)

4. When you do +1, all the trailing 1's flip AGAIN, becoming zero like they were in x. The next highest 0 (say it was the n'th) also flips, becoming 1... like it was in x.

5. Crucial observation: The n'th 0 did NOT match the corresponding bit in x prior to the increment, therefore it MUST match after the increment. All higher bits stay as-is.

6. This leaves only the n'th bits matching in x and ~x + 1, isolating the highest power-of-2 divisor of x when you AND them.


I'm glad this worked for you, but I don't think that you understand OP's central argument about the penalties imposed by the substantial ergonomic mismatch between ADHD "smart" and the conventional species, and may not have as strong a sense of what being on the inside of this condition feels like.

ADHD wiring essentially forces every task to be derived from a set of fundamental axioms about why the task must e done, why it must work the way it does, with an almost proof-like causal chain working all the way back to first principles, in order to simply remeber it in a stable way. Being interested in a subject can benefit you only in so far as it will provide you with motivation to build out a vast knowledge graph scaffold around the set of tasks that need to be done, in order to not feel like you are kicking a dead whale up the beach every time you have to start doing one of them.

But if you are presented with a subject where there is no time to do this, or the type of subject where it is actually not possible and only the muscle memory of rote memorization will power you through it, it doesn't matter how much it subjectively appeals to or interests you. You are going to be at the back of the pack despite your best efforts.

Attempts to give you help will only frustrate your (very likely memorization-gifted) tutors and mentors: they don't understand what's going on, so you merely look stupid, unmotivated or both. However, if you had enough runaway, they would find that not only you would catch up to wherever everyone else was (in one third of the time it took you,) but after another third share of prep time you would move from the bottom decile to the top, with gains still compounding. But this occasion almost never presents itself, because you're typically flushed out of the cycle long before you build enough inertia in the domain to show what you're capable of.

One can go almost sick with envy over the way neurotypically smart people are almkst unaware of how easily and quickly they retain multiple arbitrary lists of "how" steps in processes, even when these are largely self-contained and unconnected to any other chain of reasoning, and just get shit done without having to know how the entire superstructure is put together.

You'll be almost comically bad at (and find little pleasure in) all board games (except the most popular ones you've had years of exposure to), if you have not had time to master them ADHD style - even if you genuinely enjoy board games in principle. Whereas peers in your same nerd adjacent circle seem to reach competence or even mastery of any example in this genre of bureaucracy-as-a-sport within a few plays. Performing on stage, if there are more than a handful of lines to memorize, is utterly out of the question. Even if you love acting or theater, it's just not for you.

My own testament to this paradox is not from board games, but incredibly demoralizong experience trying to learn the piano (as an adult no less), something I had more than ample interest in and motivation to learn, but which in the initial stages presented almost insurmountable obstacles when it came to simply memorizing the basics of sight reading, scales, and the learner's songbook. skills that I watched 7 and 8 year olds, teens and even fellow adult learners, acquire in weeks but took me well over a year to reach parity. Since my job and self-image werent riding on being at the top of the class, I was able to keep with it accordimg to my own pace. And although I probably still wouldn't get hired even for a gig in the local shopping mall, my ability to improvise and stylize outside the set pieces I had received my basic training on inexorably began to surpass most of that cohort who had lapped me several times over back when we were just doing the rote basics.


People always seem to think "premature optimization" means "premature optimization for speed". But there are lots of otherwise-good things that you can prematurely optimize for:

    - modularity
    - readability
    - abstraction
    - maintainability
    - scalability
    - reusability
    - testability
    - cost
We've all seen codebases that are over-abstracted in the name of code reuse, or to adhere to this or that software design philosophy, and are nightmares as a result. "You Ain't Gonna Need It" is a restatement of the premature-optimization adage, just for a different metric.

Cluster stability is a good heuristic that should be more well-known:

For a given k:

  for n=30 or 100 or 300 trials:
    subsample 80% of the points
    cluster them
    compute Fowlkes-Mallow score (available in sklearn) of the subset to the original, restricting only to the instances in the subset (otherwise you can't compute it)
  output the average f-m score
This essentially measure how "stable" the clusters are. The Fowlkes-Mallow score decreases when instances pop over to other clusters in the subset.

If you do this and plot the average score versus k, you'll see a sharp dropoff at some point. That's the maximal plausible k.

edit: Here's code

  def stability(Z, k):
    kmeans = KMeans(n_clusters=k, n_init="auto")
    kmeans.fit(Z)
    scores = []
    for i in range(100):
        # Randomly select 80% of the data, with replacement
        # TODO: without
        idx = np.random.choice(Z.shape[0], int(Z.shape[0]*0.8))
        kmeans2 = KMeans(n_clusters=k, n_init="auto")
        kmeans2.fit(Z[idx])

        # Compare the two clusterings
        score = fowlkes_mallows_score(kmeans.labels_[idx], kmeans2.labels_)
        scores.append(score)
    scores = np.array(scores) 
    return np.mean(scores), np.std(scores)

There's a meditation I've found healing for memories like this.

>> In one instance, a teacher uttered the words ‘Ewan’s naturally bad at maths’. I was 6

The exercise goes something like:

Summon up a painful memory, like feeling underestimated by a teacher or ashamed of yourself. Let the memory (and feelings) get as strong as they need to be, without trying to suppress or judge how you feel. Then, imagine stepping into the memory and giving a younger version of yourself exactly what you needed. This is especially healing if there were adults in your early life may have failed to provide what you needed, and you're still holding on to pain/blame/spite.

Here's the guided meditation where I learned this technique:

https://timdesmond.net/self-compassion-skills-workbook/


I also use spreadsheets but not for content. Not only is it not guaranteed to be available before the design starts, but "design" is much more than just making the UI look nice. Also, applications (which is what I tend to work on) are much more than content.

My method is meant to expose the business rules. I start out with a single column, and I list every "rule" of the application. So something like "A user cannot export their dashboard without a premium account". Once I have a complete list, I go back and tease out any significant nouns and verbs.

So given the sentence "A user cannot export their dashboard without a premium account", the significant terms are "user", "export", "dashboard", and "premium account".

For each of these terms, I create a separate checkbox column and mark the checkbox if the rule applies to that term.

Once you've done this with enough rules, you'll start to see your domain model form. It exposes all sorts of inconsistencies in your rules and forces you to be very clear about how the application is expected to behave. It also forces you to clarify your language because there will be multiple terms that refer to the same concept, and part of the process is removing these duplications.

It's a great way to get clarity around your product before you start building out the experience.


I posted a much more concise derivation (and implementation, in just 16 lines) on HN a while back but didn't gain much traction:

https://news.ycombinator.com/item?id=35899215

Here are the 16 lines in full:

   function sprung_response(t,d,v,k,c,m)
      local decay = c/2/m
      local omega = math.sqrt(k/m)
      local resid = decay*decay-omega*omega
      local scale = math.sqrt(math.abs(resid))
      local T1,T0 = t , 1
      if resid<0 then
         T1,T0 = math.sin( scale*t)/scale , math.cos( scale*t)
      elseif resid>0 then
         T1,T0 = math.sinh(scale*t)/scale , math.cosh(scale*t)
      end
      local dissipation = math.exp(-decay*t)
      local evolved_pos = dissipation*( d*(T0+T1*decay) + v*(   T1      ) )
      local evolved_vel = dissipation*( d*(-T1*omega^2) + v*(T0-T1*decay) )
     return evolved_pos , evolved_vel
   end
And the embedded interactive demo in the blog post:

https://www.desmos.com/calculator/ynbtai98ns

I'm hesitant about reposting as all of my submissions had been inexplicably blocked by HN filters, by the time someone vouches the post it has already been buried.


In a similar vein, JT Nimoy has an illuminating writeup on her work for Tron Legacy's "futuristic hacker interfaces": https://www.talisman.org/~erlkonig/misc/tron-legacy-effects-...

I use the usual adblocker UBlock and:

* https://addons.mozilla.org/de/firefox/addon/canvasblocker/

which prevents fingerprinting via Canvas elements, additionally warns you if a site does it. There are more sites out there than you would assume. Some stupid blogs even.

* https://addons.mozilla.org/en-US/firefox/addon/multi-account...

This splits your tabs into different categories, each with their own cookie storage.

The fingerprinting website in the article didn't manage to correlate me visiting the website concurrently from two distinct container tabs.


Prediction is compression. They are a dual. Compression is intelligence see AIXI. Evidence from neuroscience that the brain is a prediction machine. Dominance of the connectionist paradigm in real world tests suggests intelligence is an emergent phenomena -> large prediction model = intelligence. Also panspermia is obviously the appropriate frame to be viewing all this through, everything has qualia. If it thinks and acts like a human it feels to it like it's a human. God I'm so far above you guys it's painful to interact. In a few years this is how the AI will feel about me.

This is a good list! Another fun quirk: because x86 is a register-memory architecture and allows all kinds of variants of reg/mem operand encodings, there are a handful of equivalent encodings with exactly the same lengths (and just slightly different ModR/M bytes). You can take advantage of this to do software fingerprinting or, in my case, steganography without changing an executable’s size or semantics[1].

[1]: https://github.com/woodruffw/steg86


I've been using ChatGPT pretty consistently during the workday and have found it useful for open ended programming questions, "cleaning up" rough bullet points into a coherent paragraph of text, etc. $20/month useful is questionable though, especially with all the filters. My "in between" solution has been to configure BetterTouchTool (Mac App) with a hotkey for "Transform & Replace Selection with Javascript". This is intended for doing text transforms, but putting an API call instead seems to work fine. I highlight some text, usually just an open ended "prompt" I typed in the IDE, or Notes app, or an email body, hit the hotkey, and ~1s later it adds the answer underneath. This works...surprisingly well. It feels almost native to the OS. And it's cheaper than $20/month, assuming you aren't feeding it massive documents worth of text or expecting paragraphs in response. I've been averaging like 2-10c a day, depending on use.

Here is the javascript if anyone wants to do something similar. I don't know JS really, so I'm sure it could be improved. But it seems to work fine. You can add your own hard coded prompt if you want even.

    async (clipboardContentString) => {
        try {
          const response = await fetch("https://api.openai.com/v1/completions", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              "Authorization": "Bearer YOUR API KEY HERE"
            },
            body: JSON.stringify({
              model: "text-davinci-003",
              prompt: `${clipboardContentString}.`,
              temperature: 0,
              max_tokens: 256
            })
          });
          const data = await response.json();
          const text = data.choices[0].text;
        return `${clipboardContentString} ${text}`;
        } catch (error) {
          return "Error"
        }
      }

It was painfully easy for me to find my PNP deficiency.

- I had my genome run my 23andme (twice). - I plugged the raw data into https://promethease.com/. - I sorted it by frequency. - Then just researched every rare polymorphism.

It would be so simple to write an algorithm that does this.


> How the fuck does ext4 [...] still have problems with this?

I'm increasingly realising that most of the code out there isn't tested anywhere near as well as we think it is. Most programmers stop when the feature works, not when the feature is bulletproof.

I've been writing a database storage engine recently. It should be well behaved even in the event of sudden power loss. I'm doing "the obvious thing" to test it - and making a fake, in-memory filesystem which is configured to randomly fail sometimes when write/fsync commands are issued (leaving a spec-compliant mess).

I can't be the first person to try this, but it feels like I'm walking over virgin ground. I can't find a clear definition of what guarantees modern block devices provide, either directly or via linux syscalls. And I can't find any rust crates for doing this programatically. And googling it, it looks like many large "professional" databases misunderstood all this and used fsync wrong until recently. Its like there's a tiny corner of software that works reliably. And then everything else - which breaks utterly when the clock is set to 2038 because there aren't any tests and nobody tried it.

I half remember a quote from Carmack after he ran some new analysis tools on the old quake source code. He said that realising how many bugs there are in modern software, he's amazed that computers boot at all.


The real canary in the coalmine was actually a movie from 1999 called "Enemy of the State."

The plot for the movie was actually based on an account from an NSA employee who tipped one of the producers or director (I forget which) of the mass surveillance the agency was involved in.

To me this movie is iconic just because it predicted events so vividly almost a quarter of a century ago.


I have a slight fascination with sweeteners. About five years ago I imported a kilo of "Neotame" sweetener from a chem factory in Shanghai. It was claimed to be 10,000-12,000 times sweeter than sugar. It's a white powder and came in a metal can with a crimped lid and typically plain chemical labeling. Supposedly it is FDA-approved and a distant derivative of aspartame.

US customs held it for two weeks before sending it on to Colorado with no explanation. When received, the box was covered in "inspected" tape and they had put the canister in a clear plastic bag. The crimped lid looked like a rottweiler chewed it open and white powder was all over the inside of the bag. I unwisely opened this in my kitchen with no respirator as advised by the MSDS which I read after the fact (I am not a smart man).

Despite careful handling of the bag, it is so fine in composition that a small cloud of powder erupted in front of me and a hazy layer of the stuff settled over the kitchen. Eyes burning and some mild choking from inhaling the cloud, I instantly marveled at how unbelievably sweet the air tasted, and it was delicious. For several hours I could still taste it on my lips. The poor customs inspector will have had a lasting memory of that container I'm pretty sure.

Even after a thorough wipe-down, to this day I encounter items in my kitchen with visually imperceptible amounts of residue. After touching it and getting even microscopic quantities of the stuff on a utensil or cup, bowl, plate, whatever, it adds an intense element of sweetness to the food being prepared, sometimes to our delight. I still have more than 900g even after giving away multiple baggies to friends and family (with proper safety precautions).

We have been hooked on it since that first encounter. I keep a 100mL bottle of solution in the fridge which is used to fill smaller dropper bottles. I've prepared that 100mL bottle three times over five years, and that works out to about 12g of personal (somewhat heavy) usage for two people in that time. Probably nowhere near the LD50.

I carry a tiny 30mL dropper bottle of the solution for sweetening the nasty office coffee and anything else as appropriate. Four drops to a normal cup of coffee. We sweeten home-carbonated beverages, oatmeal, baked goods (it is heat stable), use it in marinades, and countless other applications.

I don't know if it's safe. The actual quantity used is so incredibly tiny that it seems irrelevant. I'd sweeten my coffee with polonium-210 if it could be done in Neotame-like quantities. Between this, a salt shaker loaded with MSG and a Darwin fish on my car, I'm doomed anyway.


If you're ray-tracing voxels on a GPU, one technique is to use a single bit per voxel (so 32 voxels per uint32_t: a 0 bit means empty, a 1-bit means filled) and then put the whole voxel space into a Morton space-filling curve like this:

https://bugfix-66.com/e2d9aaf5b7f285b4d35c46e87fcf6f7e25d338...

You can then cast rays through 3D space mapped onto 1D space, with one ray per GPU thread.

The space-filling curve gives you locality of reference (just like an octree), and the simple linear nature of the data means you can use a sparse bit vector to represent it. Huge regions without voxels are represented implicitly:

https://bugfix-66.com/7256e0772dc3b02d72abf15b171731c933fd44...

Of course, you want a much larger branching factor (to get a shallower tree) for rendering.

You can step your ray through the space without deinterleaving the bits, like this:

https://bugfix-66.com/d6907b4d3eb6330241128ffbaeef6194ddeecc...

This technique allows extremely detailed (and real-time editable!) voxel worlds with tiny code.



As University libraries have moved online, one reads many poorly scanned journal articles. I often wonder about taking the time to clean them up. What replaces temporal information here is the same characters appearing over and over.

So of course I read this article hoping to learn about an off-the-shelf tool that would do a great job of scanned text reconstruction. Alas, the best candidates were "no code available."


A number of NFT promoters have made the argument that other video games could support the WoW NFT and then that content would be portable across those games!!!

Okay, but none do, and none will, and any other video game that did code in a substantially similar functionality would simply sell the same content in their own game, there's no benefit to the company to spend the time and money to make the content and not get compensated for it especially given radically different content architectures, visual styles, levels of detail, physics, object-player interactivity, etc. You can tell this is true, because they could already make it interoperable now and they don't -- like it's entirely possible that Marvel could sell "buy the Spider-Man game and get Spider-Man costumes in every other game he's a crossover character, across all platforms" and they... absolutely don't do this!

But also this vision is predicated on there being a small number of canonical NFT brands, when in reality you can open up Grand Theft Auto Online and there are literally tens of thousands of items made for the game. So if there's 10,000 items made for GTA Online and 50,000 items made for the Sims Series, then interoperability means that Square Enix needs to add 60,000 items to Final Fantasy to support subsidizing the NFT marketplace for the other two games? Or else you sit around trying to import your Mercedes Hood Ornament NFT from Forza into Mortal Kombat 13 and it tells you "hey, we don't support that one! Or that one! Or that one! Or that one!"

And you can tell this is true because Nintendo already has a system for this called Amiibo where you buy little figurines with fungible codes that putatively can work in any game that supports them. And 99% of games on Switch don't support any, the ones that support any only support 1 or 2, and only one game supports more than 10 or so, and it's a crossover fighting game called Smash Bros.

You might say, okay, but Amiibo are finnicky, they take up space, NFTs improve on Amiibo by not having you actually need a physical object. Okay, but the vast majority of the value is in the physical object. You can tell this is true because Nintendo has the capability of reprinting the relatively expensive physical figurines as marginally nearly zero cost trading cards and... they don't, because there's no real demand.

But then you say, no, the key thing to NFTs is their non-fungibility. Okay, but that's a horrid fit for games. Now instead of modelling Mario once, I need to model Mario a hundred thousand times. If the differences are small between each model, then I get the benefits of procedural generation so it's less work, but the market collapses because the token is as-if fungible and that means the supply is as-if unbounded. And as Nintendo, wouldn't I rather sell each Mario costume for $1 to every player that wants it rather than selling one Mario costume for $100 to someone and then establish an elaborate crypto-driven derivative market where I get a chunk of each secondary sale?

It seems like the most obvious way you can make NFTs actually be something different is when you overtly lean into the bizarre gambling, ultra-rare one offs, and big money market speculation stuff, and at that point you no longer have a game at all, which is probably pretty bad if you're a game manufacturer. But game manufacturers have tried this too, with limited edition sales (Nintendo sold a game last year that they discontinued after 6 months to preserve scarcity, both digital and physical; Nintendo has also done ultra-rare and non-fungible collectible Pokemon leveraging real world events), numbered editions (Atlus with Devil Summoner 2 on the PS2 in 2006 or so). Even one-off multi-thousand dollar stuff has been done in the gaming industry, with special issue collectible hardware (Nintendo, Microsoft, and Sony have all done this).

Like the issues raised in the currently top upvoted thread, almost everything about NFT in video games is pretty easily analogized to something people have already tried and failed at in video games or something people currently do in video games more efficiently without NFT. And it seems the people entering the space, rather than study what works or doesn't, start from the premise that they read a novel that described something they thought was cool and then trying to blue sky that in video games.


Pretty cool!

I'm curious as to why this is offered as a cloud machine and not something that runs locally. Wouldn't the encoding performance on a free or cheap cloud instance be poor?

I create a lot of video compilations using twitch and youtube videos as source. My internet is 5Mbps down, 3Mbps up, so it can take hours to download long video streams and extract just the parts I want.

Because of my network limitation, I found a way to combine ffmpeg and youtube-dl to grab sections of video from a twitch or yt video. The following is an example which replicates the videodownloadtool.io example.

    ffmpeg -ss 00:15:34 -to 00:16:09 -i $(youtube-dl -f best -g https://www.youtube.com/watch?v=Qf2tplcb6eE) -vf "crop=(iw*0.75):(ih*0.80):(iw*0.20):(ih*0.08)" ./output.mp4

Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: