Moblin - IRL Streaming
A free iOS app for IRL streaming. Mainly targeting Twitch, but can stream to YouTube, Kick, Facebook and OBS Studio as well (and probably more).
Website: https://moblin.app
Discord: https://discord.moblin.app
Github: https://github.com/eerimoq/moblin
TestFlight: https://testflight.apple.com/join/PDpxEaGh
Privacy policy: https://eerimoq.github.io/moblin/privacy-policy/en.html
Features
Main app
- Stream using RTMP, RTMPS, SRT, SRTLA, RIST or WHIP (WebRTC) to any
- Mobcam. Use the phone as a low latency webcam over USB.
- H.264/AVC and H.265/HEVC video codecs.
- Up to 4K resolution and 60 FPS. Use 120 FPS at your own risk.
- SRTLA and RIST.
- Twitch integration.
- Kick integration.
- YouTube integration.
- SOOP integration.
- Open Streaming Platform integration.
- Basic scenes.
- Back, front or multi camera.
- Low energy triple and dual cameras.
- Back, front, top, bottom or external mic.
- Video stabilization.
- Zoom.
- Back camera lens selection.
- Record to disk (MP4-file).
- Ingests.
- Localization. Supports many languages, for example English, French,
- Tap screen for manual focus.
- Stream connection status and uptime.
- OBS WebSocket (remote control)
- Make phone screen black by pressing a button.
- Stealth mode. Show a custom image instead of the app.
- Supports UVC (USB-C) cameras on iPad.
- Basic support for Mac.
- Video effects.
- Alerts.
- Chat.
- Color spaces (for devices that supports them).
- Bundled and custom 3D LUT effects.
- Battery indicator.
- Web browser.
- Game controllers for remote control.
- Stream Deck support.
- Keyboard shortcuts.
- Selfie stick button support.
- Moblink for more connection.
- Low light boost.
- Cosmetics.
- Configure stream resolution, FPS, video codec, bitrate and more.
- Configurable bitrate presets.
- Adaptive bitrate for SRT(LA), RIST and RTMP.
- Macros. Run a sequence of actions, optionally repeatedly.
- Optionally remote control the streamer's Moblin app over the network.
- Web remote control. Control the streamer's Moblin app from a web
- Torch.
- Mute audio.
- Talkback.
- Deep link settings (moblin://).
- Landscape.
- Portrait.
- Background streaming.
- Simple poll.
- Chat bot.
- Screen capture as video source.
- Basic video player as video source and mic.
- Apple Music control. Experimental.
- DJI camera Bluetooth controller.
- GoPro QR-code creator.
- Show grid for easier positioning.
- Camera settings (on some cameras).
- Cat printer.
- Black Shark cooler support.
- Take snapshots.
- Photo shoot. Take clean pictures periodically.
- Save and play replays.
- Tesla vehicle status and control.
- Support for DockKit gimbals.
- Cycling power monitor.
- Heart rate monitor.
- Workout. Walking, running and cycling.
- Show video on external display. Aka clean HDMI out.
- Basic VTuber and PNGTuber.
- Auto scene switcher.
- Disconnect protection. Automatically switch to a fallback scene when
- Navigation. Walking, cycling and driving directions.
- RTMP(S) multi streaming.
- Preview stream. Low bitrate copy of the stream.
Apple Watch companion app
- Stream preview.
- Show audio level.
- Show bitrate.
- Show number of viewers.
- Show iPhone thermal state.
- Chat.
- Control.
- Scoreboards.
- Watch face complication.
Import settings using moblin:// (custom URL)
Examples
New stream
An example creating a new stream is
moblin://?{"streams":[{"name":"BELABOX%20UK","url":"srtla://uk.srt.belabox.net:5000?streamid=9812098rh9hf8942hid","video":{"codec":"H.265/HEVC"},"obs":{"webSocketUrl":"ws://123.22.32.112:5465","webSocketPassword":"foobar"}}]}
where the URL decoded pretty printed JSON blob is
`` json
{
"streams": [
{
"name": "BELABOX UK",
"url": "srtla://uk.srt.belabox.net:5000?streamid=9812098rh9hf8942hid",
"video": {
"codec": "H.265/HEVC"
},
"obs": {
"webSocketUrl": "ws://123.22.32.112:5465",
"webSocketPassword": "foobar"
}
}
]
}
### Quick button settings
An example with only two quick buttons enabled is moblin://?{"quickButtons":{"twoColumns":false,"showName":true,"enableScroll":true,"disableAllButtons":true,"buttons":[{"type":"Mute","enabled":true},{"type":"Draw","enabled":true}]}}
where the URL decoded pretty printed JSON blob is json
{
"quickButtons": {
"twoColumns": false,
"showName": true,
"enableScroll": true,
"disableAllButtons": true,
"buttons": [
{
"type": "Mute",
"enabled": true
},
{
"type": "Draw",
"enabled": true
}
]
}
}
js moblin.subscribe({ chat: { prefix: "!" } }); moblin.onmessage = (message) => { if (message.chat !== undefined) { console.log(message.chat.message); } };## Specificationmoblin://?<URL encoded JSON blob>Format:
MoblinSettingsUrlThe
class in MoblinSettingsUrl.swift defines the JSON blob format. Class members are JSON object keys. Members with?after the type are optional.Settings -> Scenes -> My browser widget -> Moblin accessBrowser widget JavaScript API
Get access to various data in your Browser widget.
NOTE: You must enable
to give the website access to the Browser widget JavaScript API.!Example
Add this code to your website to receive chat messages with prefix
.
js moblin.subscribe({ speechToText: {} }); moblin.onmessage = (message) => { if (message.speechToText !== undefined) { console.log(message.speechToText.position, message.speechToText.text); } if (message.speechToTextClear !== undefined) { console.log("Transcript cleared"); } };Add this code to your website to receive the speech to text transcript. You must enableSettings -> Scenes -> My browser widget -> Speech to textas well.textis a sliding window of the latest transcript andpositionis the offset of its first character, counted from when speech to text started. The transcript is cleared after a few seconds of silence.
Add this code to your website to write a message to Moblin's log.js
moblin.log("Hello from my browser widget!");
brew install just brew install swiftlint brew install swiftformat brew install codespell brew install oxfmt brew install oxlint brew install python3.14 python3.14 -m venv .venv source .venv/bin/activate pip install -r requirements.txt -U## SpecificationSubscribeTopicTopics to subscribe to are defined by
in BrowserEffectServer.swift.onmessageMessages passed to
are defined byMessagein BrowserEffectServer.swift.git clone https://github.com/eerimoq/moblin.gitSimilar software
- https://irlpro.app/
- Twitch app.
- https://softvelum.com/larix/ios/
Development environment setup
Build the project
Roughly the steps to setup Moblin's developement environment.
- Install Xcode with iOS and MacOS simulators on your Mac.
- Open a terminal.
- Clone Moblin.
cd moblin
- Enter Moblins repository.
Config/User.xcconfig
- Create
. This file contains user specific settings and is not under version control.cp User.template.xcconfig Config/User.xcconfigopen Moblin.xcodeproj
- Open the Moblin project in Xcode. Wait for the dependencies to load.
Config/User.xcconfig
- Modify
in Xcode.Command + B
- Press
to build Moblin.Run Destination
- Enable developer mode in your iPhone/iPad.
- Select you iPhone/iPad as
in Xcode (at the top in the middle).Command + R
- Build and run by pressing
.
- Done!
Styling, linting and more
- Install tools.
2. Perform styling, linting and more.
source .venv/bin/activate # Once per shell is enough.
just style lint spell-check
json { "webcredentials": { "apps": [ "L82N7LD4N5.com.eerimoq.Mobs" ] } }3. Done!just web-remote-control-frontend-prepareWeb remote control frontend
It's built with SolidJS.
- Install dependencies.
WebRemoteControlFrontend/
- Modify files in
.Moblin/RemoteControl/Web/*
- Build to update files in
.just web-remote-control-frontend-buildASWebAuthenticationSession
- Done!
Twitch login callback server
Twitch login uses
with anhttps://mys-lang.org/authcallback. For iOS to hand the callback to Moblin,mys-lang.orgmust serve an Apple App Site Association file that lists Moblin's app identifier, and Moblin's entitlements must containwebcredentials:mys-lang.org(they already do)..well-known/apple-app-site-association
- Create
(no file extension) with the following content.
nginx location /.well-known/apple-app-site-association { default_type application/json; } `2. Serve it over HTTPS asapplication/jsonin nginx.
- Reload nginx.
sudo nginx -s reload
- Verify that it is served.
curl -i https://mys-lang.org/.well-known/apple-app-site-association`
- Done!