HackerTrans
TopNewTrendsCommentsPastAskShowJobs

lukeschaefer

no profile record

Submissions

Show HN: Chrome Please Fix Your Audio

chrome-please-fix-your-audio.xyz
4 points·by lukeschaefer·2년 전·0 comments

comments

lukeschaefer
·6개월 전·discuss
Absolutely - one of my favorite bug with users was an application we had made in which the loading of a filtered view was so slow, that results would come in one-at-a-time, such that clicking 'select all' would only select those ones. When this was removed, users complained until we added shift-clicking to select groups of items
lukeschaefer
·2년 전·discuss
Leading to a new equilibrium. That equilibrium will not necessarily be one favorable to human life. In the same way that eating an extra 5 donuts a day might lead to a new equilibrium of your weight, but that doesn't necessarily imply one is healthy.
lukeschaefer
·2년 전·discuss
Ah that's on me, it's a private repo because my code is embarrassing. But behind the scenes here's how it works:

- I wrote my own scraper for HN for reasons I no longer remember

- Scraper is called every 30 seconds by an Apps Script timer on a Google Sheet (to be dirt cheap, Vercel doesn't have free cron jobs).

- Caches the front page, plus ten comments per post into a single Firestore document (to save money on reads vs 20 reads per load)

- Home page loads via SSR with Nuxt.

- Post pages will load the rest of the comments from a separate doc for each post

- the other comments load instantly on navigation if on a halfway decent connection - but if not, you still get to see the first 10 comments to get an idea of the discussion while you wait.

- Added some Workbox stuff to get it offline-first.

- Added an IndexDB wrapper around Firestore for more control over cache behavior I think.

- It's worked now for over a year with no oversight needed and not costing a penny!

Then I got distracted because I wanted to rebuild it from scratch to not use Nuxt and never completed that rewrite. Been a while since I've worked on it, had no idea other people even knew it existed! There's definitely some bugs (I think CSS gets broken on deeply nested comments) but it worked enough for my uses so I moved on.
lukeschaefer
·2년 전·discuss
Author of hn.zip here - thanks so much for the shout out! I never really publicize it and never 100% finished it, but I'm so glad people are using it! It's basically how I browse HN on my phone and once it reached 90% good enough I stopped working on it haha.
lukeschaefer
·2년 전·discuss
Since I'm bored - here's a quick run down of how this works, split into chunks.

#1 - Function Wrapper:

   (r = n => setInterval(t => {
        ...
    }, 100))()
Here a number of things are done:

- set `r` to the function that runs the whole quine.

- when r is called (inline immediately at the end) it sets an interval to call the body every 100ms.

- `n` is unused, and is there for spacing instead of using `()` to indicate no params.

#2 - Row Looper:

    for (j = o = "\n", y = 5; y--; document.body['innerHTML'] = "<pre>&lt" + (S = "script>\n") + o + "\n\n&lt/" + S)
- create a loop that will occur 5 times (one for each row of the output).

- initialize some variables `j` and `o` to newlines. `o` will contain our rendered output, `j` will soon become an incrementor.

- after each loop, put the contents of 'o' between two strings of "<script>".

- the `S = "script>\n"` portion helps with spacing and S is no longer needed after this line.

#3 - Column Looper:

    for (x = -001; x++ < 63; o += `(r=${r})()`[j++].fontcolor(c ? '#FF0' : "#444"))
- loop through the 64 columns, incrementing x and j.

- x keeps track of the column, j keeps track of the character within the Function `r`.

- each loop, `o` adds a letter from `r`. (In Javascript, functions can be converted to strings which contain their source).

- Also add the `)()` to the end of `r`, which the implicit Function.toString() will not have.

- Set the fontcolor on that string based on `c` - String.fontcolor() is an old deprecated method which wraps your string in a `<font>` tag.

#4 - Renderer:

    c = x / 2 % 4 < 3 && [31599, 19812, 14479, 31207, 23524, 29411, 29679, 30866, 31727, 31719, 1040][(D = Date()[16 + (x / 8 | 0)]) < 10 ? D : 10] & 1 << (x / 2 | 0) % 4 + 3 * y
- The array of numbers is essentially a font, defining the numbers 0..9 and lastly ":"

- We pick which character of this font to render based on a Substring of Date(). Either a number, or ":".

- Date()[16] is where the Time string starts, and chars are rendered 8 blocks wide.

- With the beginning `x / 2 % 4 < 3` we render 2 spaces of dark characters between numbers.

- At the end, render our `font` with the x and y coords

- x is divided by two, so all pixels in this font are two characters wide.

- font glyphs are 3x5, and thus defined as 15 bits.

- for example, the glyph for '0' is:

   111
   101
   101
   101
   111

 - which results in 0b111101101101111 and therefor 31599  
 - To render these characters, we bit shift (<<) the number by the row & col*width and see what value is in the `1` place.
#5 - Coming together

Now just travel the last few steps back up the chain again, and you can see how these characters are placed in `o` - and if `c` is true (we hit a character) it is rendered yellow. `o` is put between a "<script>" and that resulting string is put in document.innerHTML every 100 milliseconds.
lukeschaefer
·2년 전·discuss
10 cases in several years, and "in all of the cases, the people had some sort of immune-compromising condition, mostly cancer, but also solid organ transplant and HIV. This likely put them at higher risk for infection and severe outcomes."

So yes, use distilled water... but in terms of risk factor, I don't think it's too high.
lukeschaefer
·2년 전·discuss
Haha those are my photos! Forgot I had that placeholder in there. I'll remove it until I have a tutorial video in place - that's my last major task left, outside some bug fixes and waiting for Chrome to fix their audio.

As for how the site works - make sure you have a microphone and ideally headphones. Click START and you'll hear a metronome. Click ADD TRACK to record a loop. If you're musically inclined you can combine multiple recordings to make a short looping song, by either adding bars to a loop or layering multiple tracks. Hit CTRL or right-click (long press on mobile) a track to modify how it sounds or delete it.

I'll post it to Show HN hopefully soon.
lukeschaefer
·2년 전·discuss
I just filed https://chrome-please-fix-your-audio.xyz the other day for chrome bug #327472528 - apparently all audio output is noise-reduced from audio input in Chrome - even when using headphones and when explicitly disabling this feature in the Web Audio API. It basically means you can't make any music app where you sing along with a background track, among other obvious use cases for microphones.

https://issues.chromium.org/issues/327472528