<?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: Hendra Hendriana</title>
    <description>The latest articles on DEV Community by Hendra Hendriana (@hendrahend).</description>
    <link>https://dev.to/hendrahend</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%2F1191591%2Feb911702-239b-4c1d-83aa-a220d465a248.jpeg</url>
      <title>DEV Community: Hendra Hendriana</title>
      <link>https://dev.to/hendrahend</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hendrahend"/>
    <language>en</language>
    <item>
      <title>Kicau: an Indonesian bird-call identifier that works offline</title>
      <dc:creator>Hendra Hendriana</dc:creator>
      <pubDate>Sun, 11 Oct 2026 15:32:43 +0000</pubDate>
      <link>https://dev.to/hendrahend/kicau-an-indonesian-bird-call-identifier-that-works-offline-2ica</link>
      <guid>https://dev.to/hendrahend/kicau-an-indonesian-bird-call-identifier-that-works-offline-2ica</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The birds outside my window have Indonesian names — but every bird-identifying app I tried only knew the English ones. Six apps, and not one could tell me what the bird out there is called in the language I actually speak.&lt;/p&gt;

&lt;p&gt;So I built Kicau: an offline bird-call identifier that speaks Indonesian.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Kicau&lt;/strong&gt; records bird audio — from your microphone or an uploaded file — and identifies the species, on-device, in English or Indonesian. No internet, no server, no account. It works in the middle of a national park with zero bars of signal, and your recordings never leave your device. An EN/ID toggle in the corner switches the whole UI &lt;em&gt;and&lt;/em&gt; the species names — &lt;em&gt;Orthotomus sutorius&lt;/em&gt; reads "Common Tailorbird" or "Cinenen pisang" depending on the toggle.&lt;/p&gt;

&lt;p&gt;It's for Indonesian birders, hikers, and anyone who's ever heard a bird on a trail and wondered what it was. The screen is the shortest part of the experience: record ten seconds, read the result, pocket the phone, go find the bird. Tap "Use my location" and it also weighs which birds actually live near you.&lt;/p&gt;

