621

May 31st, 2023 × #Svelte#WebDev#Podcasting

The New Syntax Site × Ingest, Stack, AI and more

Scott and Wes discuss building the infrastructure and backend for the new Syntax.fm website. Topics include choosing SvelteKit, setting up GitHub OAuth, integrating PostCSS, and leveraging AI for automated podcast transcription.

or
Topic 0 00:00

Transcript

Wes Bos

Hey, everybody. Welcome to Syntax, the podcast with the tastiest web development treats out there today.

Wes Bos

Scott and I are going to be going through sort of work in progress on the new syntax website, some pretty fun stuff, as well as, like, Just how you tackle building a website like this because there's a lot of moving parts we're going to talk about.

Topic 1 00:17

Wes and Scott discuss website infrastructure

Wes Bos

We're not at the like nice CSS stage just yet, but we're more at the, like, infrastructure lower level types of things. And we're going to discuss what stack My name is Wes Bos. I'm a developer from Canada with me as always, mister Scott Talinski. How are you doing today, Scott? Hey.

Guest 2

Oh, hey. I'm doing I'm doing pretty decent. You know, we had, like, record setting rains here in Colorado the past few days, and, like, Man, it's been kinda iffy. We we had our our just a roof is from the nineties, and we knew it needed to be replaced. And we were just holding out for, like, a hailstorm and didn't get that hailstorm, ended up getting several days full of rain. Next thing you know, we have a leak in the roof and in the ceiling.

Guest 2

Big old, nasty wet spot in the ceiling that we're gonna have to take care of. Already got the roof people on the line, but, man, it's been just nonstop rain. We've never seen Anything like it in the entire time I've been living here, but, I'm sure all of our reservoirs, all of our rivers, all that stuff are very happy. But It's it's been wild because it's almost like every other neighbor that we had was having some bit of flooding, some bit of House emergency.

Guest 2

So we were on duty. Everybody was kind of helping together. There's no no major floods or anything, but, yeah, definitely concern.

Wes Bos

We have a hilarious story of our house leaking when I was a kid, and my, like, parents were out there, Like, in their pajamas, but adds in his underwear, and the neighbor comes over at, like, 3 AM and starts helping bail out.

Wes Bos

Oh, no. Yeah. No. Oh, Yeah. We didn't get that far. Let's get on into it. The new syntax website, we have been kind of been splitting Our work here and there, Scott's been taking on more of the foundational organizational part of the website, which is Getting all the bits and pieces in place. And then I've been sort of researching a lot of the a lot of the automation stuff, a lot of the AI show notes being being able to figure out how do we efficiently surface All of the content that is in both the older episodes as well as anything new that comes.

Guest 2

So, you wanna kick it off with the tech stack that we chose? Yeah. And and, Actually, even before we do that, Wes, I'm gonna tell you something. This building an aspect of this site has, like, Really opened my eyes to using light mode for things. I've changed my light dark mode over to system so that it auto toggles night. And And I gotta say there's something really refreshing about having big, you know, blindingly bright websites everywhere.

Topic 2 02:53

Scott switched to light mode

Guest 2

I'm still getting used to it, but I do think it is maybe just a little bit easier to read. What what is it about this website that makes you wanna go light mode? Like, why this website? Nothing specifically about this website. But when I was working on the theme engine, which we'll talk about, I was building in, like, the system toggle so that it, You know, by default, we'll give you light or dark mode based on your system settings.

Guest 2

And I just by the simple fact of turning on light mode to Give it a try and check it out. I was like, You know, and I haven't been here in a little while, and it's kinda novel and interesting. So Yeah. It's

Topic 3 03:58

Website is built with SvelteKit

Wes Bos

Give me different vibes. That's good. I I honestly I agree a lot. A lot of times websites have, like, white text on black, and I find I find that hard to read. I much prefer the opposite. So I think I'm a big dark mode user myself, but I never have it on system. I almost always have it on. I choose because if it's if it's not a good dark mode, it's hard to read, and I honestly think dark mode is a bit overrated. Yeah. Yeah. I don't know. I'd I'd It's still dark mode big dark mode fan, but, you know, also,

Guest 2

