shoplive_streamer
Broadcast (live streaming) screen for Flutter, built on Shoplive Android SDK 3.0.2 (cloud.shoplive:shoplive-streamer-sdk). Re-exports shoplive_core.
Requirements
| Minimum | |
|---|---|
| Flutter / Dart | 3.22 / 3.4 |
| Android Gradle Plugin / Gradle | 8.7 / 8.9 |
| JDK | 17 |
| Android minSdk / compileSdk | 23 / 36 |
| iOS | 15.0 (Xcode with Swift 5.9 or later; set platform :ios, '15.0' in your Podfile) |
Installation
dependencies:
shoplive_streamer: 3.0.2 # includes shoplive_core
Android: Maven repository setup
Shoplive Android SDK 3.x is served from https://sdk.shoplive.cloud/maven-repo.
Why cloud.shoplive must come only from the Shoplive repository: Maven Central hosts an artifact with the same coordinates but different contents (cloud.shoplive:shoplive-media3:1.10.1.2). The Central copy lacks ShopLiveHlsPlayerFactory, which shoplive-player-sdk:3.0.2 references. If Central is searched first, release (R8) builds fail with Missing class, and HLS playback can crash with NoClassDefFoundError. The fix is to restrict the cloud.shoplive group to the Shoplive repository with exclusiveContent. This is a temporary measure until shoplive-media3 is merged into shoplive-player-sdk (planned for 3.0.4).
(a) Default: automatic
The Shoplive plugins (shoplive_core, shoplive_player, shoplive_streamer) add the repository to rootProject.allprojects for you, using exclusiveContent for the cloud.shoplive group. Gradle fails to resolve a group that is declared exclusiveContent more than once. To avoid that, the first Shoplive plugin sets the root-project flag shopliveMavenRepoConfigured to true and the other plugins skip the declaration. The plugins check the flag's value (from ext or gradle.properties); only true counts. You do not need to add anything.
(b) You declare the repository yourself (mirror/proxy, custom setup)
If your project declares the Shoplive repository itself, do both of the following:
-
Tell the plugins not to add their own declaration. Add this to
android/gradle.properties(the value must betrue;falseor a missing value makes the plugins declare the repository again):shopliveMavenRepoConfigured=true -
Declare the repository with
exclusiveContentwhere your project declares repositories.
Groovy (android/build.gradle):
allprojects {
repositories {
google()
mavenCentral()
exclusiveContent {
forRepository { maven { url "https://sdk.shoplive.cloud/maven-repo" } }
filter { includeGroup "cloud.shoplive" }
}
}
}
Kotlin DSL (android/build.gradle.kts):
allprojects {
repositories {
google()
mavenCentral()
exclusiveContent {
forRepository { maven { url = uri("https://sdk.shoplive.cloud/maven-repo") } }
filter { includeGroup("cloud.shoplive") }
}
}
}
If your build resolves dependencies from settings.gradle(.kts) dependencyResolutionManagement (repositories mode PREFER_SETTINGS), put the same exclusiveContent block there and still set the flag. We have not verified this mode with Flutter builds. In Flutter's default mode (PREFER_PROJECT), project repositories win.
iOS setup
-
Minimum iOS 15. Set
platform :ios, '15.0'inios/Podfile. Flutter's template uses a lower value, andpod installfails with "higher minimum deployment target" until you change it. -
Camera and microphone usage descriptions are required. Add
NSCameraUsageDescriptionandNSMicrophoneUsageDescriptiontoios/Runner/Info.plist. Without them iOS terminates the app as soon as the broadcast screen asks for the camera (crash report: TCC "attempted to access privacy-sensitive data without a usage description"). Android needs no extra setup; the SDK declares its permissions.<key>NSCameraUsageDescription</key> <string>Used to broadcast live video.</string> <key>NSMicrophoneUsageDescription</key> <string>Used to broadcast live audio.</string> -
The Shoplive iOS SDK is downloaded during
pod install. The plugins fetch the SDK 3.0.2 XCFrameworks from the GitHub releasehttps://github.com/shoplive/shoplive-sdk-ios/releases/tag/3.0.2. Every zip is checked against its sha256; if a checksum does not match,pod installstops and nothing unverified is linked. The frameworks are unpacked into the plugin'sios/Frameworks/folder and reused by later installs, so only the first install downloads. Anything that evaluates the podspec downloads too:pod install,flutter build ios/flutter run(which runpod install) andpod spec lint.- Network: the first install needs access to
github.comand its download host.curlhonoursHTTPS_PROXY,ALL_PROXYandNO_PROXY. - Mirror: set
SHOPLIVE_IOS_SDK_BASE_URLto a server that serves<base>/3.0.2/<Name>.xcframework.zip. - Offline / CI: set
SHOPLIVE_IOS_SDK_DIRto a folder that contains the five release zips (ShopliveCore,ShoplivePlayerSDK,ShopliveStreamerSDK,ShopLiveWebRTCHelperSDK,WebRTC.xcframework.zip). To avoid downloading on every CI run, cache the pub cache (key it by SDK version). - The plugin folder must be writable, because the frameworks have to live inside it. With a read-only pub cache, point
PUB_CACHEat a writable folder and runflutter pub getagain.
- Network: the first install needs access to
-
If you run
pod installyourself, use a UTF-8 locale (export LANG=en_US.UTF-8); CocoaPods fails otherwise. -
Upgrading from 1.x: run
flutter cleanonce. Stale 1.x build products otherwise cause "'ShoplivePlayerPlugin' has different definitions in different modules".
Usage
import 'package:shoplive_streamer/shoplive_streamer.dart';
await Shoplive.initialize(const ShopliveConfiguration(accessKey: 'YOUR_ACCESS_KEY'));
// Required before start: the broadcaster token. Without it the server returns no ingest address and the
// broadcast screen shows "Failed to start the broadcast" (logcat: "stream/status failed: Token does not exist").
await Shoplive.setStreamToken('BROADCASTER_STREAM_TOKEN');
final streamer = ShopliveStreamer.instance;
streamer.events.listen((event) {
switch (event) {
case ShopliveStreamerStateChanged(:final state, :final isRehearsal): print('$state rehearsal=$isRehearsal'); // isRehearsal is null on iOS
case ShopliveStreamerErrorEvent(:final error): print('error: ${error.code}');
case ShopliveStreamerUnknownEvent(): break;
}
});
await streamer.start('CAMPAIGN_KEY'); // NO_HOST_SCREEN without a foreground Activity
final state = await streamer.getState(); // last session state, `idle` if none
- Each
startcreates a new broadcast session. Events from the previous session stop being delivered. - A session in
endedis kept, because the SDK may restart the same session, andgetState()reports its real state. A session is released when it isidlewhile the screen is detached, when the nextstartis called, or when the engine is detached. After release,getState()keeps the last state. - Not exposed in 3.0.2: appearance options (resource IDs) and the headless streamer API (requires an embedded preview view).
Errors
Every API returns a Future and fails with PlatformException. The codes are:
code |
Meaning |
|---|---|
INVALID_ARGUMENT |
Missing or blank required value, wrong type, unknown enum value, out-of-range value, or a value rejected by SDK validation |
NO_HOST_SCREEN |
No foreground screen to show the player or broadcast UI (Android: no Activity; iOS: no foreground window/root view controller) |
NOT_RUNNING |
A session command was sent while no player session is running |
SDK_ERROR |
The SDK call failed. details contains the exception class name and, when available, the SDK error code |
A method the platform does not implement fails with MissingPluginException. Event streams never throw on unexpected payloads. Unknown or malformed events arrive as …UnknownEvent, and unknown enum values map to unknown.
Known limitations
- iOS: restarting while a broadcast screen is shown dismisses it and presents the new one afterwards;
startreturns success before that, so a later presentation failure is not reported. - Calling
startwhile a broadcast is still running starts a new session. What happens to the previous session is up to the SDK and is not yet verified. - A kept session (for example
ended) holds a reference to the Activity it was started from until it is released. This is limited to one session.
Libraries
- shoplive_streamer
- Shoplive 방송(streamer) Flutter 플러그인 — Android SDK 3.0.2
cloud.shoplive:shoplive-streamer-sdk.