&lt;p&gt;Yes — there are other bird identifiers in this challenge. Kicau is the one built for Indonesia's 280 million people: Bahasa Indonesia UI, Indonesian species names ("Cikrak bambu", not just &lt;em&gt;Abroscopus superciliaris&lt;/em&gt;), two pip packages, one HTML file, zero build step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Kicau is offline-first, so there's no hosted demo — that would defeat the point. It runs on your machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/hendrahend/kicau &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;kicau
python &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python scripts/download_model.py   &lt;span class="c"&gt;# one-time, ~53 MB&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; kicau.server             &lt;span class="c"&gt;# open http://127.0.0.1:8765&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhlctawhfjrx7ax7hkstk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhlctawhfjrx7ax7hkstk.png" alt="Kicau main UI — record and upload tabs" width="480" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Common Tailorbird field recording, identified on-device:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fhendrahend%2Fkicau%2Fmain%2Fdocs%2Fdemo-result.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fhendrahend%2Fkicau%2Fmain%2Fdocs%2Fdemo-result.png" alt="Kicau result — species cards with confidence bars and the per-3-second detection timeline" width="480" height="1310"&gt;&lt;/a&gt;&lt;br&gt;
Or from the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; kicau.identify recording.mp3 &lt;span class="nt"&gt;--top-n&lt;/span&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/hendrahend/kicau" rel="noopener noreferrer"&gt;https://github.com/hendrahend/kicau&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MIT licensed. What's inside:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kicau/identify.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Model loading, chunking, inference, Indonesian labels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kicau/audio.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ffmpeg-based decode/resample to 48 kHz mono&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kicau/server.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;stdlib-only HTTP server + &lt;code&gt;/api/identify&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kicau/labels_id.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6,522 species labels in Indonesian (BirdNET team)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;web/index.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Single-file offline UI — record, upload, timeline, playback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tests/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pipeline tests, including a real-audio classification test&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The whole experience is built around one open-weight model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;BirdNET v2.4&lt;/strong&gt; (Cornell Lab of Ornithology / TU Chemnitz)&lt;/td&gt;
&lt;td&gt;6,522-species bioacoustics classifier; I use the fp16 TFLite variant (~26 MB)&lt;/td&gt;
&lt;td&gt;CC BY-NC 4.0 (weights)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;LiteRT&lt;/strong&gt; (&lt;code&gt;ai-edge-litert&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;On-device inference runtime — no TensorFlow install, no GPU&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;BirdNET's Indonesian labels&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Species names in Bahasa Indonesia, shipped by the BirdNET team&lt;/td&gt;
&lt;td&gt;MIT (analyzer repo)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One honest caveat on the Indonesian names: the BirdNET team's Indonesian label set covers 1,227 of the 6,522 species so far — the rest fall back to English while the translation grows. The covered ones include the birds you're most likely to meet in Indonesia (Cinenen, Cikrak, Elang-alap).&lt;/p&gt;

&lt;p&gt;Pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mic / upload → ffmpeg (→ 48 kHz mono) → 3-second chunks →
BirdNET v2.4 TFLite (LiteRT, on-device) → flat sigmoid →
top species per chunk, Indonesian names
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I verified the math against BirdNET-Analyzer's source line by line — chunk length, sample rate, sigmoid sensitivity — so results match the reference implementation. Then I ran BirdNET's own reference soundscape through it: Black-capped Chickadee 0.92, Dark-eyed Junco 0.88, House Finch 0.83. And on an openly-licensed field recording of a Common Tailorbird (Vis M via iNaturalist, CC BY-SA 4.0, Wikimedia Commons): &lt;strong&gt;"Common Tailorbird (&lt;em&gt;Orthotomus sutorius&lt;/em&gt;)" at 1.00 confidence&lt;/strong&gt; — correct species. (Flip the app's EN/ID toggle and it reads "Cinenen pisang" — species names switch languages too.)&lt;/p&gt;

&lt;p&gt;One honest miss, because that's part of the deal: on a noisy caged-bird training clip, confidence stayed low (0.06–0.21) and the top guess was wrong. Clean field recordings are this model's home turf; noisy clips aren't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Location-aware, too.&lt;/strong&gt; BirdNET ships a second tiny model that takes your latitude, longitude, and the week of the year, and returns how likely each species is there right now. Tap "Use my location" and Kicau multiplies the acoustic confidence by that local likelihood — a bird that merely sounds similar but doesn't live here gets demoted. I verified it: in Jakarta in October the top picks are Burung-gereja erasia (Eurasian Tree Sparrow) and Perkutut jawa (Zebra Dove) — exactly the birds outside my window — while Berlin returns Great Tit and Eurasian Blackbird.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No signal, no problem.&lt;/strong&gt; The entire point is identifying birds &lt;em&gt;outside&lt;/em&gt;. A cloud API is useless in a national park. A local open-weight model is the only architecture that works where the birds actually are.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your recordings stay yours.&lt;/strong&gt; Audio is decoded, chunked, classified, and deleted — on your machine. There is nowhere to upload it to, because there is no server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs nothing, forever.&lt;/strong&gt; No per-request pricing, no API key to babysit. A school birding club can run it on one laptop for years.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could actually verify it.&lt;/strong&gt; I checked my preprocessing against the reference implementation line by line and tested on known audio. Try getting that level of verification from a black-box API.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One honest license note: the BirdNET &lt;em&gt;weights&lt;/em&gt; are CC BY-NC 4.0 (free for research, education, and personal use) while the analyzer code is MIT and my code is MIT. Open weights with a non-commercial term — worth knowing, and fine for this project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of GitHub Copilot&lt;/strong&gt;: the repo ships a GitHub Actions CI workflow that installs dependencies, downloads the BirdNET weights, and runs the full pytest suite — including a real-audio classification test — on every push.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built for Hacktoberfest 2026. Then go outside. That's the whole point.&lt;/em&gt; 🌿&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