if I'm building a site and building sites and using interfaces, I think it's in my best interest to experience light and dark modes, all the modes possible. Like, really Get familiar with the patterns and everything rather than just pigeonholing myself into straight up dark mode.

Guest 2

But even actually, before we get in the tech stack, West, let's take a, like, a a second to talk about, like, the project management stack and, like, working in public and some of those aspects.

Guest 2

So this site is open sourced. It's available to be seen as we're working on it. You can follow along if that's something you're into.

Guest 2

We have a link in the show notes here. We'll have our all of our GitHub issues and their milestones and all of that will be public as well. The only thing that's not public so far is the projects aspect of this, but that will probably be public at some point. I I didn't have it public because we were, like, moving the repo around and stuff. So there was a little bit of, you know, give and play there. Either way so we'll have a link to the the branch. The branch is named v two. And, also, we we'll be updates to the Discord. If you're not a member of the Syntax Discord, I'll have a link for that in the show notes. You can also get updates. That way, you can follow along and see what we're working on. Now some people have have been wondering about when we're working public and we have these GitHub issues, is it appropriate Get to chime in and give my 2¢ on this and that and whatever here. And I think at some points, it might be maybe after you're using the thing And the things up, that might be a more appropriate time to do that. For right now, you know, maybe, take A glance at it, see what's going on, see what we're talking about, see how we're thinking about things, and see where those processes are before maybe Trying to, chime in too much, but either way, we are gonna be building in public. And if you wanna see how we're organizing this thing, The types of things we're doing for project management, the way that we're working on issues and things like that, those are all going to be public available for you to check out. And, You know, honestly, I we're still growing in in elaborating on it all the time, so it's just definitely overall a work in progress.

Guest 2

Alright. Tech Stack. Tech Stack, stacking it up, stacking that tech stack.

Guest 2

Hey hey, Wes. What was your high school DJ's name?

Wes Bos

We already talked about this before. High school DJ.

Wes Bos

I don't think we had a a DJ. Like, you you have a DJ at your middle school? And they don't have dances in Canada.

Guest 2

Oh, man. We had great school and high school. I just saw the word stack, and it, like, came into my brain, stacks of wax. That was ours. He had stacks of wax.

Guest 2

But what? You just have a DJ at your school all the time? No. For we we did, like, monthly school dances in middle school. Oh. They were called, oh, where I went to pop pizza pop candy fun. Maltby dances are number 1. Well, that's wild. We Would have

Wes Bos

dances every now and then.

Wes Bos

But it was usually just somebody's older brother who's Like, you always thought they were so cool, but then you realize, like, what what a degenerate of, like, this like, guy that's, like, 10 years older than us coming to play. Oh, yeah. There's, like, CDs, whatever. But My middle school party. Yeah. I went to a high school where, like, probably 60% of the thing was, like, very rural, people that went to it. So, like, usually, the high school dances were just, like, People drinking beer in the woods, like, they would just sneak away. So it wasn't as it's funny because I would always watch Movies growing up, and you would see what American middle school and football and high school. Oh, yeah. You you would see what all these things look like, and, like, Ours look nothing like that at all.

Guest 2

Ours definitely looked like that. We had a so in our activity nights, You could dance with the girls if you were cool.

Guest 2

You could play basketball if you were sporty.

Guest 2

Some people will just play basketball the whole time.

Guest 2

You play video games if you really wanted to ostracize yourself from the school at a school dance. You could just play video games the whole time, or you could just hang out, whatever.

Guest 2

They were a lot of fun. I remember that very vividly. Alright. Tech Stack. Stack to wax. In this tech stack, we've kinda gone Very similar to what we did in the claim or the, the coupon voucher, the giveaway site that we did. Yeah. Where we're using Prisma For the ORM, the basically, the connector from the data to the database, allowing us to work with the databases Easier.

Guest 2

We're using a MySQL database via PlanetScale currently.

Topic 4 08:59

Using Prisma and PlanetScale for the database

Guest 2

The benefits of that is it's just MySQL. So if, like, we wanted to Pick it up and move it or something like that. It's not gonna be that hard to do that. It's MySQL. But at the same time, it worked really well for the giveaway site.

