From d9130824b5fed7d519a566e615a424ae87231029 Mon Sep 17 00:00:00 2001 From: Boris Borgobello Date: Fri, 20 Nov 2020 16:15:11 +0100 Subject: [PATCH 01/13] wip --- .../android/AllSamples/settings.gradle | 3 +- .../android/ExoPlayer-Yospace/.gitignore | 14 ++ .../android/ExoPlayer-Yospace/README.md | 18 ++ .../android/ExoPlayer-Yospace/app/.gitignore | 1 + .../ExoPlayer-Yospace/app/build.gradle | 51 ++++ .../ExoPlayer-Yospace/app/proguard-rules.pro | 21 ++ .../app/src/main/AndroidManifest.xml | 31 +++ .../exoplayer/ExoPlayerInteractor.kt | 43 ++++ .../orchestrator/exoplayer/MainActivity.kt | 30 +++ .../orchestrator/exoplayer/PlayerActivity.kt | 238 ++++++++++++++++++ .../orchestrator/exoplayer/SRApplication.kt | 12 + .../drawable-v24/ic_launcher_foreground.xml | 34 +++ .../res/drawable/ic_launcher_background.xml | 170 +++++++++++++ .../src/main/res/drawable/streamroot_logo.png | Bin 0 -> 43584 bytes .../app/src/main/res/layout/activity_main.xml | 121 +++++++++ .../src/main/res/layout/activity_player.xml | 11 + .../src/main/res/layout/content_player.xml | 35 +++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3056 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5024 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2096 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2858 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4569 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7098 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6464 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10676 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9250 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15523 bytes .../app/src/main/res/values/colors.xml | 6 + .../app/src/main/res/values/dimens.xml | 3 + .../app/src/main/res/values/strings.xml | 35 +++ .../app/src/main/res/values/styles.xml | 20 ++ .../main/res/xml/network_security_config.xml | 9 + .../android/ExoPlayer-Yospace/build.gradle | 28 +++ .../ExoPlayer-Yospace/gradle.properties | 15 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54708 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + .../android/ExoPlayer-Yospace/gradlew | 172 +++++++++++++ .../android/ExoPlayer-Yospace/gradlew.bat | 84 +++++++ .../android/ExoPlayer-Yospace/settings.gradle | 1 + 41 files changed, 1221 insertions(+), 1 deletion(-) create mode 100644 orchestrator/android/ExoPlayer-Yospace/.gitignore create mode 100644 orchestrator/android/ExoPlayer-Yospace/README.md create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/.gitignore create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/build.gradle create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/proguard-rules.pro create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/AndroidManifest.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/ExoPlayerInteractor.kt create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/MainActivity.kt create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/PlayerActivity.kt create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/SRApplication.kt create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable/streamroot_logo.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/layout/activity_main.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/layout/activity_player.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/layout/content_player.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/values/colors.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/values/dimens.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/values/strings.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/values/styles.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/app/src/main/res/xml/network_security_config.xml create mode 100644 orchestrator/android/ExoPlayer-Yospace/build.gradle create mode 100644 orchestrator/android/ExoPlayer-Yospace/gradle.properties create mode 100644 orchestrator/android/ExoPlayer-Yospace/gradle/wrapper/gradle-wrapper.jar create mode 100644 orchestrator/android/ExoPlayer-Yospace/gradle/wrapper/gradle-wrapper.properties create mode 100755 orchestrator/android/ExoPlayer-Yospace/gradlew create mode 100644 orchestrator/android/ExoPlayer-Yospace/gradlew.bat create mode 100644 orchestrator/android/ExoPlayer-Yospace/settings.gradle diff --git a/orchestrator/android/AllSamples/settings.gradle b/orchestrator/android/AllSamples/settings.gradle index 01fccca3..78fe4915 100644 --- a/orchestrator/android/AllSamples/settings.gradle +++ b/orchestrator/android/AllSamples/settings.gradle @@ -2,7 +2,8 @@ def samples = [ 'ExoPlayer', 'ExoPlayer-Java', - 'PRESTOplay-Java' + 'PRESTOplay-Java', + 'ExoPlayer-Yospace' ] samples.each { diff --git a/orchestrator/android/ExoPlayer-Yospace/.gitignore b/orchestrator/android/ExoPlayer-Yospace/.gitignore new file mode 100644 index 00000000..2ae72914 --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/.gitignore @@ -0,0 +1,14 @@ +*.iml +.gradle +/local.properties +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +.DS_Store +/build +/captures +.externalNativeBuild + +yoAdManagement-debug.aar +yoUtil-debug.aar +PlayerPolicyImpl.java \ No newline at end of file diff --git a/orchestrator/android/ExoPlayer-Yospace/README.md b/orchestrator/android/ExoPlayer-Yospace/README.md new file mode 100644 index 00000000..6319cd69 --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/README.md @@ -0,0 +1,18 @@ +# Streamroot Android Orchestrator ExoPlayer Kotlin + +## Common integration + +Make sure you start with the [common Kotlin integration](https://github.com/streamroot/streamroot-samples/blob/master/orchestrator/android/README_kotlin.md) + +## Specific integration override + +### 3. Bridge between your Player and the delivery client + +In order to work perfectly, the SDK instances need to interact with the player and listen to its events. +Please add the following class to your project : + +- [PlayerInteractor](https://github.com/streamroot/streamroot-samples/blob/master/orchestrator/android/ExoPlayer/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/ExoPlayerInteractor.kt) + +## Additional steps + +-> ExoPlayer requires targetCompatibility java 8. diff --git a/orchestrator/android/ExoPlayer-Yospace/app/.gitignore b/orchestrator/android/ExoPlayer-Yospace/app/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/orchestrator/android/ExoPlayer-Yospace/app/build.gradle b/orchestrator/android/ExoPlayer-Yospace/app/build.gradle new file mode 100644 index 00000000..abdacdc4 --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/app/build.gradle @@ -0,0 +1,51 @@ +//noinspection GradleCompatible +apply plugin: 'com.android.application' + +apply plugin: 'kotlin-android' + +apply plugin: 'kotlin-android-extensions' + +android { + compileSdkVersion 29 + defaultConfig { + applicationId "io.streamroot.lumen.delivery.client.samples.orchestrator.exoplayer" + minSdkVersion 19 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + multiDexEnabled true + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +repositories { + flatDir { + dirs 'libs' + } +} + +dependencies { + implementation 'com.google.android.exoplayer:exoplayer:2.11.7' + + def dc_version = '1.1.1' + implementation 'io.streamroot.lumen.delivery.client:orchestrator-sdk:' + dc_version + implementation 'io.streamroot.lumen.delivery.client:orchestrator-sdk-utils:' + dc_version + + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.0-rc1' + + implementation(name: 'yoAdManagement-debug', ext: 'aar') + implementation(name: 'yoUtil-debug', ext: 'aar') +} diff --git a/orchestrator/android/ExoPlayer-Yospace/app/proguard-rules.pro b/orchestrator/android/ExoPlayer-Yospace/app/proguard-rules.pro new file mode 100644 index 00000000..f1b42451 --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/orchestrator/android/ExoPlayer-Yospace/app/src/main/AndroidManifest.xml b/orchestrator/android/ExoPlayer-Yospace/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..9bfd57ff --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/app/src/main/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/ExoPlayerInteractor.kt b/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/ExoPlayerInteractor.kt new file mode 100644 index 00000000..89bea9b6 --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/ExoPlayerInteractor.kt @@ -0,0 +1,43 @@ +package io.streamroot.lumen.delivery.client.samples.orchestrator.exoplayer + +import com.google.android.exoplayer2.ExoPlaybackException +import com.google.android.exoplayer2.ExoPlayer +import com.google.android.exoplayer2.PlaybackParameters +import com.google.android.exoplayer2.Player +import com.google.android.exoplayer2.source.TrackGroupArray +import com.google.android.exoplayer2.trackselection.TrackSelectionArray +import io.streamroot.lumen.delivery.client.core.* + +class ExoPlayerInteractor(player: ExoPlayer) : LumenPlayerInteractorBase(), Player.EventListener { + + init { player.addListener(this) } + + override fun onSeekProcessed() { + super.playerStateChange(LumenVideoPlaybackState.SEEKING) + } + + override fun onTracksChanged(trackGroups: TrackGroupArray, trackSelections: TrackSelectionArray) { + super.playerTrackSwitch() + } + + override fun onPlayerError(error: ExoPlaybackException) { + super.playerError() + } + + override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) { + when (playbackState) { + Player.STATE_IDLE -> { + super.playerStateChange(LumenVideoPlaybackState.IDLE) + } + Player.STATE_BUFFERING -> { + super.playerStateChange(LumenVideoPlaybackState.REBUFFERING) + } + Player.STATE_READY -> { + super.playerStateChange(if (playWhenReady) LumenVideoPlaybackState.PLAYING else LumenVideoPlaybackState.PAUSED) + } + Player.STATE_ENDED -> { + super.playerStateChange(LumenVideoPlaybackState.ENDED) + } + } + } +} diff --git a/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/MainActivity.kt b/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/MainActivity.kt new file mode 100644 index 00000000..504a743a --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/MainActivity.kt @@ -0,0 +1,30 @@ +package io.streamroot.lumen.delivery.client.samples.orchestrator.exoplayer + +import android.content.Intent +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import kotlinx.android.synthetic.main.activity_main.* + +class MainActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + launchButton.setOnClickListener { + if (streamEditText.text.isBlank()) return@setOnClickListener + PlayerActivity.makeIntent(this, + PlayerActivity.PlayerActivityArgs( + dcKeyET.text.toString(), + streamEditText.text.toString(), + orchPropET.text.toString() + ) + ).apply { + addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + }.run { + startActivity(this) + } + } + } +} diff --git a/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/PlayerActivity.kt b/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/PlayerActivity.kt new file mode 100644 index 00000000..e43b667c --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/PlayerActivity.kt @@ -0,0 +1,238 @@ +package io.streamroot.lumen.delivery.client.samples.orchestrator.exoplayer + +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import com.google.android.exoplayer2.C +import com.google.android.exoplayer2.ExoPlaybackException +import com.google.android.exoplayer2.ExoPlayer +import com.google.android.exoplayer2.PlaybackParameters +import com.google.android.exoplayer2.Player +import com.google.android.exoplayer2.SimpleExoPlayer +import com.google.android.exoplayer2.Timeline +import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer +import com.google.android.exoplayer2.mediacodec.MediaCodecUtil +import com.google.android.exoplayer2.source.LoopingMediaSource +import com.google.android.exoplayer2.source.MediaSource +import com.google.android.exoplayer2.source.TrackGroupArray +import com.google.android.exoplayer2.source.dash.DashMediaSource +import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource +import com.google.android.exoplayer2.source.hls.HlsMediaSource +import com.google.android.exoplayer2.trackselection.TrackSelectionArray +import com.google.android.exoplayer2.ui.PlayerView +import com.google.android.exoplayer2.upstream.DefaultHttpDataSource +import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory +import com.google.android.exoplayer2.util.Util +import io.streamroot.lumen.delivery.client.core.LumenDeliveryClient +import io.streamroot.lumen.delivery.client.core.LumenLogLevel +import io.streamroot.lumen.delivery.client.utils.LumenStatsView + +class PlayerActivity : AppCompatActivity(), Player.EventListener { + data class PlayerActivityArgs( + val dcKey: String?, + val url: String?, + val orchProperty: String? + ) + + companion object { + private const val ARG_DC_KEY = "dcKey" + private const val ARG_STREAM_URL = "streamUrl" + private const val ARG_ORCH_PROP = "orchestratorProperty" + + fun makeIntent(ctx: Context, args: PlayerActivityArgs) : Intent { + return Intent(ctx, PlayerActivity::class.java).apply { + putExtra(ARG_STREAM_URL, args.url) + putExtra(ARG_ORCH_PROP, args.orchProperty) + putExtra(ARG_DC_KEY, args.dcKey) + } + } + fun extractArgs(i: Intent) : PlayerActivityArgs { + return PlayerActivityArgs( + i.getStringExtra(ARG_DC_KEY), + i.getStringExtra(ARG_STREAM_URL), + i.getStringExtra(ARG_ORCH_PROP) + ) + } + } + + private lateinit var exoPlayerView: PlayerView + private lateinit var dcStatsView: LumenStatsView + + private var mDCKey: String? = null + private var mStreamUrl: String? = null + private var mOrchProperty: String? = null + + private var player: ExoPlayer? = null + + private var deliveryClient: LumenDeliveryClient? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_player) + + val args = extractArgs(intent) + mStreamUrl = args.url + mDCKey = args.dcKey?.takeUnless { it.isBlank() } + mOrchProperty = args.orchProperty?.takeUnless { it.isBlank() } + + exoPlayerView = findViewById(R.id.exoplayerView) + dcStatsView = findViewById(R.id.dcStatsView) + } + + override fun onStart() { + super.onStart() + + if (Util.SDK_INT > 23) { + initPlayer() + } + } + + override fun onResume() { + super.onResume() + + if (Util.SDK_INT <= 23 || player == null) { + initPlayer() + } + } + + override fun onPause() { + super.onPause() + if (Util.SDK_INT <= 23) { + releasePlayer() + } + } + + override fun onStop() { + super.onStop() + if (Util.SDK_INT > 23) { + releasePlayer() + } + } + + private fun initPlayer() { + if (player == null) { + val newPlayer = SimpleExoPlayer.Builder(applicationContext).build() + + newPlayer.playWhenReady = true + newPlayer.addListener(this) + + initDeliveryClient(newPlayer).let { dc -> + deliveryClient = dc + + dc.addStateStatsListener(dcStatsView) + dcStatsView.showStats() + dc.start() + + val uri = Uri.parse(dc.localUrl()) + newPlayer.prepare(LoopingMediaSource(buildMediaSource(uri)), true, false) + } + + player = newPlayer + exoPlayerView.player = newPlayer + } + } + + private fun releasePlayer() { + player?.release() + player = null + + stopDeliveryClient() + } + + @SuppressLint("SwitchIntDef") + private fun buildMediaSource(uri: Uri): MediaSource { + val defaultDataSourceFactory = + DefaultHttpDataSourceFactory( + Util.getUserAgent(applicationContext, "StreamrootQA"), + DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS, + DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, + true + ) + + return when (Util.inferContentType(uri)) { + C.TYPE_HLS -> HlsMediaSource.Factory(defaultDataSourceFactory) + //.setDrmSessionManager() + .createMediaSource(uri) + C.TYPE_DASH -> DashMediaSource.Factory( + DefaultDashChunkSource.Factory( + defaultDataSourceFactory + ), defaultDataSourceFactory + ) + //.setDrmSessionManager() + .createMediaSource(uri) + else -> { + throw IllegalStateException("Unsupported type for url: $uri") + } + } + } + + private fun initDeliveryClient(newPlayer: SimpleExoPlayer) = + LumenDeliveryClient.orchestratorBuilder(applicationContext) + .playerInteractor(ExoPlayerInteractor(newPlayer)) + .options { + mDCKey?.let { deliveryClientKey(it) } + mOrchProperty?.let { orchestratorProperty(it) } + logLevel(LumenLogLevel.TRACE) + } + .build(mStreamUrl!!) + + + private fun stopDeliveryClient() { + deliveryClient?.terminate() + deliveryClient = null + } + + /** + * Utils + */ + + private fun showToast(message: String) { + Toast.makeText(applicationContext, message, Toast.LENGTH_LONG).show() + } + + /** + * Player EventListener + */ + + override fun onPlayerError(error: ExoPlaybackException) { + var errorString: String? = null + if (error.type == ExoPlaybackException.TYPE_RENDERER) { + val cause = error.rendererException + if (cause is MediaCodecRenderer.DecoderInitializationException) { + // Special case for decoder initialization failures. + val codecInfo = cause.codecInfo + errorString = when { + codecInfo != null -> getString( + R.string.error_instantiating_decoder, + codecInfo.name + ) + cause.cause is MediaCodecUtil.DecoderQueryException -> getString(R.string.error_querying_decoders) + cause.secureDecoderRequired -> getString( + R.string.error_no_secure_decoder, + cause.mimeType + ) + else -> getString(R.string.error_no_decoder, cause.mimeType) + } + } + } + + if (errorString != null) { + showToast(errorString) + } + } + + override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters) {} + override fun onSeekProcessed() {} + override fun onTracksChanged(trackGroups: TrackGroupArray, trackSelections: TrackSelectionArray) {} + + override fun onLoadingChanged(isLoading: Boolean) {} + override fun onPositionDiscontinuity(reason: Int) {} + override fun onRepeatModeChanged(repeatMode: Int) {} + override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {} + override fun onTimelineChanged(timeline: Timeline, manifest: Any?, reason: Int) {} + override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {} +} \ No newline at end of file diff --git a/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/SRApplication.kt b/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/SRApplication.kt new file mode 100644 index 00000000..e46c23b5 --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/app/src/main/java/io/streamroot/lumen/delivery/client/samples/orchestrator/exoplayer/SRApplication.kt @@ -0,0 +1,12 @@ +package io.streamroot.lumen.delivery.client.samples.orchestrator.exoplayer + +import androidx.multidex.MultiDexApplication +import io.streamroot.lumen.delivery.client.core.LumenDeliveryClient + +class SRApplication: MultiDexApplication() { + + override fun onCreate() { + super.onCreate() + LumenDeliveryClient.initializeApp(this) + } +} \ No newline at end of file diff --git a/orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 00000000..c7bd21db --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable/ic_launcher_background.xml b/orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..d5fccc53 --- /dev/null +++ b/orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable/streamroot_logo.png b/orchestrator/android/ExoPlayer-Yospace/app/src/main/res/drawable/streamroot_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..33cc7499f23adf2e7871502348bc15a0ff518ad4 GIT binary patch literal 43584 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +