Live Streaming Reliability — React Native + OvenMediaEngine
Worldwide
𝟭. 𝗖𝗢𝗡𝗧𝗘𝗫𝗧 We run a live‑streaming platform. Streamers publish from a React Native mobile app; viewers also watch in a React Native mobile app, playing back through OvenMediaEngine (OME). Both ends are mobile apps — there is no web client, so viewer playback is an in‑app LLHLS player, not a browser. We are hiring a freelancer to make the streamer→OME→viewer path resilient to the real‑world failure modes of mobile streaming: backgrounding, network switches, OS interruptions, crashes, and disconnections. 𝗦𝗧𝗔𝗖𝗞 (𝗙𝗜𝗫𝗘𝗗 — 𝗗𝗢 𝗡𝗢𝗧 𝗣𝗥𝗢𝗣𝗢𝗦𝗘 𝗥𝗘𝗣𝗟𝗔𝗖𝗜𝗡𝗚 𝗧𝗛𝗘𝗦𝗘) | Layer | Technology | |------------------------|-------------------------------------------------| | Streamer app | React Native (mobile) | | Viewer app | React Native (mobile) — in‑app LLHLS player (no web/browser client) | | RTMP publishing module | @cbucket/react-native-livestream | | Media server | OvenMediaEngine (OME) | | Ingest protocol | RTMP | | Viewer playback | LLHLS (Low‑Latency HLS) | | Backend | Stream state/control plane (Node or equivalent) | 𝟮. 𝗢𝗪𝗡𝗘𝗥𝗦𝗛𝗜𝗣 𝗔𝗡𝗗 𝗦𝗖𝗢𝗣𝗘 This is a full end‑to‑end engagement: streamer side → backend → viewer side. You take ownership of a working result, not of a single layer. Every requirement below may involve frontend and backend work. - You may modify the contents of node_modules on the streamer side (specifically @cbucket/react-native-livestream) where required. Modifications must be documented and reproducible (patch file via patch-package or a maintained fork — not an undocumented hand‑edit). - You will write native code where a requirement cannot be met from JS. Several requirements below cannot be met from JS and explicitly require native work. 𝟯. 𝗞𝗘𝗬 𝗗𝗘𝗦𝗜𝗚𝗡 𝗣𝗔𝗥𝗔𝗠𝗘𝗧𝗘𝗥𝗦 (𝗔𝗟𝗥𝗘𝗔𝗗𝗬 𝗗𝗘𝗖𝗜𝗗𝗘𝗗) These are fixed inputs, not open questions: - Reconnection grace window = 60 seconds. If a streamer's media stops (background, network drop, crash) and resumes within 60 s re‑publishing the same stream key, it is treated as the same logical broadcast and viewers resume seamlessly. After 60 s with no media, the broadcast is declared ENDED. - Liveness is determined by actual media flow into OME, not by a client heartbeat. A client "I'm alive" ping is at most a secondary signal. The authoritative signal is whether OME is receiving RTMP bytes for the stream. (Reason: a backgrounded/suspended app cannot reliably send JS heartbeats, but the native media pipeline may still be streaming — and a crashed app sends nothing regardless.) - Viewer playback is LLHLS. On a clean end, the LLHLS playlist must be properly concluded (e.g. OME "Conclude HLS Live") so viewers receive a definitive ended state rather than indefinite loading. 𝟰. 𝗖𝗢𝗥𝗘 𝗥𝗘𝗤𝗨𝗜𝗥𝗘𝗠𝗘𝗡𝗧𝗦 Each requirement is written with an acceptance test. "Done" means the acceptance test passes on the agreed device matrix — not that it works in a quick demo. Vague terms like "seamless" and "graceful" are defined by their acceptance test, not by interpretation. 𝗥𝟭 — 𝗕𝗔𝗖𝗞𝗚𝗥𝗢𝗨𝗡𝗗 / 𝗙𝗢𝗥𝗘𝗚𝗥𝗢𝗨𝗡𝗗 𝗦𝗧𝗥𝗘𝗔𝗠𝗜𝗡𝗚 Required behavior: The app must keep the stream running while backgrounded and resume cleanly on return to foreground, holding the same broadcast across the transition (within the 60 s grace window). Where the operating system prevents camera capture while the app is backgrounded, live video may pause — in which case the viewer must see a black/placeholder frame with a loading indicator (this fallback is acceptable) — and video must resume automatically when the app returns to the foreground. Audio‑only continuation in the background is also acceptable where supported. Use the platform's supported background‑execution mechanism to keep the media pipeline and the connection to OME alive for as long as the OS permits. 𝗔𝗰𝗰𝗲𝗽𝘁𝗮𝗻𝗰𝗲 𝗧𝗲𝘀𝘁: 1. Start a stream. Background the app for up to 60 s, then foreground. 2. If background capture is supported: the viewer sees uninterrupted video (or a gap ≤ the agreed target) and the same session continues. 3. If background capture is not supported: the viewer sees audio‑only or a placeholder + loading indicator; on foreground, video resumes within the agreed gap as the same broadcast. 4. Background beyond 60 s → the broadcast ends cleanly with no ghost stream; returning to foreground starts a new broadcast. 𝗥𝟮 — 𝗡𝗘𝗧𝗪𝗢𝗥𝗞 𝗦𝗪𝗜𝗧𝗖𝗛𝗘𝗦 (𝗪𝗜‑𝗙𝗜 ⇄ 𝗖𝗘𝗟𝗟𝗨𝗟𝗔𝗥) Switching networks mid‑stream must reconnect automatically and resume the same broadcast within the 60 s window. - Define and meet a maximum media gap target on switch: ____ s (suggest ≤ 5 s). - Viewer must show a reconnecting/loading state during the gap and recover automatically. - On switch to cellular, handle the data‑cost dimension: agreed behavior is to warn the user / reduce bitrate / nothing (circle one). 𝗔𝗰𝗰𝗲𝗽𝘁𝗮𝗻𝗰𝗲 𝗧𝗲𝘀𝘁: While streaming on Wi‑Fi, disable Wi‑Fi (device falls back to cellular); reverse the test. Measure the media gap; confirm it meets target, the viewer recovers without manual action, and the backend keeps it as the same session (no new broadcast, no ghost). 𝗥𝟯 — 𝗠𝗢𝗕𝗜𝗟𝗘 𝗜𝗡𝗧𝗘𝗥𝗥𝗨𝗣𝗧𝗜𝗢𝗡𝗦 (𝗧𝗛𝗘 𝗠𝗢𝗦𝗧 𝗖𝗢𝗠𝗠𝗢𝗡𝗟𝗬 𝗙𝗢𝗥𝗚𝗢𝗧𝗧𝗘𝗡 𝗖𝗔𝗧𝗘𝗚𝗢𝗥𝗬) The stream must survive and recover from OS‑level capture interruptions: incoming/outgoing phone calls, alarms, voice assistant, screen lock, system notifications, and another app taking the camera or microphone. Hook into the OS capture/audio‑session interruption lifecycle: on interruption begin, pause the stream gracefully; on interruption end, auto‑resume the same broadcast within the 60 s window. During any interruption the viewer must show the agreed paused/reconnecting state (consistent with R1) — never a frozen UI or a false "live." 𝗔𝗰𝗰𝗲𝗽𝘁𝗮𝗻𝗰𝗲 𝗧𝗲𝘀𝘁: While streaming, place a real phone call to the device (and separately: trigger an alarm, lock the screen, open the native camera app). The stream pauses gracefully; after the interruption ends it auto‑resumes as the same broadcast within the 60 s window; the viewer transitions cleanly through reconnecting → live; no ghost stream is created. 𝗥𝟰 — 𝗦𝗧𝗥𝗘𝗔𝗠‑𝗦𝗜𝗗𝗘 𝗖𝗥𝗔𝗦𝗛 𝗛𝗔𝗡𝗗𝗟𝗜𝗡𝗚 / 𝗡𝗢 𝗚𝗛𝗢𝗦𝗧 𝗦𝗧𝗥𝗘𝗔𝗠𝗦 If the streamer app crashes, is force‑quit, or loses connectivity, the platform must converge to the correct ENDED state and must never leave a "ghost" stream that viewers see as live. This is primarily a backend requirement and cannot be satisfied frontend‑only. Required mechanism: - The backend determines liveness from OME media flow — poll OME's REST API per origin and use inbound‑byte deltas (not mere presence of the stream object, and not raw connection counters, which OME does not decrement reliably). - A lease + 60 s grace window model: the stream's "live" lease is renewed by evidence of media flow; on expiry with no recovery, transition to ENDED. - Session generation/epoch per publish session so a late or missing "close" event for an old session does not corrupt a newly reconnected session (see R5 for the RTMP race this addresses). - On ENDED, force teardown via OME REST (Delete Stream) and Conclude the LLHLS output so viewers get a definitive ended state. 𝗔𝗰𝗰𝗲𝗽𝘁𝗮𝗻𝗰𝗲 𝗧𝗲𝘀𝘁: Force‑quit the app from the app switcher mid‑stream (and separately: enable airplane mode and leave it). The viewer shows reconnecting within ___ s, then ENDED within 60 s + margin; the backend stream state is ENDED; the stream no longer appears as active in OME; and crucially, no ghost stream remains after the grace window. 𝗥𝟱 — 𝗥𝗘𝗖𝗢𝗡𝗡𝗘𝗖𝗧𝗜𝗢𝗡 (𝗦𝗧𝗥𝗘𝗔𝗠𝗘𝗥 𝗔𝗡𝗗 𝗩𝗜𝗘𝗪𝗘𝗥) Unified reconnection behavior covering all of the above causes (background, network switch, interruption, transient crash). - Grace window = 60 s. Re‑publishing the same stream key within 60 s = resume same broadcast; after 60 s = new broadcast. - Reconnection uses exponential backoff with a defined max attempt count / total duration (≤ 60 s of streamer‑side retry before giving up): ____. - Generation‑aware on the backend to handle the RTMP reconnect race: an RTMP reconnect is a new publish session at OME and the old session's close webhook may arrive late or never; the backend must not let a stale close event tear down the resumed session. - Viewer side (LLHLS): the player must auto‑recover when segments resume, show a reconnecting state during the gap, and show a clean ended state when the playlist is concluded. 𝗔𝗰𝗰𝗲𝗽𝘁𝗮𝗻𝗰𝗲 𝗧𝗲𝘀𝘁: (a) Drop the connection and restore it within 60 s → same broadcast resumes for existing viewers. (b) Restore after 60 s → a new broadcast starts and the old one is ENDED. (c) Rapid drop‑and‑reconnect → verify exactly one active session (no duplicate/zombie session, no wrongful teardown of the live session). 𝟱. 𝗗𝗘𝗟𝗜𝗩𝗘𝗥𝗔𝗕𝗟𝗘𝗦 1. Streamer‑side RN implementation (incl. native modules and any documented @cbucket/react-native-livestream patches/fork). 2. Backend stream‑state reconciler implementing the lease + 60 s grace + generation model (R4/R5), with OME REST/webhook integration. 3. Viewer‑side LLHLS integration with full viewer state handling (loading, reconnecting, ended, error). 4. OME configuration changes required. 5. Documentation: architecture overview, the stream state machine, all tunable parameters, every node_modules modification, and run instructions for each acceptance test below. 6. Acceptance test toolkit (we will run these) 𝟲. 𝗔𝗖𝗖𝗘𝗣𝗧𝗔𝗡𝗖𝗘 𝗧𝗘𝗦𝗧 𝗧𝗢𝗢𝗟𝗞𝗜𝗧 - Force‑quit: remove app from the app switcher mid‑stream. - Network switch / loss: toggle Wi‑Fi and airplane mode; use a network link conditioner / bandwidth‑throttling tool for degraded‑network and bitrate‑adaptation tests. - Interruptions: real inbound phone call, alarm, screen lock, launching the native camera app. - Ghost‑stream check: after each failure, query the backend state and OME's active streams — both must read ENDED within the grace window.
$200.00
Fixed-price- ExpertExperience Level
- Remote Job
- One-time projectProject Type
Skills and Expertise
Activity on this job
- Proposals:5 to 10
- Last viewed by client:29 minutes ago
- Interviewing:6
- Invites sent:13
- Unanswered invites:4
About the client
- IndiaHyderabad9:34 PM
- $44K total spent92 hires, 10 active
- 68 hours
Explore similar jobs on Upwork
How it works
Create your free profileHighlight your skills and experience, show your portfolio, and set your ideal pay rate.
Work the way you wantApply for jobs, create easy-to-by projects, or access exclusive opportunities that come to you.
Get paid securelyFrom contract to payment, we help you work safely and get paid securely.
About Upwork
- 4.9/5(Average rating of clients by professionals)
- G2 2021#1 freelance platform
- 49,000+Signed contract every week
- $2.3BFreelancers earned on Upwork in 2020
Find the best freelance jobs
Growing your career is as easy as creating a free profile and finding work like this that fits your skills.
Trusted by