Guest 2

It's nice and easy if you wanna run a local version of MySQL and connect via that way. You could do that as well. I'm running my development version just straight off of the the net, but you could do it local if you if you really wanted to. That should be no problem Because it's just straight up MySQL. Yeah. We should say that, like, the benefits of using

Wes Bos

something like PlanetScale is that You can deploy it serverless, meaning that if you need to connect 50 serverless functions to it, generally, you can't do that With most databases unless they're stateless because you need to create a database connection that stays open.

Wes Bos

And then when you send queries and mutations to it, they come back and forth. And if you have too many connections to a database, then it will say, yeah, that's too many For me to handle. So PlanetScale does that. It's called connection pooling. It does that for you. It does deploy previews branching a bunch of stats around it, which is My perfect kind of technology is 100% standard.

Wes Bos

None of our code has anything to do with PlanetScale. However,

Guest 2

They give us all the special sauce on top. All the special sauce on top, and Prisma makes it easy. You just pass them in the URL. You tell it to MySQL database, And it handles all the stuff that, we didn't wanna handle. You know, people around the time that we were picking this ORM was around the time that people were just starting to talk about things like Drizzle, as being like an alternative to Prisma.

Guest 2

But, honestly, I didn't wanna lose all of the migration stuff that you get with Prisma. There is a migration kind of beta tool in Drizzle right now, maybe further than that by the time you hear this, but probably not.

Guest 2

It's way not as mature, and the idea is is that you get to write MySQL type queries In an ORM rather than using ORM syntax to do, like, create many, delete all, whatever. Now For me, that's not a huge selling point because I'm not a MySQL wizard or anything like that. I I've been primarily working in MongoDB since Meteor came out, which was 2011. So it has been a very long time since I've written my sequel straight up. So for me, if the if the, selling point is, oh, it's just like Prisma, but you have to do more and you get to write, Rob MySQL, that to me is not, like, really that a huge sell for me. Yeah. No way, man. Just me personally. Yeah. I I just wanna be able to

Wes Bos

Run a method and pass all my stuff and have the whole thing typed start to finish. I don't want to have to enter join or deal with primary keys and whatnot. And Especially, like, what we're building is not

Guest 2

anything that would need raw straight performance like that. Yeah. And let me tell you. You know who's been a big help in all of this? Figuring out MySQL stuff or Prisma stuff or being able to ask questions is chat g p t. You know, I ask you questions, and since MySQL's, You know, mature enough of a technology, I can get real answers about things that I want to know. And it's giving me good good advice here and there. I'm using it To, help any sort of bumps along the way, but, you know, that's been a learning experience for me as well, moving off of MongoDB, having to create tables for So many things that I'm not used to creating tables for, you know, not not being able to do a an array of primitives.

Guest 2

It's like, ah, shoot.

Wes Bos

Do you have to worry that it is MySQL under the hood? Because I like, Prisma adapts to a number of different databases out Right? Like, you could use what are what are the ones that you could also use? Postgres.

Wes Bos

Postgres or SQLite or You could use Mongo with it. Yeah. There's a Mongo. So, like, when you're When you're making the schema for the syntax website, are you actively saying, okay. I'm doing this to MySQL wait? Like, you're saying, oh, I'm building tables. Doesn't Prisma take care of that for you? You have to tell Prisma that it is a MySQL database.

Guest 2

And because it's a MySQL database, that then puts in certain limitations.

Guest 2

For instance, like doing a field that's an array of primitives. So if I wanted to say, I have a roles property. This roles property is going to be a Array of strings.

Guest 2

And maybe these strings could come from an INA. Maybe they don't.

Guest 2

What you can't do In MySQL is do that, and and Prisma will say, hey. We noticed you're in a MySQL context, and you're trying to do an array of primitives.

Guest 2

You can't do that here.

Guest 2

So you have to create another model for whatever you're going to be doing. So I had to create a roles model and then make a seeding for it and have that be its own table rather than have its string of an array like you would. And, like, you would be able to do according to the documentation in Postgres.

Guest 2

