โ† Zakรกzky

Live Streaming Reliability โ€” React Native + OvenMediaEngine

Rozpoฤet: $200.0 FIXED / โญ 4.52 (57) India

react-native, android, ios, phone, node.js

Preferred qualifications

  • Experience: Expert
๐Ÿญ. ๐—–๐—ข๐—ก๐—ง๐—˜๐—ซ๐—ง 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.
Otevล™รญt na Upwork

AI proposal draft

Generate a short cover letter for this job. Edit before sending.

Sign in to generate an AI proposal draft.

Pล™ihlรกsit