<?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: Mohit Dubey</title>
    <description>The latest articles on DEV Community by Mohit Dubey (@mohit_dubey_5ac5787d1280a).</description>
    <link>https://dev.to/mohit_dubey_5ac5787d1280a</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3476800%2F01f0cb13-f412-40a6-9f27-d7511fb09fd1.png</url>
      <title>DEV Community: Mohit Dubey</title>
      <link>https://dev.to/mohit_dubey_5ac5787d1280a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mohit_dubey_5ac5787d1280a"/>
    <language>en</language>
    <item>
      <title>MoQ Support Is Now Available in Ant Media Server</title>
      <dc:creator>Mohit Dubey</dc:creator>
      <pubDate>Wed, 29 Apr 2026 10:36:31 +0000</pubDate>
      <link>https://dev.to/mohit_dubey_5ac5787d1280a/moq-support-is-now-available-in-ant-media-server-1bf6</link>
      <guid>https://dev.to/mohit_dubey_5ac5787d1280a/moq-support-is-now-available-in-ant-media-server-1bf6</guid>
      <description>&lt;p&gt;We're excited to announce that &lt;strong&gt;MoQ (Media over QUIC) support is now available in Ant Media Server&lt;/strong&gt; via a new plugin. MoQ is one of the most interesting developments in live streaming right now, and we wanted to ship early access so you can start experimenting with it alongside us.&lt;/p&gt;

&lt;p&gt;In this post, we'll walk through what the AMS MoQ plugin offers, how it works under the hood, and everything you need to get started.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Heads up:&lt;/strong&gt; MoQ is still an evolving protocol. The IETF standard is actively being developed, and the current plugin is based on &lt;strong&gt;moq-lite&lt;/strong&gt; — a pragmatic, deployable subset of the full spec. We're continuously monitoring progress and will ship updates as it matures.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What Is Media over QUIC (MoQ)?
&lt;/h2&gt;

&lt;p&gt;Media over QUIC is an emerging live media protocol built on &lt;strong&gt;QUIC&lt;/strong&gt; and &lt;strong&gt;WebTransport&lt;/strong&gt;. It's being standardized by the IETF working group, with backing from Google, Cisco, Akamai, Cloudflare, and others — which gives a strong signal of where the industry is heading.&lt;/p&gt;

&lt;p&gt;At its core, MoQ is built on QUIC: a modern transport protocol that handles multiple streams of data independently over a single connection. This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No head-of-line blocking&lt;/strong&gt; — one dropped packet doesn't stall other streams&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in multiplexing&lt;/strong&gt; — audio, video, and metadata travel independently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native browser support&lt;/strong&gt; via WebTransport — no plugins, no peer connections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a deeper technical comparison, check out our article &lt;a href="https://antmedia.io/webrtc-vs-moq-media-over-quic-ant-media-server/" rel="noopener noreferrer"&gt;WebRTC vs. MoQ — Two Protocols, One Platform&lt;/a&gt;. In this post, we focus on the practical: what the plugin does and how to use it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the AMS MoQ Plugin Does
&lt;/h2&gt;

&lt;p&gt;The AMS MoQ plugin adds &lt;strong&gt;bidirectional MoQ support&lt;/strong&gt; to any Ant Media Server deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live streams published to AMS are &lt;strong&gt;automatically broadcast as MoQ tracks&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Browser clients connect via &lt;strong&gt;WebTransport&lt;/strong&gt; and receive video with &lt;strong&gt;sub-second latency&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;No plugins, no WebRTC peer connections, and no SFU infrastructure required on the playback side&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each quality level is exposed as a separate named track. For example, a stream with ID &lt;code&gt;myStream&lt;/code&gt; would surface its source quality at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;moq://your-ams-server:4443/myStream/source
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before opening the MoQ player pages, make sure the following are in place:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTPS is required on real servers.&lt;/strong&gt; MoQ uses WebTransport, and browsers only allow it over HTTPS. If your server has a real domain or IP address, it needs a valid SSL certificate. &lt;code&gt;localhost&lt;/code&gt; is the one exception browsers allow without SSL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Port 4443 must be open.&lt;/strong&gt; The embedded MoQ relay listens on UDP/TCP port 4443. If your server is behind a firewall, open that port to inbound traffic or the browser won't be able to reach the relay.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Once a stream is live on AMS, viewers can connect via the built-in MoQ player or any moq-compatible client.&lt;/p&gt;

&lt;h3&gt;
  
  
  Publishing a Stream
&lt;/h3&gt;

&lt;p&gt;Publish a stream to Ant Media Server the same way you always would — via WebRTC, RTMP, SRT, or WHIP. The MoQ plugin picks it up automatically and broadcasts it as a MoQ relay.&lt;/p&gt;

&lt;h3&gt;
  
  
  Watching via the MoQ Player
&lt;/h3&gt;

&lt;p&gt;Open the standalone MoQ player page (served by AMS) and enter your stream's MoQ URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;moq://your-ams-server:4443/streamId/source
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The player connects via WebTransport, decodes video using &lt;strong&gt;WebCodecs&lt;/strong&gt;, and renders it with sub-second latency — all natively in the browser, no extensions required.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📝 &lt;strong&gt;Note:&lt;/strong&gt; The standalone MoQ player pages are temporary. MoQ playback and publishing will be built directly into the main Ant Media Server web player in a future release.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  MoQ vs. WebRTC: Not a Replacement
&lt;/h2&gt;

&lt;p&gt;It's worth being clear: &lt;strong&gt;MoQ is not a replacement for WebRTC&lt;/strong&gt; — at least not today.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;WebRTC&lt;/th&gt;
&lt;th&gt;MoQ (moq-lite)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Latency&lt;/td&gt;
&lt;td&gt;~0.5s&lt;/td&gt;
&lt;td&gt;Sub-second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser support&lt;/td&gt;
&lt;td&gt;Universal&lt;/td&gt;
&lt;td&gt;Partial (WebTransport required)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fan-out model&lt;/td&gt;
&lt;td&gt;SFU-based&lt;/td&gt;
&lt;td&gt;Relay/CDN-native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spec maturity&lt;/td&gt;
&lt;td&gt;Production-ready&lt;/td&gt;
&lt;td&gt;Evolving (IETF WG)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Interactive, bidirectional&lt;/td&gt;
&lt;td&gt;Large-scale, one-to-many&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;WebRTC is the right answer for telehealth, live auctions, drone monitoring, and anything that requires interactive, bidirectional communication. MoQ is compelling for massive concurrent audiences and CDN-native delivery — once cross-browser support closes.&lt;/p&gt;

&lt;p&gt;At Ant Media, our strategy is simple: the future of streaming is &lt;strong&gt;multi-protocol capability in one platform&lt;/strong&gt;, so your infrastructure can adapt without rewriting your application.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The AMS MoQ plugin is an early but functional step toward next-generation live streaming infrastructure. By building on moq-lite today, you get a hands-on way to explore what MoQ brings to the table:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sub-second latency&lt;/li&gt;
&lt;li&gt;CDN-scale fan-out&lt;/li&gt;
&lt;li&gt;A modern browser stack built on WebTransport and WebCodecs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll keep shipping updates as moq-lite evolves and as the IETF spec progresses.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;Read more about &lt;a href="https://antmedia.io/moq-support-now-available-in-ant-media-server/" rel="noopener noreferrer"&gt;MoQ implementation on Ant Media Server&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're experimenting with the MoQ plugin or building something on top of it, we'd love to hear about it. Join us on the &lt;a href="https://community.antmedia.io" rel="noopener noreferrer"&gt;Ant Media Community Forum&lt;/a&gt; or reach out directly.&lt;/p&gt;