So there is definitely limitations, but the linting in Prisma is so good But if I try to do anything like that, it gives me a red underline and a good error and a link to the documentation that tells where about it. That's great. And because of that, I'm learning quite a bit and able to, you know, go with it. But, you know, it is all a learning experience because when we did the giveaway site, The the modeling was not that intense. Well, we had claims, and we had, people who made the claims, whatever. We or you had a a Coupon code, and you had a user that submitted that coupon code, and that was really it. Within this process, I've already created a table for Users, roles, shows, guests.

Guest 2

I had one for themes at some point, but I've revised the theme system to be databaseless.

Wes Bos

So love it. I've got a bunch coming your way. And also the other thing I was going to ask, and I think I know the answer to this, is Once you have it set up, like, let's say you have a show and then you want to pass it a list of Like, you have an array primitive if I wanna pass it 7, 8, 9, whatever those values are. I don't have to, like, first create those primitives And then pass that into Prisma. Prisma will allow you to pass it nested content, and as long as it matches the relationships, it'll it'll update both of those tables. Yeah. For the best part and there are some times where you don't want to do that. For instance, like,

Guest 2

I have a guest, and I want to Upsert that guest. Right? If the guest exists already, I want to. So for some of those processes, I have taken it out of the flow to say, Alright. Do the guest. Check to see if the guest is there. Upsert it. Then then use that guest inside of the next object. So I have separated some of it, But the real benefit, I think, comes from querying the data because you'll be able to query data effortlessly to pull in the stuff. You know, I'm so used to Mongo where it's like, Oh, now I gotta either do an aggregation or I have to model my data in a way where everything is nested. And normally, I went the aggregation route, which is Heavier on the CPU and a little bit slower, but more freedom. And at that point, you're just like, why aren't you using a relational database anyways? So, you know, there there's so many different little little things here that I'm I'm picking up as I go. But for the most part, Prisma makes all that stuff really easy.

Guest 2

We both have experienced how nice and and, honestly, the the migrations aspect is one of those things that I just really migrations are painful for me. So being able to do PNPM DB push and have a a you know, migration go up is super easy for me, and it tells me if there's anything I need to think about or worry about or whatever. And I I I just been really, really fan of this stack. Let's get into the auth. I've already built in the auth for this. Oh, I I think you forgot a major part of the stack, which is Oh, yeah. I did. Yes. You're right. What? Oh, so wild. Okay. So, actually, I forgot some other things too because we're using post CSS as well. So post CSS That's the preset ENV for CSS.

Guest 2

Yeah. And I'm using an import glob plug in as well to glob CSS imports for the theme engine. We'll talk about that. But the site is built in SvelteKit server side rendered, so it's gonna be a server side based site.

Topic 5 17:04

Using PostCSS and import glob plugin

Guest 2

But we're gonna deploy it Probably on Vercel. I I think that's the, the current status of it, which we can then run serverless with our database and everything like that. So a SvelteKit site, And it's it's a joy. I love working in SvelteKit. Me too. I've very much enjoyed

Wes Bos

the 1st stack that we did, so I'm very looking forward to being able to add in my pieces. So I've been I've been building all of my hunks sort of outside of this Just because I've been doing a lot more experimentation,

Guest 2

but I'm almost at a point now where it makes sense to bring it in. Yeah. And and the data is in here in a way that it's Ready to be brought in.

Guest 2

So let's get into some of the stuff that's done, that's been worked on, that's, interesting here. So one thing that we've been doing Is I I wrote the auth for this already, and we went with just OAuth via GitHub being your developers. Right? This is a developer first thing. So I felt like instead of building out a whole auth system with emails and all this stuff, it's like, let's just move the auth to GitHub. Let's keep it that way. Let's do it OAuth. And instead of bringing any sort of auth package, which many of the auth packages that I found to just be really heavy handed, let me tell you.

Guest 2

Building a basic OAuth setup for GitHub Lockin is really not that tough. And if you wanna use our code for, you know, Ex explanation on how to do it for yourself, by all means, go ahead. You don't need to bring in an auth package all the time. Here's here's how we do it. So the very first thing we do is send a post request to our own endpoint.

Topic 6 18:27

Built custom OAuth authentication with GitHub

Guest 2

