{"article":{"slug":"hijacking-the-ps5s-rtmp-stream","title":"Hijacking the PS5's RTMP Stream","subtitle":null,"summary":"How the PS5 Broadcast RTMP pipeline can be intercepted and redirected: reverse-engineering the stream path and what that unlocks.","content_type":"blog_post","language":"en","canonical_url":"https://yashgarg.dev/posts/hijacking-ps5-rtmp-stream/","author":{"name":"Yash Garg","url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"yashgarg.dev","url":"https://yashgarg.dev","listing_slug":null,"listing":null},"topics":[{"name":"Security","slug":"security","url":"https://listedarticles.com/topics/security"},{"name":"Reverse Engineering","slug":"reverse-engineering","url":"https://listedarticles.com/topics/reverse-engineering"},{"name":"Gaming","slug":"gaming","url":"https://listedarticles.com/topics/gaming"},{"name":"Networking","slug":"networking","url":"https://listedarticles.com/topics/networking"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":1016,"reading_minutes":4,"published_at":"2026-09-28T12:00:00.000Z","added_at":"2026-09-28T12:16:33.095Z","updated_at":"2026-09-28T12:16:33.095Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":false},"profile_url":"https://listedarticles.com/articles/hijacking-the-ps5s-rtmp-stream","markdown_url":"https://listedarticles.com/articles/hijacking-the-ps5s-rtmp-stream.md","example":false,"citation":"Yash Garg, yashgarg.dev. \"Hijacking the PS5's RTMP Stream.\" 28 Sept 2026. https://yashgarg.dev/posts/hijacking-ps5-rtmp-stream/ (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://yashgarg.dev/posts/hijacking-ps5-rtmp-stream/"},"body_markdown":"## Contents\n\nSony has progressively locked down what you can do with the PS5’s hardware. Streaming is a good example: the console gives you a nice, convenient **“Broadcast”** button, but the moment you want to do anything outside the handful of services Sony supports, it gets annoying very fast.\n\nThird-party Bluetooth devices are the same story! Sony locks the wireless stack to their own peripherals, so your headphones or controllers from other brands simply won’t pair :/\n\n## [#](https://yashgarg.dev#the-problem)The Problem\n\nI often stream games with friends on [Discord](https://discord.com) who watch me play, but the PS5 doesn’t support screen sharing to Discord. The obvious fix is a capture card — plug the HDMI output into a [capture card](https://www.elgato.com/us/en/explorer/products/capture/what-is-a-capture-card/), feed it into [OBS](https://obsproject.com/) on your Mac, stream from there. But decent ones aren’t cheap, and I didn’t want to spend upwards of $100 just for this.\n\n## [#](https://yashgarg.dev#remote-play)Remote Play\n\n[Remote Play](https://www.playstation.com/en-in/remote-play/) somewhat worked for me. I could connect the PS5 to my MacBook, share the Mac’s screen to Discord and play from there.\n\nThe problem is that you need to connect everything to the Remote Play device: controller, earphones, etc. I also occasionally ran into input lag, and the stream quality is entirely controlled by the PS5. You can’t really configure anything.\n\nI didn’t want to change my physical setup every time I wanted to stream.\n\n## [#](https://yashgarg.dev#how-ps5-streaming-works)How PS5 Streaming Works\n\nThe PS5 supports streaming to [YouTube](https://youtube.com) and [Twitch](https://twitch.tv) by default if you’re signed into those accounts. The protocol used for this is [RTMP](https://en.wikipedia.org/wiki/Real-Time_Messaging_Protocol), or Real-Time Messaging Protocol, which is commonly used for live audio/video streaming.\n\nSo when you start a broadcast, the PS5 roughly does this:\n\nWhat if we could make our own device act as Twitch and receive that RTMP stream instead?\n\nThat’s the idea. The PS5 doesn’t hardcode Twitch’s IP, it looks it up via DNS every time. If we control what DNS returns, we control where the stream goes.\n\n## [#](https://yashgarg.dev#finding-the-right-hostname)Finding the Right Hostname\n\nThe obvious first attempt was to spoof `ingest.twitch.tv` directly. That’s the hostname the PS5 resolves when you hit broadcast, so pointing it at the Mac should work, right?\n\nNot quite. `ingest.twitch.tv:443` is actually a **discovery endpoint**, not the RTMP server itself. The PS5 makes an HTTPS call to it asking “which regional ingest server should I use?”. Twitch responds with something like `ap-southeast-1.prod.fi.contribute.live-video.net`. Then the PS5 pushes the actual stream there.\n\nSpoofing that hostname ran into a different problem: the actual Twitch ingest uses **RTMPS** (RTMP over TLS on port 443), and the PS5 validates the certificate against trusted [CAs](https://en.wikipedia.org/wiki/Certificate_authority). A self-signed cert doesn’t work, and there’s no way to install custom CAs on a PS5.\n\nI then tried YouTube as a workaround. YouTube’s RTMP ingest uses plain RTMP on port 1935 with no TLS, so the stream came through fine. But the PS5 stopped the broadcast after about 60 seconds because it periodically checks YouTube’s API to confirm the stream is actually live. Since we intercepted it, YouTube never saw it, so the API returned nothing and the PS5 gave up.\n\nThe actual fix came from watching DNS logs while broadcasting:\n\n```\nsudo tail -f /tmp/dnsmasq.log\n# Sep 22 23:20:28 dnsmasq: query[A] ingest.global-contribute.live-video.net from 192.168.8.171\n# Sep 22 23:20:28 dnsmasq: reply aps30.contribute.live-video.net is 35.55.13.0\n```\nThe PS5 was resolving `ingest.global-contribute.live-video.net`, which chains down to `aps30.contribute.live-video.net`. That’s the real RTMP server. Spoofing `contribute.live-video.net` covers all subdomains and redirects the actual stream to the Mac without any certificate issues.\n\n## [#](https://yashgarg.dev#dns-trick)DNS Trick\n\nThe setup has two main parts: [`dnsmasq`](https://dnsmasq.org) and [`nginx-rtmp`](https://github.com/arut/nginx-rtmp-module). I built a small macOS menu bar app that bundles both and manages them.\n\nI run `dnsmasq` on my Mac and configure it to resolve Twitch’s ingest domains to my Mac’s LAN address:\n\n```\nserver=1.1.1.1\nserver=8.8.8.8\n# Redirect Twitch ingest traffic to the Mac\naddress=/contribute.live-video.net/192.168.8.175\naddress=/ingest.global-contribute.live-video.net/192.168.8.175\naddress=/live.twitch.tv/192.168.8.175\naddress=/live-sin.twitch.tv/192.168.8.175\naddress=/live-nrt.twitch.tv/192.168.8.175\naddress=/live-syd.twitch.tv/192.168.8.175\naddress=/live-fra.twitch.tv/192.168.8.175\naddress=/live-ams.twitch.tv/192.168.8.175\naddress=/live-lhr.twitch.tv/192.168.8.175\naddress=/live-jfk.twitch.tv/192.168.8.175\naddress=/live-lax.twitch.tv/192.168.8.175\naddress=/live-sea.twitch.tv/192.168.8.175\nlog-queries\nlog-facility=/tmp/dnsmasq.log\nno-hosts\nlisten-address=0.0.0.0\n```\n`192.168.8.175` is my Mac’s IP. When the PS5 asks DNS for one of these Twitch endpoints, `dnsmasq` returns my Mac’s IP instead. The PS5 connects to my Mac thinking it’s Twitch.\n\nThe last piece is pointing the PS5 at this DNS server. I have a [GL.iNet router](https://www.gl-inet.com/) running [OpenWRT](https://openwrt.org/), so I configured it to hand my Mac’s IP as the DNS server specifically for the PS5’s [DHCP](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol) lease.\n\n```\n# SSH into the router and run:\nuci add_list dhcp.lan.dhcp_option=\"tag:PS5,6,192.168.8.175\"\nuci commit dhcp\n/etc/init.d/dnsmasq restart\n```\nThe `tag:PS5` part works because the PS5’s static lease already has that tag set in `/etc/config/dhcp`. Option `6` is the DHCP option for DNS server. The PS5 picks this up on its next DHCP renewal, no manual DNS configuration is required on the console!\n\n## [#](https://yashgarg.dev#receiving-the-stream)Receiving the Stream\n\nFor that, I’m using `nginx-rtmp`:\n\n```\nworker_processes 1;\nerror_log /tmp/nginx-error.log warn;\npid /tmp/nginx.pid;\nevents {\n    worker_connections 512;\n}\nrtmp {\n    server {\n        listen 1935;\n        chunk_size 4096;\n        application app {\n            live on;\n            record off;\n            sync 10ms;\n            # Notify our app when a stream starts\n            on_publish http://127.0.0.1:9988/on_publish;\n        }\n    }\n}\nhttp {\n    server {\n        listen 8080;\n        location /stat {\n            rtmp_stat all;\n        }\n    }\n}\n```\nThe `on_publish` callback is how the menu bar app detects when the PS5 starts broadcasting. nginx fires a POST to `localhost:9988` with the stream name, and the app surfaces the full RTMP URL ready to copy.\n\nAt this point, the PS5 is pushing its stream (1080p60, H.264, AAC stereo) directly to my Mac instead of Twitch.\n\nFrom here I can pull the stream into anything: OBS to re-stream it, record it locally, or just play it directly.\n\n## [#](https://yashgarg.dev#watching-it)Watching It\n\nInstead of going through OBS, I used [`mpv`](https://mpv.io/) to pull the stream and shared the window to Discord. The low-latency profile keeps the delay less than a second:\n\n`mpv --profile=low-latency --audio-buffer=0.3 rtmp://127.0.0.1/app/<stream-key>`\nThis has been quite reliable surprisingly. I’ve been using it for a few weeks now and haven’t had any issues. You can find the complete source code [here](https://github.com/yash-garg/PS5Streamer).\n\n*Until next time! 👋*","body_html":"<h2 id=\"contents\">Contents</h2>\n<p>Sony has progressively locked down what you can do with the PS5’s hardware. Streaming is a good example: the console gives you a nice, convenient <strong>“Broadcast”</strong> button, but the moment you want to do anything outside the handful of services Sony supports, it gets annoying very fast.</p>\n<p>Third-party Bluetooth devices are the same story! Sony locks the wireless stack to their own peripherals, so your headphones or controllers from other brands simply won’t pair :/</p>\n<h2 id=\"the-problem\"><a href=\"https://yashgarg.dev#the-problem\" rel=\"nofollow ugc noopener\">#</a>The Problem</h2>\n<p>I often stream games with friends on <a href=\"https://discord.com\" rel=\"nofollow ugc noopener\">Discord</a> who watch me play, but the PS5 doesn’t support screen sharing to Discord. The obvious fix is a capture card — plug the HDMI output into a <a href=\"https://www.elgato.com/us/en/explorer/products/capture/what-is-a-capture-card/\" rel=\"nofollow ugc noopener\">capture card</a>, feed it into <a href=\"https://obsproject.com/\" rel=\"nofollow ugc noopener\">OBS</a> on your Mac, stream from there. But decent ones aren’t cheap, and I didn’t want to spend upwards of $100 just for this.</p>\n<h2 id=\"remote-play\"><a href=\"https://yashgarg.dev#remote-play\" rel=\"nofollow ugc noopener\">#</a>Remote Play</h2>\n<p><a href=\"https://www.playstation.com/en-in/remote-play/\" rel=\"nofollow ugc noopener\">Remote Play</a> somewhat worked for me. I could connect the PS5 to my MacBook, share the Mac’s screen to Discord and play from there.</p>\n<p>The problem is that you need to connect everything to the Remote Play device: controller, earphones, etc. I also occasionally ran into input lag, and the stream quality is entirely controlled by the PS5. You can’t really configure anything.</p>\n<p>I didn’t want to change my physical setup every time I wanted to stream.</p>\n<h2 id=\"how-ps5-streaming-works\"><a href=\"https://yashgarg.dev#how-ps5-streaming-works\" rel=\"nofollow ugc noopener\">#</a>How PS5 Streaming Works</h2>\n<p>The PS5 supports streaming to <a href=\"https://youtube.com\" rel=\"nofollow ugc noopener\">YouTube</a> and <a href=\"https://twitch.tv\" rel=\"nofollow ugc noopener\">Twitch</a> by default if you’re signed into those accounts. The protocol used for this is <a href=\"https://en.wikipedia.org/wiki/Real-Time_Messaging_Protocol\" rel=\"nofollow ugc noopener\">RTMP</a>, or Real-Time Messaging Protocol, which is commonly used for live audio/video streaming.</p>\n<p>So when you start a broadcast, the PS5 roughly does this:</p>\n<p>What if we could make our own device act as Twitch and receive that RTMP stream instead?</p>\n<p>That’s the idea. The PS5 doesn’t hardcode Twitch’s IP, it looks it up via DNS every time. If we control what DNS returns, we control where the stream goes.</p>\n<h2 id=\"finding-the-right-hostname\"><a href=\"https://yashgarg.dev#finding-the-right-hostname\" rel=\"nofollow ugc noopener\">#</a>Finding the Right Hostname</h2>\n<p>The obvious first attempt was to spoof <code>ingest.twitch.tv</code> directly. That’s the hostname the PS5 resolves when you hit broadcast, so pointing it at the Mac should work, right?</p>\n<p>Not quite. <code>ingest.twitch.tv:443</code> is actually a <strong>discovery endpoint</strong>, not the RTMP server itself. The PS5 makes an HTTPS call to it asking “which regional ingest server should I use?”. Twitch responds with something like <code>ap-southeast-1.prod.fi.contribute.live-video.net</code>. Then the PS5 pushes the actual stream there.</p>\n<p>Spoofing that hostname ran into a different problem: the actual Twitch ingest uses <strong>RTMPS</strong> (RTMP over TLS on port 443), and the PS5 validates the certificate against trusted <a href=\"https://en.wikipedia.org/wiki/Certificate_authority\" rel=\"nofollow ugc noopener\">CAs</a>. A self-signed cert doesn’t work, and there’s no way to install custom CAs on a PS5.</p>\n<p>I then tried YouTube as a workaround. YouTube’s RTMP ingest uses plain RTMP on port 1935 with no TLS, so the stream came through fine. But the PS5 stopped the broadcast after about 60 seconds because it periodically checks YouTube’s API to confirm the stream is actually live. Since we intercepted it, YouTube never saw it, so the API returned nothing and the PS5 gave up.</p>\n<p>The actual fix came from watching DNS logs while broadcasting:</p>\n<pre><code>sudo tail -f /tmp/dnsmasq.log\n# Sep 22 23:20:28 dnsmasq: query[A] ingest.global-contribute.live-video.net from 192.168.8.171\n# Sep 22 23:20:28 dnsmasq: reply aps30.contribute.live-video.net is 35.55.13.0</code></pre>\n<p>The PS5 was resolving <code>ingest.global-contribute.live-video.net</code>, which chains down to <code>aps30.contribute.live-video.net</code>. That’s the real RTMP server. Spoofing <code>contribute.live-video.net</code> covers all subdomains and redirects the actual stream to the Mac without any certificate issues.</p>\n<h2 id=\"dns-trick\"><a href=\"https://yashgarg.dev#dns-trick\" rel=\"nofollow ugc noopener\">#</a>DNS Trick</h2>\n<p>The setup has two main parts: <a href=\"https://dnsmasq.org\" rel=\"nofollow ugc noopener\"><code>dnsmasq</code></a> and <a href=\"https://github.com/arut/nginx-rtmp-module\" rel=\"nofollow ugc noopener\"><code>nginx-rtmp</code></a>. I built a small macOS menu bar app that bundles both and manages them.</p>\n<p>I run <code>dnsmasq</code> on my Mac and configure it to resolve Twitch’s ingest domains to my Mac’s LAN address:</p>\n<pre><code>server=1.1.1.1\nserver=8.8.8.8\n# Redirect Twitch ingest traffic to the Mac\naddress=/contribute.live-video.net/192.168.8.175\naddress=/ingest.global-contribute.live-video.net/192.168.8.175\naddress=/live.twitch.tv/192.168.8.175\naddress=/live-sin.twitch.tv/192.168.8.175\naddress=/live-nrt.twitch.tv/192.168.8.175\naddress=/live-syd.twitch.tv/192.168.8.175\naddress=/live-fra.twitch.tv/192.168.8.175\naddress=/live-ams.twitch.tv/192.168.8.175\naddress=/live-lhr.twitch.tv/192.168.8.175\naddress=/live-jfk.twitch.tv/192.168.8.175\naddress=/live-lax.twitch.tv/192.168.8.175\naddress=/live-sea.twitch.tv/192.168.8.175\nlog-queries\nlog-facility=/tmp/dnsmasq.log\nno-hosts\nlisten-address=0.0.0.0</code></pre>\n<p><code>192.168.8.175</code> is my Mac’s IP. When the PS5 asks DNS for one of these Twitch endpoints, <code>dnsmasq</code> returns my Mac’s IP instead. The PS5 connects to my Mac thinking it’s Twitch.</p>\n<p>The last piece is pointing the PS5 at this DNS server. I have a <a href=\"https://www.gl-inet.com/\" rel=\"nofollow ugc noopener\">GL.iNet router</a> running <a href=\"https://openwrt.org/\" rel=\"nofollow ugc noopener\">OpenWRT</a>, so I configured it to hand my Mac’s IP as the DNS server specifically for the PS5’s <a href=\"https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol\" rel=\"nofollow ugc noopener\">DHCP</a> lease.</p>\n<pre><code># SSH into the router and run:\nuci add_list dhcp.lan.dhcp_option=&quot;tag:PS5,6,192.168.8.175&quot;\nuci commit dhcp\n/etc/init.d/dnsmasq restart</code></pre>\n<p>The <code>tag:PS5</code> part works because the PS5’s static lease already has that tag set in <code>/etc/config/dhcp</code>. Option <code>6</code> is the DHCP option for DNS server. The PS5 picks this up on its next DHCP renewal, no manual DNS configuration is required on the console!</p>\n<h2 id=\"receiving-the-stream\"><a href=\"https://yashgarg.dev#receiving-the-stream\" rel=\"nofollow ugc noopener\">#</a>Receiving the Stream</h2>\n<p>For that, I’m using <code>nginx-rtmp</code>:</p>\n<pre><code>worker_processes 1;\nerror_log /tmp/nginx-error.log warn;\npid /tmp/nginx.pid;\nevents {\n    worker_connections 512;\n}\nrtmp {\n    server {\n        listen 1935;\n        chunk_size 4096;\n        application app {\n            live on;\n            record off;\n            sync 10ms;\n            # Notify our app when a stream starts\n            on_publish http://127.0.0.1:9988/on_publish;\n        }\n    }\n}\nhttp {\n    server {\n        listen 8080;\n        location /stat {\n            rtmp_stat all;\n        }\n    }\n}</code></pre>\n<p>The <code>on_publish</code> callback is how the menu bar app detects when the PS5 starts broadcasting. nginx fires a POST to <code>localhost:9988</code> with the stream name, and the app surfaces the full RTMP URL ready to copy.</p>\n<p>At this point, the PS5 is pushing its stream (1080p60, H.264, AAC stereo) directly to my Mac instead of Twitch.</p>\n<p>From here I can pull the stream into anything: OBS to re-stream it, record it locally, or just play it directly.</p>\n<h2 id=\"watching-it\"><a href=\"https://yashgarg.dev#watching-it\" rel=\"nofollow ugc noopener\">#</a>Watching It</h2>\n<p>Instead of going through OBS, I used <a href=\"https://mpv.io/\" rel=\"nofollow ugc noopener\"><code>mpv</code></a> to pull the stream and shared the window to Discord. The low-latency profile keeps the delay less than a second:</p>\n<p><code>mpv --profile=low-latency --audio-buffer=0.3 rtmp://127.0.0.1/app/&lt;stream-key&gt;</code>\nThis has been quite reliable surprisingly. I’ve been using it for a few weeks now and haven’t had any issues. You can find the complete source code <a href=\"https://github.com/yash-garg/PS5Streamer\" rel=\"nofollow ugc noopener\">here</a>.</p>\n<p><em>Until next time! 👋</em></p>","headings":[{"level":2,"text":"Contents","id":"contents"},{"level":2,"text":"#The Problem","id":"the-problem"},{"level":2,"text":"#Remote Play","id":"remote-play"},{"level":2,"text":"#How PS5 Streaming Works","id":"how-ps5-streaming-works"},{"level":2,"text":"#Finding the Right Hostname","id":"finding-the-right-hostname"},{"level":2,"text":"#DNS Trick","id":"dns-trick"},{"level":2,"text":"#Receiving the Stream","id":"receiving-the-stream"},{"level":2,"text":"#Watching It","id":"watching-it"}]}}