&lt;p&gt;And if you want to dive deeper into the protocol comparison, read: &lt;a href="https://antmedia.io/webrtc-vs-moq-media-over-quic-ant-media-server/" rel="noopener noreferrer"&gt;WebRTC vs. MoQ — Two Protocols, One Platform Completely Built for Both&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy streaming! 🎥&lt;/p&gt;

</description>
      <category>streaming</category>
      <category>webrtc</category>
      <category>quic</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I Added Real-Time AR Filters and Custom Overlays to a Live Android Stream 🎭📱</title>
      <dc:creator>Mohit Dubey</dc:creator>
      <pubDate>Wed, 01 Apr 2026 10:59:06 +0000</pubDate>
      <link>https://dev.to/mohit_dubey_5ac5787d1280a/how-i-added-real-time-ar-filters-and-custom-overlays-to-a-live-android-stream-3goc</link>
      <guid>https://dev.to/mohit_dubey_5ac5787d1280a/how-i-added-real-time-ar-filters-and-custom-overlays-to-a-live-android-stream-3goc</guid>
      <description>&lt;p&gt;Live streaming is everywhere. But just streaming a plain camera feed feels boring in 2026. Viewers expect filters, effects, branding — the kind of stuff you see on TikTok and Instagram Live.&lt;/p&gt;

&lt;p&gt;In this post I'll show you how to build exactly that: an Android app that applies &lt;strong&gt;real-time DeepAR AR filters&lt;/strong&gt; (think viking helmets, neon devil horns, cat ears) and &lt;strong&gt;custom canvas overlays&lt;/strong&gt; (your logo, watermark, live badge) — and streams the whole thing live via &lt;strong&gt;Ant Media Server&lt;/strong&gt; over WebRTC with ~0.5s latency.&lt;/p&gt;

&lt;p&gt;The full sample project is on GitHub → &lt;a href="https://github.com/USAMAWIZARD/AntMedia-DeepAR-And-Overlay" rel="noopener noreferrer"&gt;AntMedia-DeepAR-And-Overlay&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What you'll build
&lt;/h2&gt;

&lt;p&gt;Two Activities, both streaming live:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DeepARActivity&lt;/strong&gt; — real-time AR face filters powered by DeepAR SDK&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CustomCanvasActivity&lt;/strong&gt; — custom bitmap/text overlays drawn with Android Canvas&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you start, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android Studio (Hedgehog or newer)&lt;/li&gt;
&lt;li&gt;A physical Android device (API 21+) — emulators don't do face tracking justice&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://developer.deepar.ai" rel="noopener noreferrer"&gt;DeepAR account&lt;/a&gt; and license key (free tier available)&lt;/li&gt;
&lt;li&gt;Git installed — Android Studio does &lt;strong&gt;not&lt;/strong&gt; include Git, install it separately from &lt;a href="https://git-scm.com/download/win" rel="noopener noreferrer"&gt;git-scm.com&lt;/a&gt; first&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1 — Clone the project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/USAMAWIZARD/AntMedia-DeepAR-And-Overlay.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open Android Studio → &lt;strong&gt;File → Open&lt;/strong&gt; → select the cloned folder. Wait for Gradle sync to finish.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Good news:&lt;/strong&gt; The repo already has &lt;code&gt;settings.gradle&lt;/code&gt;, &lt;code&gt;build.gradle&lt;/code&gt;, and the &lt;code&gt;assets&lt;/code&gt; folder pre-configured. You don't need to add dependencies manually — they're already there.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 2 — Get your DeepAR license key
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://developer.deepar.ai" rel="noopener noreferrer"&gt;developer.deepar.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a new project → Add Android App&lt;/li&gt;
&lt;li&gt;Enter your exact package name: &lt;code&gt;com.example.antmediacustomcanvasstreaming&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Copy the generated license key&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Open &lt;code&gt;res/values/strings.xml&lt;/code&gt; and paste it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;resources&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"app_name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;AntMediaDeepAR&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"deepar_license_key"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;YOUR_LICENSE_KEY_HERE&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/resources&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;The license key is tied to your exact package name.&lt;/strong&gt; If the app crashes on launch, this is almost certainly why — double-check the package name matches exactly.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 3 — Add the DeepAR effect files
&lt;/h2&gt;