That endpoint from the server side Hits GitHub. But before it hits GitHub, it creates a UUID using random UUID.

Guest 2

This is a topic of a video that I wanna do. You don't need a dependency for UUID.

Guest 2

If you if you don't know about this, you can create a UUID or a unique identifier really easily, in node with the crypto package that comes with node via the random UUID Function.

Guest 2

And that gives you a random UUID. So that's our session token. So first and foremost, we hit this thing. We create our session token.

Guest 2

Okay. The session token is then used to create a session in our database.

Guest 2

K? So the session is being stored in our database Before we've even talked to GitHub, then what happens is we redirect to a specific GitHub URL with our auth URL, with our Public ID and then with the state query parameter as the session token. The reason why we do that is to prevent any sort of attacks here because we're sending a session token to GitHub to say, hey. This is the specific session we're trying to validate right now.

Guest 2

GitHub then comes back with that same session token as well as a code, an access code.

Guest 2

So that access code can then be used to then get what's called an access token.

Guest 2

So we get an access token from GitHub.

Guest 2

That access token is what actually allows us to be authenticated.

Guest 2

With that access token, you can get all of the user's information that they're able to or that we ask for from GitHub, such as their username, their photo, those types of things. So the way that the thing works is when we redirect GitHub, that's where you get the the user interface that allows you click accept. You click to accept. That sends back to the callback. In that callback, we use the code coming from GitHub to get the access token. We then use that access token to get all of the user information from GitHub that we need, Their username, blah blah blah. And then from there, we find or create the user. The user exists.

Guest 2

Load that user's information.

Guest 2

The user doesn't exist. Don't. Right? Or or create the user.

Guest 2

Then we find the session. We find the session that uses the session token that we created in the initial part. It's been sent to GitHub. It comes back to us. After we have that session, we're able to then update the session with the access token as well as the, the user that is being involved in this session. And then from there, we set the cookie this token to be an HTTP only secure cookie for the site.

Guest 2

That way, the cookie with the access token is never stored or Accessed or available on the client side, and that way we can validate that access token with a session. That session be can be connected to a specific user on the site, And that user is effectively logged in. Sounds simple.

Wes Bos

It well, we we have I'm just joking. We we did an entire Episode on that. If you go back to episode 5,599, OAuth APIs explained. But, yeah, there's quite a big dance of going back and forth and creating tokens. And Alright. I have my token. Here's the other one. Yeah. It's it's pretty wild. And if if you wanna get, like, a nonrambly version of this thing, I I actually wrote in the code

Guest 2

A step by step inside of our code that says, here's what we're doing. Pull the code from that. Use the code. Use the access token. Use the data. Create sessions, set the access token, redirect to home page. Done. Okay? So if you wanna follow step by step, I did write a a little step by step exactly what's going on. And that's one thing I've been trying to do as I go in this code because I I realized that if we are building in public and we're an educational podcast that perhaps people would like to read the code, and perhaps I'd like to read and learn from the code. So I've been reading a lot of helpful comments to specifically teach people what's going on while we're doing it in case you wanted to follow along. So either way, when we have that access token, you can use middleware to then look up the user from the session every single time. And on every request, eventually, we'll cache that in a better way, maybe in, like, a or something. Who knows? But either way, therefore, we're able to pass that user information along to Any user interface on the entire site, whether that be the header, whether that be, server side to prevent access to things, yada yada yada.

Topic 7 23:15

Wes explains transcription process

Wes Bos

It's on. Alright. Next 1 we have is, the transcription, which is essentially taking the m p 3 that we have and turning it into text.

Wes Bos

There's actually quite a bit that goes into it. And I think that this is going to be Extremely useful for the website, of course, because we can offer, like, a transcript if somebody wants to read it. But I don't know that that many people are going to sit there and read through an hour's worth of transcription. I think the real benefit is now that we have The transcription.

Wes Bos

We can do a lot of other things with that data in order to surface topics and bullet points and All kinds of really neat stuff. So the first thing in all of the stuff I've been doing is basically I need to get The MP 3 turned into text, right? Text to speech. I thought it can't be too hard. And I actually went down this rabbit hole a couple Years ago when I initially started working on transcription for the Syntax website.

