<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mathew Addala</title>
    <description>The latest articles on DEV Community by Mathew Addala (@mathew777).</description>
    <link>https://dev.to/mathew777</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3954870%2F168f0adc-7e9f-49ac-be70-5473fbd91b1b.png</url>
      <title>DEV Community: Mathew Addala</title>
      <link>https://dev.to/mathew777</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mathew777"/>
    <language>en</language>
    <item>
      <title>STIKSHOT - A STICKMAN VIDEO RENDERER TOWARDS BEYOND</title>
      <dc:creator>Mathew Addala</dc:creator>
      <pubDate>Sun, 07 Jun 2026 13:21:42 +0000</pubDate>
      <link>https://dev.to/mathew777/stikshot-a-stickman-video-renderer-towards-beyond-2h5k</link>
      <guid>https://dev.to/mathew777/stikshot-a-stickman-video-renderer-towards-beyond-2h5k</guid>
      <description>&lt;p&gt;Build a 100% Client-Side AI Motion Capture Engine in the Browser&lt;br&gt;
Imagine uploading a dance video and having it instantly turned into a neon stickman animation—all without uploading a single megabyte to a server.&lt;/p&gt;

&lt;p&gt;That is stikshot, a local-first, serverless AI motion-capture web app. In this article, we'll dive into the architecture, the browser APIs we used, and the workarounds we engineered to make WebCodecs run stably on desktop and mobile.&lt;/p&gt;

&lt;p&gt;The Core Stack&lt;br&gt;
To keep stikshot completely serverless, static, and scale-free, we built the entire pipeline to run inside the user's browser sandbox:&lt;/p&gt;

&lt;p&gt;AI Engine: TensorFlow.js running the MoveNet Multipose model.&lt;br&gt;
Background Thread: Web Workers to keep the UI responsive.&lt;br&gt;
Compression: The browser's native WebCodecs API (VideoEncoder and AudioEncoder).&lt;br&gt;
Muxer: webm-muxer to compile the video/audio streams into a playable WebM file.&lt;br&gt;
 Architecture: Offscreen Pipelining&lt;br&gt;
To prevent the browser from lagging, we split the application into two parts: a Main Thread Coordinator and a Web Worker Processor.&lt;/p&gt;

&lt;p&gt;Mermaid diagram&lt;br&gt;
Code Highlights&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Seeking Background frames
To avoid tab-throttling when users switch tabs, we avoided requestVideoFrameCallback and fell back to standard seeked media event listeners combined with a safe timeout fallback:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;javascript&lt;/p&gt;

&lt;p&gt;function seekTo(video, time) {&lt;br&gt;
    return new Promise((resolve) =&amp;gt; {&lt;br&gt;
        const onSeeked = () =&amp;gt; {&lt;br&gt;
            video.removeEventListener('seeked', onSeeked);&lt;br&gt;
            clearTimeout(fallback);&lt;br&gt;
            resolve();&lt;br&gt;
        };&lt;br&gt;
        const fallback = setTimeout(() =&amp;gt; {&lt;br&gt;
            video.removeEventListener('seeked', onSeeked);&lt;br&gt;
            resolve();&lt;br&gt;
        }, 500); // 500ms timeout safety net&lt;br&gt;
        video.addEventListener('seeked', onSeeked);&lt;br&gt;
        video.currentTime = time;&lt;br&gt;
    });&lt;br&gt;
}&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Safeguarding iOS Safari WebCodecs Crashes
During development, we encountered a severe bug: Safari would crash/freeze when trying to write encoded video chunks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We discovered that Safari freezes the browser-provided metadata objects inside the VideoEncoder output callback. Modifying or passing them directly to the muxer throws a quiet error. We solved this by copying properties to an unfrozen, clean object:&lt;/p&gt;

&lt;p&gt;javascript&lt;/p&gt;

&lt;p&gt;const videoEncoder = new VideoEncoder({&lt;br&gt;
    output: (chunk, meta) =&amp;gt; {&lt;br&gt;
        let cleanMeta = undefined;&lt;br&gt;
        if (meta) {&lt;br&gt;
            cleanMeta = {};&lt;br&gt;
            // Copy properties to bypass read-only/frozen constraints in Safari&lt;br&gt;
            if (meta.decoderConfig !== null &amp;amp;&amp;amp; meta.decoderConfig !== undefined) {&lt;br&gt;
                cleanMeta.decoderConfig = meta.decoderConfig;&lt;br&gt;
            }&lt;br&gt;
            if (meta.svc !== undefined) cleanMeta.svc = meta.svc;&lt;br&gt;
            if (meta.alphaSideData !== undefined) cleanMeta.alphaSideData = meta.alphaSideData;&lt;br&gt;
        }&lt;br&gt;
        state.muxer.addVideoChunk(chunk, cleanMeta);&lt;br&gt;
    },&lt;br&gt;
    error: (err) =&amp;gt; console.error('Encoder error:', err)&lt;br&gt;
});&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Avoiding Android Audio Hacks
Android Chrome sometimes hangs indefinitely inside decodeAudioData on corrupted tracks. We implemented a promise-wrapped audio decoder with an 8-second safety timeout:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;javascript&lt;/p&gt;