&lt;p&gt;Here's a gotcha that isn't obvious from the code: &lt;code&gt;DeepARActivity&lt;/code&gt; references &lt;strong&gt;17 specific effect files&lt;/strong&gt; by name. If any of them are missing from your &lt;code&gt;assets&lt;/code&gt; folder, the app crashes with no clear error message.&lt;/p&gt;

&lt;p&gt;Go to &lt;a href="https://developer.deepar.ai/downloads" rel="noopener noreferrer"&gt;developer.deepar.ai/downloads&lt;/a&gt; and download the &lt;strong&gt;DeepAR Filter Pack (Legacy)&lt;/strong&gt; — this zip contains all the effects the code needs. Unzip it and copy the &lt;code&gt;.deepar&lt;/code&gt; files into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/src/main/assets/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code expects these files specifically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;viking_helmet.deepar
MakeupLook.deepar
Emotions_Exaggerator.deepar
Neon_Devil_Horns.deepar
Elephant_Trunk.deepar
flower_face.deepar
Humanoid.deepar
... (and more)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;✅ Don't just download a couple — copy everything from the zip.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 4 — How the DeepAR integration works
&lt;/h2&gt;

&lt;p&gt;This is the interesting part. The key to making DeepAR and Ant Media work together is one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setVideoSource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IWebRTCClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;StreamSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CUSTOM&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default &lt;code&gt;IWebRTCClient&lt;/code&gt; opens the camera itself. Setting &lt;code&gt;CUSTOM&lt;/code&gt; tells it: &lt;em&gt;"I'll push frames to you manually."&lt;/em&gt; That's what lets you insert DeepAR (or Canvas drawing) between the camera and the WebRTC encoder.&lt;/p&gt;

&lt;p&gt;Here's the flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CameraX → feedDeepAR() → DeepARRenderer (GLSurfaceView) → IWebRTCClient → Ant Media Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;IWebRTCClient&lt;/code&gt; is set up like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;webRTCClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IWebRTCClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setServerUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"wss://test.antmedia.io/LiveApp/websocket"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setActivity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setVideoSource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IWebRTCClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;StreamSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CUSTOM&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setWebRTCListener&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;createWebRTCListener&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInitiateBeforeStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CameraX feeds each frame into DeepAR via &lt;code&gt;receiveFrame()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;deepAR&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;receiveFrame&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;buffers&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;currentBuffer&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getImageInfo&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getRotationDegrees&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;lensFacing&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;CameraSelector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LENS_FACING_FRONT&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// mirror for selfie&lt;/span&gt;
    &lt;span class="nc"&gt;DeepARImageFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;YUV_420_888&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;uPixelStride&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DeepAR processes the frame (applies the AR effect using GPU), then &lt;code&gt;DeepARRenderer&lt;/code&gt; pushes the result to the WebRTC client.&lt;/p&gt;