Wes Bos

And at that time, I landed on a service called Otter AI.

Wes Bos

And that was you can upload audio, and at the other end, it will give you your transcription. You can download it however you However, they don't have an API. And it seems like since then, they've also I reverse engineered the API to make it work with the syntax website. But I really don't I'm not gonna I'm not gonna be fixing that on Monday night at 8 PM. You know? So and it also seems like that company is going Way more in the direction of add Otter dotai to your Zoom meetings, and we will listen and transcribe and Bullet point everything for you.

Wes Bos

And that's that's really not what Syntax is, the podcast. Right? So I'm not moving away from Otter dotai.

Wes Bos

I tried a bunch of different ones out there. I tried Amazon Transcribe, Quite a big player in the space. I didn't know because it does a lot of medical records, so they will listen to hours and hours of people interviewing doctors, talking to patients, things like that, and you can transcribe those and get data out of it.

Wes Bos

So that I tried that one. It's just working with the Amazon SDK was just such a brutal thing. Like it didn't allow you to pass it a buffer, which is You you want like, you read an MP 3 into memory.

Wes Bos

It's stored as a buffer. Right? Mhmm. And then you pass that buffer to an SDK. Alright. Here's my MP 3. I didn't allow you to do that. You had a and then you it didn't allow you to give it a URL. So you had to, like, pass it. You had to upload it to s 3 And then pass it only an S3 URL, right? Like it's saying, oh, I only am doing S3, which makes sense because they want it in the same systems, but It's just kind of inflexible, and it wasn't amazing at the end of the day. The next one I tried is Whisper.

Wes Bos

So Whisper is one that you can run both locally and on as it's part of OpenAI.

Wes Bos

So you can pass it. You can run it on your computer. That one worked pretty good as well. The downside to that is it doesn't do diatarization, which is it doesn't detect Who the speakers are. And that's a no go for us because we need to be able to say Scott is saying this at this point, right? They can't just give somebody At a 100 minutes of a paragraph dumped into the thing, you need to be able to say, alright, 6 minutes in, Scott said this thing.

Wes Bos

So there's another project called WhisperX, which uses Whisper as well as another And basically, that's a Python package from, I think, PyTorch that will actually detect who the speakers are.

Wes Bos

And that's pretty cool because it will say speaker 1, speaker 2. So I went down that rabbit hole for probably a whole day And I was so frustrated with trying to get Python running. I finally got it running. But every now and then I would get these such bizarre Python errors. And that's kind of the thing about this AI space is a lot of these tools are Python based, right? They're not JavaScript based.

Wes Bos

So I was like, you know what? This is not very good. And I kinda looked into it, and the guy building it is obviously very smart, but it's like a research project for his PhD or something like that. So like I was like, I don't really feel like using a Thomet's PhD project as our thing. I rather like a like a proper package. An established yeah. Yeah. You're you're building on shaky ground or Exactly. Yeah. Like this is it's it's more research than it is an actual product. So Otter dotai is out. Amazon's out. Whisper X and Whisper are out, and then I tried Google Cloud Transcribe.

Wes Bos

Same thing. Doesn't do diatritization.

Wes Bos

So I ended up, lot of people on Twitter are like, hey, check out Deepgram. So Deepgram is an API. You just send it your data.

Wes Bos

And It was very good, both because, like, I was able to get a transcription in like 3 minutes of being able to sign up and and have a demo. Their onboarding experience was fantastic.

Wes Bos

Their SDK is like TypeScript, but also has all the JS doc types and examples and, like, So good. Like, such a beautiful I have not had such a nice experience working with somebody's API in so long, and Deepgram did that. And then I also realized, like, it's cheap as hell. It's it's 0.4¢ per minute, Meaning that every single podcast, like an hour long podcast we do, is going to be, what, 15¢ or something like that? My gosh. Pretty unreal to build, and they give you $200 in credit. So I I did I think I did the entire syntax Transcript all on the free credit. And then I scrapped it, so I had to redo it. So I did end up paying for it. But it was I was just very happy with So Deepgram is definitely the winner there.

Wes Bos

