Skip to content

Commit

Permalink
Merge pull request #31 from StreamAMG/feature/CORE-4969-Update-SDK-to…
Browse files Browse the repository at this point in the history
…-avoid-restarting-player-when-screen-rotated

Feature/core 4969 update sdk to avoid restarting player when screen rotated
  • Loading branch information
KharchenkoAlex authored Nov 6, 2024
2 parents b10e7be + 297daff commit 4849f7f
Show file tree
Hide file tree
Showing 11 changed files with 524 additions and 260 deletions.
3 changes: 2 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

177 changes: 113 additions & 64 deletions docs/data/tutorials/playbacksdk/getstarted.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
{
"inlineContent": [
{
"text": "Make sure this step is done before proceed to the next steps",
"text": "Ensure that the plugin setup and registration occur during the app's initialization process.",
"type": "text"
}
],
Expand Down Expand Up @@ -163,7 +163,7 @@
},
{
"type": "text",
"text": " Initialize the Playback SDK by providing your API key and register the default player plugin."
"text": "Create an instance of the custom video player plugin and configure it by setting playback options such as autoplay and background playback. To do this, create a `VideoPlayerConfig` object, update its autoplay and background playback settings, and then pass this configuration object to the plugin."
},
{
"type": "text",
Expand All @@ -172,7 +172,7 @@
{
"inlineContent": [
{
"text": "Make sure this step is done when the app starts.",
"text": "Ensure that the plugin setup and registration occur during the app's initialization process.",
"type": "text"
}
],
Expand Down Expand Up @@ -293,7 +293,7 @@
},
{
"type": "text",
"text": " function provided by the Playback SDK to initialize and load the video player. The function takes the entry ID and authorization token as parameters. Additionally, it includes a closure to handle any potential playback errors that may occur during the loading process."
"text": " function provided by the Playback SDK to initialize and load the video player. The function takes three parameters: the entry ID, viewer ID, and authorization token. The viewer ID is the unique ID from CloudPay (CustomerID). It will not be present for free videos, as there is no session for those users. If the viewer ID is null, analytics tracking will be disabled. Additionally, it includes a closure to handle any potential playback errors that may occur during the loading process."
},
{
"type": "text",
Expand Down Expand Up @@ -474,6 +474,14 @@
"references": {
"PlayerTestView.kt": {
"identifier": "PlayerTestView.kt",
"highlights": [
{
"line": 84
},
{
"line": 86
}
],
"content": [
"// Others imports",
"import com.streamamg.PlaybackAPIError",
Expand All @@ -484,38 +492,58 @@
"import com.streamamg.player.plugin.VideoPlayerPluginManager",
"import com.streamamg.player.plugin.bitmovin.BitmovinVideoPlayerPlugin",
"",
"class PlayerViewActivity : ComponentActivity() {",
"",
" override fun onCreate(savedInstanceState: Bundle?) {",
" super.onCreate(savedInstanceState)",
"",
" val apiKey = \"API_KEY\"",
" val customUserAgent = \"okhttp/${okhttp3.OkHttp.VERSION}\"",
"",
" PlaybackSDKManager.updateCastContext(this)",
"",
" // Initialize SDK with the settings",
" PlaybackSDKManager.initialize(apiKey, userAgent = userAgentHeader) { license, error ->",
"",
" error?.let {",
" Log.e(this::class.simpleName, it.toString())",
" }",
"",
" val customPlugin = BitmovinVideoPlayerPlugin()",
" // Enable background playback",
" val playerConfig = VideoPlayerConfig()",
" playerConfig.playbackConfig.autoplayEnabled = true",
" playerConfig.playbackConfig.backgroundPlaybackEnabled = true",
" // Inject the player config to the plugin",
" customPlugin.setup(playerConfig)",
"",
" VideoPlayerPluginManager.registerPlugin(customPlugin)",
" }",
"",
" setContent {",
" val navController = rememberNavController()",
" PlaybackDemoAndroidTheme {",
" Surface(",
" modifier = Modifier.fillMaxSize(),",
" color = Color.White",
" ) {",
" PlayerContent(entryId = \"\", authorizationToken = \"\")",
" // Custom view to show player UI",
" PlayerContent(entryId = \"ENTRY ID\", authorizationToken = \"AUTH TOKEN or null or empty string\")",
" }",
" }",
" }",
" }",
"}",
"",
"var customPlugin: BitmovinVideoPlayerPlugin? = null",
"",
"@Composable",
"fun PlayerContent(entryId: String, authorizationToken: String) {",
" val apiKey = \"API_KEY\",",
" // Initialize SDK with the settings",
" PlaybackSDKManager.initialize(apiKey) { license, error ->",
" error?.let {",
" errorMessage = it.toString()",
" }",
" customPlugin = BitmovinVideoPlayerPlugin()",
" VideoPlayerPluginManager.registerPlugin(customPlugin!!)",
" }",

" val context = LocalContext.current",
" PlaybackSDKManager.updateCastContext(context)",

" if (authorizationToken.isEmpty()) {",
" playerLoaded = true",
" LaunchedEffect(Unit) {",
" playerLoaded = true",
" }",
" } else {",
" // Need to start the SSO before using the playback API",
" LaunchedEffect(Unit) {",
Expand All @@ -530,6 +558,7 @@
" }",
" }",
" }",

" if (playerLoaded) {",
" Box(",
" modifier = Modifier.fillMaxSize()",
Expand All @@ -540,7 +569,9 @@
" .aspectRatio(16f / 9f)",
" .align(Alignment.TopCenter)",
" ) {",
" loadPlayer(entryId, authorizationToken) { error ->",
" val viewerId = \"viewer id\"",
" ",
" PlaybackSDKManager.loadPlayer(entryId, viewerId, authorizationToken) { error ->",
" Log.e(\"PlayerActivity\", error.message.toString())",
" when (error) {",
" is PlaybackAPIError.ApiError -> {",
Expand Down Expand Up @@ -579,7 +610,6 @@
],
"syntax": "swift",
"fileType": "kotlin",
"highlights": [],
"fileName": "PlayerTestView.kt",
"type": "file"
},
Expand Down Expand Up @@ -618,37 +648,48 @@
"",
" override fun onCreate(savedInstanceState: Bundle?) {",
" super.onCreate(savedInstanceState)",
"",
" val apiKey = \"API_KEY\"",
"",
" PlaybackSDKManager.updateCastContext(this)",
"",
" // Initialize SDK with the settings",
" PlaybackSDKManager.initialize(apiKey) { license, error ->",
"",
" error?.let {",
" Log.e(this::class.simpleName, it.toString())",
" }",
"",
" val customPlugin = BitmovinVideoPlayerPlugin()",
" // Enable background playback",
" val playerConfig = VideoPlayerConfig()",
" playerConfig.playbackConfig.autoplayEnabled = true",
" playerConfig.playbackConfig.backgroundPlaybackEnabled = true",
" // Inject the player config to the plugin",
" customPlugin.setup(playerConfig)",
"",
" VideoPlayerPluginManager.registerPlugin(customPlugin)",
" }",
"",
" setContent {",
" val navController = rememberNavController()",
" PlaybackDemoAndroidTheme {",
" Surface(",
" modifier = Modifier.fillMaxSize(),",
" color = Color.White",
" ) {",
" PlayerContent(entryId = \"\", authorizationToken = \"\")",
" // Custom view to show player UI",
" PlayerContent(entryId = \"ENTRY ID\", authorizationToken = \"AUTH TOKEN or null or empty string\")",
" }",
" }",
" }",
" }",
"}",
"",
"var customPlugin: BitmovinVideoPlayerPlugin? = null",
"",
"@Composable",
"fun PlayerContent(entryId: String, authorizationToken: String) {",
" ",
" val apiKey = \"API_KEY\",",
"",
" // Initialize SDK with the settings",
" PlaybackSDKManager.initialize(apiKey) { license, error ->",
"",
" error?.let {",
" errorMessage = it.toString()",
" }",
"",
" customPlugin = BitmovinVideoPlayerPlugin()",
" VideoPlayerPluginManager.registerPlugin(customPlugin!!)",
" }",
" // Yours UI for the screen ",
"}"
]
},
Expand All @@ -657,22 +698,22 @@
"fileName": "PlayBackDemoAppWithUserAgent.kt",
"highlights": [
{
"line": 36
"line": 16
},
{
"line": 37
"line": 17
},
{
"line": 40
"line": 22
},
{
"line": 41
"line": 23
},
{
"line": 42
"line": 24
},
{
"line": 43
"line": 25
}
],
"identifier": "PlayBackDemoAppWithUserAgent.kt",
Expand All @@ -689,47 +730,55 @@
"import com.streamamg.player.plugin.VideoPlayerPluginManager",
"import com.streamamg.player.plugin.bitmovin.BitmovinVideoPlayerPlugin",
"",
"class PlayerViewActivity : ComponentActivity() {",
"",
" override fun onCreate(savedInstanceState: Bundle?) {",
" super.onCreate(savedInstanceState)",
"",
" val apiKey = \"API_KEY\"",
" // Should match the user agent of the HTTP client used in the app",
" val customUserAgent = \"okhttp/${okhttp3.OkHttp.VERSION}\"",
"",
" PlaybackSDKManager.updateCastContext(this)",
"",
" // Initialize SDK with the settings",
" PlaybackSDKManager.initialize(",
" apiKey = apiKey,",
" userAgent = userAgentHeader",
" ) { license, error ->",
"",
" error?.let {",
" Log.e(this::class.simpleName, it.toString())",
" }",
"",
" val customPlugin = BitmovinVideoPlayerPlugin()",
" // Enable background playback",
" val playerConfig = VideoPlayerConfig()",
" playerConfig.playbackConfig.autoplayEnabled = true",
" playerConfig.playbackConfig.backgroundPlaybackEnabled = true",
" // Inject the player config to the plugin",
" customPlugin.setup(playerConfig)",
"",
" VideoPlayerPluginManager.registerPlugin(customPlugin)",
" }",
"",
" setContent {",
" val navController = rememberNavController()",
" PlaybackDemoAndroidTheme {",
" Surface(",
" modifier = Modifier.fillMaxSize(),",
" color = Color.White",
" ) {",
" PlayerContent(entryId = \"\", authorizationToken = \"\")",
" // Custom view to show player UI",
" PlayerContent(entryId = \"ENTRY ID\", authorizationToken = \"AUTH TOKEN or null or empty string\")",
" }",
" }",
" }",
" }",
"}",
"",
"var customPlugin: BitmovinVideoPlayerPlugin? = null",
"",
"@Composable",
"fun PlayerContent(entryId: String, authorizationToken: String) {",
" ",
" val apiKey = \"API_KEY\",",
"",
" // Should match the user agent of the HTTP client used in the app",
" val customUserAgent = \"okhttp/${okhttp3.OkHttp.VERSION}\"",
"",
" // Initialize SDK with the settings",
" PlaybackSDKManager.initialize(",
" apiKey = apiKey,",
" userAgent = customUserAgent,",
" ) { license, error ->",
"",
" error?.let {",
" errorMessage = it.toString()",
" }",
"",
" customPlugin = BitmovinVideoPlayerPlugin()",
" VideoPlayerPluginManager.registerPlugin(customPlugin!!)",
" }",
" // Yours UI for the screen ",
"}"
]
},
Expand Down
3 changes: 3 additions & 0 deletions playback-sdk-android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ tasks.create<org.gradle.jvm.tasks.Jar>("releaseSourcesJar") {
dependencies {
implementation("androidx.compose.runtime:runtime:1.6.2")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.fragment:fragment-ktx:1.6.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.11.0")
implementation("androidx.compose.foundation:foundation-layout-android:1.6.2")
Expand All @@ -165,4 +166,6 @@ dependencies {
implementation("com.google.accompanist:accompanist-permissions:0.28.0")

testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0-RC")

implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.6")
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ object PlaybackSDKManager {

//region Private Properties

private lateinit var playBackAPI: PlaybackAPI
private var playBackAPI: PlaybackAPI? = null
private lateinit var playerInformationAPI: PlayerInformationAPI

private lateinit var amgAPIKey: String
Expand Down Expand Up @@ -164,15 +164,15 @@ object PlaybackSDKManager {
completion: (URL?, PlaybackAPIError?) -> Unit
) {
coroutineScope.launch(Dispatchers.IO) {
playBackAPI.getVideoDetails(entryId, authorizationToken, userAgent)
.catch { e ->
playBackAPI?.getVideoDetails(entryId, authorizationToken, userAgent)
?.catch { e ->
// Handle the PlaybackAPIError or any other Throwable as a PlaybackAPIError
when (e) {
is PlaybackAPIError -> completion(null, e)
else -> completion(null, PlaybackAPIError.NetworkError(e))
}
}
.collect { videoDetails ->
?.collect { videoDetails ->
// Successfully retrieved video details, now check for the HLS URL
val hlsURLString = videoDetails.media?.hls
if (!hlsURLString.isNullOrEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ data class VideoPlayerConfig(
@Serializable
data class PlaybackConfig(
var autoplayEnabled: Boolean = true,
var backgroundPlaybackEnabled: Boolean = true
var backgroundPlaybackEnabled: Boolean = true,
var fullscreenRotationEnabled: Boolean = true,
var fullscreenEnabled: Boolean = true
)
Loading

0 comments on commit 4849f7f

Please sign in to comment.