&lt;p&gt;Switching effects mid-stream is one line and doesn't interrupt the broadcast at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;deepAR&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;switchEffect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"effect"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"file:///android_asset/viking_helmet.deepar"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5 — Custom Canvas overlays
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;CustomCanvasActivity&lt;/code&gt; takes a different approach — no DeepAR needed. It grabs each camera frame as a &lt;code&gt;Bitmap&lt;/code&gt; and paints your graphics on top using Android's &lt;code&gt;Canvas&lt;/code&gt; API before pushing to &lt;code&gt;IWebRTCClient&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Bitmap&lt;/span&gt; &lt;span class="nf"&gt;addOverlay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bitmap&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Bitmap&lt;/span&gt; &lt;span class="n"&gt;mutable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bitmap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ARGB_8888&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;Canvas&lt;/span&gt; &lt;span class="n"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Canvas&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mutable&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Logo — bottom-right corner&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;lx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mutable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWidth&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;overlayBitmap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWidth&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mutable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHeight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;overlayBitmap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHeight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;drawBitmap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;overlayBitmap&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ly&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Text watermark — top-left with drop shadow&lt;/span&gt;
    &lt;span class="nc"&gt;Paint&lt;/span&gt; &lt;span class="n"&gt;paint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Paint&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;paint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setColor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WHITE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;paint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTextSize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;paint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAntiAlias&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;paint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setShadowLayer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BLACK&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;drawText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@YourBrand"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paint&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mutable&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same &lt;code&gt;StreamSource.CUSTOM&lt;/code&gt; pattern applies — same builder, same &lt;code&gt;sendFrameForProcessing()&lt;/code&gt; call.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 — Run it
&lt;/h2&gt;

&lt;p&gt;Connect your Android phone via USB, enable USB Debugging, and hit ▶ Run in Android Studio.&lt;/p&gt;

&lt;p&gt;Grant camera and microphone permissions when prompted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The repo already points to Ant Media's public test server&lt;/strong&gt; — you don't need your own server to test this. Just tap &lt;strong&gt;Start&lt;/strong&gt; in the app, then open this URL in your browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://test.antmedia.io/LiveApp/player.html?id=test1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see your AR-filtered live stream playing in the browser within a second. 🎉&lt;/p&gt;

&lt;p&gt;When you're ready to use your own server, just swap this line in &lt;code&gt;setupStreamingAndPreview()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setServerUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"wss://YOUR-SERVER/LiveApp/websocket"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Things that tripped me up (so they don't trip you up)
&lt;/h2&gt;

&lt;p&gt;After going through this end-to-end, here's what I wish I'd known:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Install Git before you do anything else.&lt;/strong&gt;&lt;br&gt;
Android Studio doesn't come with Git. If you run &lt;code&gt;git clone&lt;/code&gt; and get &lt;code&gt;'git' is not recognized&lt;/code&gt;, go install it from git-scm.com first, then reopen your terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The Filter Pack zip is not obvious.&lt;/strong&gt;&lt;br&gt;
The downloads page shows "DeepAR Android SDK" which is the SDK itself. The effect files are in a separate "Filter Pack (Legacy)" download. Easy to miss, causes a silent crash.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Missing effect files = instant crash, no clear error.&lt;/strong&gt;&lt;br&gt;
The crash log shows an EGL surface error which looks completely unrelated to missing files. If your DeepAR activity crashes immediately, check your assets folder first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The test server is genuinely useful.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;wss://test.antmedia.io&lt;/code&gt; is Ant Media's public test server — it's real, it works, and it means you can verify your stream end-to-end without any server setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Use a physical device for DeepAR.&lt;/strong&gt;&lt;br&gt;
Emulator cameras are simulated and face tracking won't work meaningfully. The custom canvas overlay works fine on emulators though.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to build next
&lt;/h2&gt;