However, there there's some downsides there. It does do diatirization, But it doesn't do what something that Otter dotai did, which is it doesn't re realize who Scott and me are.

Wes Bos

So in the past, Otter dotai would if you did a couple and you, like, marked alright. This is Scott saying this. This is Scott. This is me. If you did enough, it starts to learn.

Wes Bos

Okay. This voice is Scott, and this voice is Wes, and it it does a really good job at at doing that. However, Deepgram doesn't do that. And as far as I I cannot find any API that does that. I know Descript does it. I know Otter AI does it, but I want to be I want to use an API so we can automate this thing to finish. Right. I don't want to have to, like, tell somebody.

Wes Bos

All right, copy paste this export. You know, like, as soon as there's a human process Involved in this, it either gets missed or paste is wrong or, like, there's all kinds of issues that come in place. Right? Like, I want to have this stuff as automated as possible.

Wes Bos

So what I ended up doing is I wrote this, like, massive List array of things that Scott says, things that I say, and then things that, like, are I call them the growler, like, the the intro guy. The growler.

Wes Bos

That I guess that that's a radio word, the growler, like, oh, little grouper.

Wes Bos

And that worked pretty good, but I couldn't find Anything that I would consistently say that you didn't say. Mhmm. And it it wasn't a 100%, and I wasn't, like, really happy with that. So, Luckily, you at the end of every show, it says thanks for listening. Like the show and leave a review. So you said that at the end of every show so I could get you.

Wes Bos

And then I tried, okay, well, if Scott's there, then the other one is B, but then it wasn't working very well. So what I did is I said, hey, Scott, Can you record yourself saying,

Guest 2

what was it? Let me find it. Peter picked a pickle pepper. Like, who it was, like, some Statement. I it was I asked purple stinky cheese or something.

Wes Bos

Yeah. So I asked OpenAI Chat GVT. I said, what's the clearest sentence That a human can say for transcription. You know, like, what's the, like, bang on? This will always get transcribed perfectly.

Wes Bos

So what I came what I came up with was my name Please buy some And then I said, my dog eats And between those two things, What I use what I do is I take the syntax MP 3. I download it from the website.

Wes Bos

Then I use FFmpeg to Tack those 2 pieces of audio onto the end, and then I send it off to Deepgram As a buffer, that was really important. It was as a buffer. I don't have to, like, read files, save to file, read file. Right. It's all done in memory.

Wes Bos

And that worked Super well.

Wes Bos

All I had to do is 1 out of 500 episodes or 600 episodes.

Wes Bos

One of them got me wrong and I had to change my string to just a regex of on the moon. It just said the moon on one of them. So I just I did a regex where on was optional and it worked great. Now it can 100% detect Scott and me in every single episode And then anybody else that is not is labeled as a guest. I haven't figured out how to do that just yet, but I think we can do it with OpenAI because In the next stuff I'll talk about, it actually gives us a list of guests

Guest 2

pretty much perfect for everything. I was gonna say. So, you know, if if we have the guest stored in the database or in the markdown as who the guest is, And we know that a guest is talking. You could just do a string replace for guest with their name. Now I don't know if that's practical. I think that will cover

Wes Bos

90% of our other use cases, which is if there are 4 people talking on the podcast, the Growlr, Scott, me, And then somebody else. Obviously, somebody else is is going to be the guest. Right? Then when there's 2 guests, we don't have that very often, but then it pops up. Then it gets a little bit weird, and we can simply just fix that by putting the guest's name in order of which they talk.

Wes Bos

Or I've been feeding it through OpenAI, and it detects the guest's name perfectly. So we could also So just take the list the guest name in order that you feed it the transcription and then apply it based on that. So we'll figure that out, but it's not a big deal. This is wild. Yeah. We were we were talking about doing this kind of stuff 6 months ago. Yeah. It's it's crazy. So Now that we have the transcript, like, what do you do with that, right? Like, obviously, we have transcripts on the website being able to show what the person is saying. Then there are time stamps for every single word or utterance. This is really cool because the transcript will give us every single word we have ever said, The start and the finish of that word. Like, it gives you things called utterances, which is like a sentence. Or every time I take a break, This is a new utterance. Right? But then it will also give you every single word, which allow us to if we ever wanna, like, make one of those clips where you highlight the currently spoken word, You have that data being able to save. It's unreal how much data it gives you. One thing about Deepgram is that it like, you can give it things like Dino.

