<?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.us-east-2.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>I deployed Media over QUIC on AWS</title>
      <dc:creator>Mohit Dubey</dc:creator>
      <pubDate>Tue, 01 Sep 2026 17:05:08 +0000</pubDate>
      <link>https://dev.to/mohit_dubey_5ac5787d1280a/i-deployed-media-over-quic-on-aws-1b75</link>
      <guid>https://dev.to/mohit_dubey_5ac5787d1280a/i-deployed-media-over-quic-on-aws-1b75</guid>
      <description>&lt;p&gt;Media over QUIC has a strange problem for a protocol this well-backed: there is a great deal written about it and almost nowhere to try it.&lt;/p&gt;

&lt;p&gt;Search for it, and you will find explainers, IETF drafts, and Cloudflare's announcement that they run relays at the edge. What you will not easily find is a server you can point a browser at. Until recently, the honest answer to "how do I try MoQ" was "compile this Rust project and good luck."&lt;/p&gt;

&lt;p&gt;Disclosure before anything else: I work at Ant Media, and we build the server this runs on. I am writing this because I spent last week deploying it end-to-end, and the notes seemed worth having in one place — including the parts that went wrong, which are the useful parts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What MoQ actually is, briefly&lt;/strong&gt;&lt;br&gt;
MoQ is a live media protocol built on QUIC, currently being standardised by the IETF. The working group includes Google, Cloudflare, Cisco, Meta and Akamai. The goal is to replace WebRTC, HLS and RTMP with one protocol that covers all of them.&lt;/p&gt;

&lt;p&gt;The reason it exists is a trade-off every streaming engineer has lived with. WebRTC gives you real-time latency and no CDN — every viewer is a peer connection, and scaling means an SFU and a lot of servers. HLS gives you CDN scale and several seconds of delay, which breaks anything interactive.&lt;/p&gt;

&lt;p&gt;MoQ runs on QUIC, where a delayed packet does not block the ones behind it, and uses a publish/subscribe model that a CDN can cache. That is the whole pitch: sub-second delivery with a fan-out story that is a caching problem rather than a connection-count problem.&lt;/p&gt;

&lt;p&gt;It uses WebTransport, so it works in the browser with no plugin and no peer connection bookkeeping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you end up with&lt;/strong&gt;&lt;br&gt;
A single EC2 instance running a MoQ relay, a browser publisher, and a browser player. You publish from one tab, watch in another, and the debug panel tells you what you are actually getting rather than what a marketing page claims.&lt;/p&gt;

&lt;p&gt;It takes roughly ten minutes from installation to publishing and playing your MoQ stream.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The four steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Launch the AMI.&lt;/strong&gt; A c5.xlarge is plenty for evaluation. The image arrives with the server already running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Add port 4443 to the security group, on TCP and UDP.&lt;/strong&gt; That is where the relay listens. Read the next section before you skip past this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Turn on SSL from the web panel.&lt;/strong&gt; Open &lt;a href="http://your-server-ip:5080" rel="noopener noreferrer"&gt;http://your-server-ip:5080&lt;/a&gt; — HTTP on 5080, because that is how the server starts before a certificate exists. Then Settings → SSL → Subdomain of antmedia.cloud → Activate. You get an allocated subdomain and a Let's Encrypt certificate, and the server restarts on &lt;a href="https://your-subdomain.antmedia.cloud:5443" rel="noopener noreferrer"&gt;https://your-subdomain.antmedia.cloud:5443&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You do not need to own a domain. This surprised me, and it removes the most annoying prerequisite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Install the plugin. SSH in as ubuntu&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# fetch the plugin release onto the server&lt;/span&gt;
curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="s2"&gt;"https://drive.usercontent.google.com/download?id=1X9ymWsDjfdNdcXH2h0y2Ak2IWpmnkijk&amp;amp;export=download&amp;amp;confirm=t"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; MoQPlugin-release.zip

&lt;span class="c"&gt;# unpack it and step into the folder&lt;/span&gt;
unzip MoQPlugin-release.zip
&lt;span class="nb"&gt;cd &lt;/span&gt;MoQ-Plugin

&lt;span class="c"&gt;# make the installer executable, then run it&lt;/span&gt;
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x install-moq-plugin.sh
&lt;span class="nb"&gt;sudo&lt;/span&gt; ./install-moq-plugin.sh

&lt;span class="c"&gt;# put the browser publisher and player into your application&lt;/span&gt;
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /usr/local/antmedia/webapps/live/moq
&lt;span class="nb"&gt;sudo cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; moq-ams-player-build/&lt;span class="k"&gt;*&lt;/span&gt; /usr/local/antmedia/webapps/live/moq

&lt;span class="c"&gt;# restart so the server loads the plugin&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;service antmedia restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open the publisher at &lt;code&gt;/live/moq/publish.html&lt;/code&gt;, pick a stream ID and hit publish. Open the player at &lt;code&gt;/live/moq/play.html&lt;/code&gt; in a second window, enter the same stream ID, and select the source track.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The two important things&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The security group rule has to cover UDP, not just TCP.&lt;/strong&gt;&lt;br&gt;
With only TCP open, every page loads perfectly. The publisher initialises. The player initialises. The WebTransport session simply never establishes, and nothing surfaces an error worth reading. Everything looks like a working install right up until it isn't.&lt;br&gt;
If you are deploying anything QUIC-based on EC2, open both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browser support is the real constraint today, not the protocol.&lt;/strong&gt;&lt;br&gt;
Chrome, Edge, and Brave are fine. Safari needs 26.4 or later. If you were thinking about anything consumer-facing, that is a meaningful chunk of an audience, and it is the thing most likely to decide whether MoQ is usable for you right now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The honest part: this is moq-lite&lt;/strong&gt;&lt;br&gt;
What we ship is &lt;strong&gt;moq-lite&lt;/strong&gt;, a deliberately reduced subset of the IETF moq-transport draft, specified separately as draft-lcurley-moq-lite. It is forward-compatible with moq-transport and works against moq-transport relays, including Cloudflare's.&lt;/p&gt;

&lt;p&gt;It leaves things out on purpose — no sub-groups, no gaps, no joining fetch, no object properties. In practice, most applications do not need them, but it is a real difference, and you should know it is there.&lt;/p&gt;

&lt;p&gt;More broadly: &lt;strong&gt;if any vendor tells you they support MoQ, ask which draft and what they have tested against.&lt;/strong&gt; The standard is still moving. Draft-20 is the interop target for the working group's October interim, and the transport draft is not scheduled to be requested for publication until the end of 2026. Ours included — this is a fair question to ask us.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where I would leave it&lt;/strong&gt;&lt;br&gt;
MoQ is at the stage where you should run it in staging and form an opinion, not where you should migrate anything. The reason to look now is that the architecture question — do we keep running an SFU — becomes much easier to answer once you have seen the alternative work.&lt;/p&gt;

&lt;p&gt;If you try it and something breaks, I would rather hear it than not. The full deployment guide with screenshots is on &lt;a href="https://antmedia.io/moq-on-aws/" rel="noopener noreferrer"&gt;our site&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webrtc</category>
      <category>moq</category>
      <category>aws</category>
      <category>tutorial</category>
    </item>
    <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>