&lt;p&gt;Once you have this running, some natural next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Filter picker UI&lt;/strong&gt; — a horizontal RecyclerView that calls &lt;code&gt;deepAR.switchEffect()&lt;/code&gt; on tap&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local recording&lt;/strong&gt; — &lt;code&gt;deepAR.startVideoRecording()&lt;/code&gt; saves an AR copy to the gallery simultaneously while streaming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom effects&lt;/strong&gt; — build your own branded AR filter in &lt;a href="https://www.deepar.ai/creator-studio" rel="noopener noreferrer"&gt;DeepAR Creator Studio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your own server&lt;/strong&gt; — sign up for &lt;a href="https://antmedia.io" rel="noopener noreferrer"&gt;Ant Media's free 14-day trial&lt;/a&gt; to get a cloud server with your own stream URLs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📦 Sample repo: &lt;a href="https://github.com/USAMAWIZARD/AntMedia-DeepAR-And-Overlay" rel="noopener noreferrer"&gt;github.com/USAMAWIZARD/AntMedia-DeepAR-And-Overlay&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📖 Full tutorial: &lt;a href="https://antmedia.io/deepar-and-custom-overlay-with-ant-media-android-sdk/" rel="noopener noreferrer"&gt;antmedia.io/deepar-and-custom-overlay-with-ant-media-android-sdk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔑 DeepAR developer portal: &lt;a href="https://developer.deepar.ai" rel="noopener noreferrer"&gt;developer.deepar.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🖥️ Ant Media docs: &lt;a href="https://antmedia.io/docs" rel="noopener noreferrer"&gt;antmedia.io/docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Have questions or hit a different error? Drop it in the comments — happy to help. 👇&lt;/p&gt;

</description>
      <category>android</category>
      <category>webrtc</category>
      <category>antmediaserver</category>
    </item>
    <item>
      <title>WebRTC Browser Support &amp; Compatibility</title>
      <dc:creator>Mohit Dubey</dc:creator>
      <pubDate>Wed, 01 Oct 2025 10:56:20 +0000</pubDate>
      <link>https://dev.to/mohit_dubey_5ac5787d1280a/webrtc-browser-support-compatibility-5co</link>
      <guid>https://dev.to/mohit_dubey_5ac5787d1280a/webrtc-browser-support-compatibility-5co</guid>
      <description>&lt;p&gt;&lt;strong&gt;WebRTC (Web Real-Time Communication) is a set of open-source standards, APIs, and protocols developed by the IETF and W3C to enable real-time communication directly inside browsers and applications.&lt;/strong&gt; Its significance lies in allowing seamless video, audio, and data transfer without requiring external plugins, legacy technologies (such as Flash), or additional installations. Learn &lt;a href="https://antmedia.io/webrtc-browser-support/" rel="noopener noreferrer"&gt;more about what WebRTC&lt;/a&gt; is and how it works.&lt;/p&gt;

</description>
      <category>dev2</category>
      <category>webrtc</category>
    </item>
    <item>
      <title>What is WebRTC and how does it work?</title>
      <dc:creator>Mohit Dubey</dc:creator>
      <pubDate>Wed, 03 Sep 2025 06:13:17 +0000</pubDate>
      <link>https://dev.to/mohit_dubey_5ac5787d1280a/what-is-webrtc-and-how-does-it-work-11i</link>
      <guid>https://dev.to/mohit_dubey_5ac5787d1280a/what-is-webrtc-and-how-does-it-work-11i</guid>
      <description>&lt;p&gt;WebRTC stands for Web Real-Time Communications. It is a very exciting, powerful, and highly disruptive cutting-edge technology and streaming protocol.&lt;/p&gt;

&lt;p&gt;WebRTC is HTML5 compatible, and you can use it to add real-time media communications directly between browsers and devices. One of the main advantages of using WebRTC is that it does not require any browser plugins as a prerequisite.&lt;/p&gt;

&lt;p&gt;Webrtc is progressively becoming supported by all major modern browser vendors, including Safari, Google Chrome, Firefox, Opera, and others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://antmedia.io/what-is-webrtc-and-how-webrtc-works/" rel="noopener noreferrer"&gt;Tutorial Source&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it includes&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What is WebRTC?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;History of WebRTC&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;WebRTC Components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;WebRTC Video Streaming&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Types of WebRTC Servers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is great for anyone who is looking to get started with WebRTC &amp;amp; learn about it.&lt;br&gt;
Feel free to check it out, give it a ⭐️ if it helps, and let me know what you think!&lt;/p&gt;

</description>
      <category>webrtc</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