Wes Bos

Like it was it was spelling it d I n o. Sure. Yeah. So it has an option to pass it keywords.

Wes Bos

But then so I gave it Dino and a list of words that we commonly say. It was also calling you like Talinsky. It was calling it like some other weird Polish name, which was hilarious.

Wes Bos

And it calls me West Boss a lot. Mhmm.

Wes Bos

So I passed it. Scott Dalinski, West Boss, Dino.

Wes Bos

But then it starts replacing words that aren't Dino with Dino because it's like, oh, I might have thought this one was Dino. Let me replace it.

Wes Bos

So if it fixed where it spelled it d I n o, but then it also broke a whole bunch of other stuff. So That's not ideal just yet. There's some weird things. But I again, I've also found if you take the the Deepgram transcript And pass that into OpenAI and say fix this. It actually gives you a really good transcript, so we might do that. I don't know how to do that and keep the word markings, but it's, again, that's another fish to fry. I'm not gonna go that deep into it just yet. That's another fish to fry.

Guest 2

Talk about another fish to fry. Let's talk about this theming system, which is something that I've been working on. This thing is pretty neat. You know, theming systems are fun. A lot of times, people just opt for the the dark mode, light mode. But there's a number of challenges that go with on with a a theming system. 1, No. You don't want a flash of unthemed content, which, can happen because typically the way people are doing their their theme systems, if you read blog posts and stuff like that, they're just like, oh, just Hosted in local storage and then read from local storage and then set the theme. The problem with that is local storage is not available on the server side. The HTML gets Sent with the light theme or the dark theme, then reads it from the, the client side local storage. Bingo. Bango. You got a flash of unthemed content.

Guest 2

So the big deal is making sure that if a user has a theme set, that that theme set is available for the server. That means you Either needed in a cookie or in the database.

Guest 2

It's easy to store in the database. Makes sense to just put in the database.

Guest 2

I have a theme property that's just accepting a string on the database.

Guest 2

That's it. Right? So because the user information is available for server side rendering, that means the current theme that they want is also available for Server side rendering as well. The big problem is is that with many of these things like, like you have with your Body, for instance, in SvelteKit. The body is inside of an index dot HTML file, and you can't write to that body dynamically from server side code as you're compiling this stuff. There's no access to the DOM.

Guest 2

And likewise, If you wanted to do it, the data attribute route, which is another thing you often see people do. You often see people use data attributes To add a data attribute to the root element, and then you can override your variables based on the data attribute for root.

Guest 2

None of those things are available to us because that just does not work with, having that available for server side rendering.

Guest 2

So What I had to do was wrap the whole site in a div. So it goes body, then you have your theme wrapper. That theme wrapper contains everything.

Guest 2

If we're setting a background image or background color, it's not going to be on the body necessarily. It's going to be on the theme wrapper. That theme wrapper Has a minimum width of 100 VH so that it always takes up the entire viewport. Right? So because of that, what we do essentially is we have a theme wrapper that wraps the whole site, and it takes classes that are named Theme hyphen whatever the theme name is. Mhmm. That said, to create a theme, all you have to do is create a new CSS file inside of the themes folder.

Guest 2

It It'll automatically populate the UI that allows you to have a button to select the theme, and it will automatically bring in that CSS.

Guest 2

To do that, I'm using a post CSS globbing plug in to import every single CSS file inside of that. That said, that's going to That's going to increase the global CSS. So I'm thinking about doing it dynamically via JavaScript instead. So that's probably something I'll I'll work on today just so we're not loading CSS for All of the themes, if a user's only using 1 theme. Right? Might as well save some little space there. So we've solved flash of unthemed content.

Guest 2

We've solved server side rendering. We have themes automatically being submitted, which means that

Share

Play / pause the audio
Minimize / expand the player
Mute / unmute the audio
Seek backward 30 seconds
Seek forward 30 seconds
Increase playback rate
Decrease playback rate
Show / hide this window