&lt;p&gt;function decodeAudioWithTimeout(buffer, sampleRate = 48000, timeoutMs = 8000) {&lt;br&gt;
    const decodeCtx = new OfflineAudioContext(1, 1, sampleRate);&lt;br&gt;
    return new Promise((resolve) =&amp;gt; {&lt;br&gt;
        let completed = false;&lt;br&gt;
        const timer = setTimeout(() =&amp;gt; {&lt;br&gt;
            if (!completed) {&lt;br&gt;
                completed = true;&lt;br&gt;
                console.warn('Audio decoding timed out');&lt;br&gt;
                resolve(null);&lt;br&gt;
            }&lt;br&gt;
        }, timeoutMs);&lt;br&gt;
        decodeCtx.decodeAudioData(buffer, &lt;br&gt;
            (decoded) =&amp;gt; {&lt;br&gt;
                if (!completed) { completed = true; clearTimeout(timer); resolve(decoded); }&lt;br&gt;
            },&lt;br&gt;
            (err) =&amp;gt; {&lt;br&gt;
                if (!completed) { completed = true; clearTimeout(timer); resolve(null); }&lt;br&gt;
            }&lt;br&gt;
        );&lt;br&gt;
    });&lt;br&gt;
}&lt;br&gt;
 What’s Next: Beyond the Stickman&lt;br&gt;
stikshot is built to be serverless, meaning we don't pay for GPU rendering. However, generating 2D stickman animations is just step one.&lt;/p&gt;

&lt;p&gt;We are looking to expand this local-first pipeline to support:&lt;/p&gt;

&lt;p&gt;3D Skeletal Rigging: Converting joint coordinates to .gltf / .fbx formats.&lt;br&gt;
Game Engine Exports: Allowing creators to export motion capture data directly to Unity or Unreal Engine.&lt;br&gt;
VTuber Overlays: Creating browser-based camera inputs for real-time virtual avatar tracking.&lt;br&gt;
 Let's Collaborate!&lt;br&gt;
If you are interested in local-first AI, WebAssembly, WebGL shaders, or browser motion tracking, check out the live app, leave a star, and get in touch:&lt;/p&gt;

&lt;p&gt;App: stikshot.com&lt;br&gt;
Email: &lt;a href="mailto:contact@stikshot.com"&gt;contact@stikshot.com&lt;/a&gt;&lt;br&gt;
Instagram: @stikshotu&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>design</category>
      <category>tensorflow</category>
    </item>
    <item>
      <title>I built 39 free browser-based dev tools — here's every decision I made and why</title>
      <dc:creator>Mathew Addala</dc:creator>
      <pubDate>Wed, 27 May 2026 19:40:43 +0000</pubDate>
      <link>https://dev.to/mathew777/i-built-39-free-browser-based-dev-tools-heres-every-decision-i-made-and-why-51o3</link>
      <guid>https://dev.to/mathew777/i-built-39-free-browser-based-dev-tools-heres-every-decision-i-made-and-why-51o3</guid>
      <description>&lt;p&gt;I got tired of the same thing happening every day.&lt;/p&gt;

&lt;p&gt;Google "json formatter online." Land on a site from 2011. Click format. Get an ad popup. Format the JSON. Close the tab. Repeat tomorrow.&lt;/p&gt;

&lt;p&gt;So I built BuiltItDev — 39 developer tools that run entirely in your browser. No accounts. No paywalls. No data leaving your machine.&lt;/p&gt;

&lt;p&gt;Why client-side only?&lt;br&gt;
You're pasting API keys, JWT tokens, internal JSON — that data shouldn't hit someone's backend.&lt;/p&gt;

&lt;p&gt;Everything processes locally. Hash generation uses the Web Crypto API. JWT decoding splits and base64-decodes in the browser. No network calls. Nothing logged.&lt;/p&gt;

&lt;p&gt;Stack&lt;br&gt;
Next.js 16 App Router + TypeScript. 49 static routes, fully pre-rendered. Each tool is its own route (/tools/json-formatter, /tools/base64) so every page can rank independently on Google.&lt;/p&gt;

&lt;p&gt;Tools so far&lt;br&gt;
Category    Examples&lt;br&gt;
Encoding    Base64, URL encoder, HTML entity encoder&lt;br&gt;
Formatting  JSON formatter, Markdown previewer, XML formatter&lt;br&gt;
Generators  UUID, Lorem ipsum, Hash (MD5/SHA family)&lt;br&gt;
Converters  Color (HEX/RGB/HSL), Timestamp, Number base&lt;br&gt;
Dev utils   Regex tester, JWT decoder, Cron parser, Diff checker&lt;br&gt;
39 total. More shipping based on requests.&lt;/p&gt;

&lt;p&gt;What I want from you&lt;br&gt;
What tool do you write as a throwaway script every few months because no clean browser version exists? Drop it in the comments — I'll build it.&lt;/p&gt;

&lt;p&gt;→ builtitdev.com&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
