Lumen help

Legacy Integration for Kaltura Playkit on Android

Project setup

                repositories {
    maven {
        url 'https://sdk.streamroot.io/android'
    }
}
            
                implementation 'com.kaltura.playkit:dna-playkit:3.9.3'
implementation 'io.streamroot.dna:dna-core:3.23.0'
            
                android {
// Configure only for each module that uses Java 8
// language features (either in its source code or
// through dependencies).
compileOptions {
      sourceCompatibility JavaVersion.VERSION_1_8
      targetCompatibility JavaVersion.VERSION_1_8
  }
}

            

Integrate Lumen SDK

                <meta-data
        android:name="io.streamroot.dna.StreamrootKey"
        android:value="streamrootKey"/>

            
                private fun initStreamroot(newPlayer: ExoPlayer, loadControl: LoadControl): DnaClient? {
    var dnaClient: DnaClient? = null
    try {
        dnaClient = DnaClient.newBuilder()
            .context(applicationContext)
            .playerInteractor(ExoPlayerInteractor(newPlayer, loadControl, false))
            .streamrootKey(<String>)
            .latency(latency)
            .start(Uri.parse(mStreamUrl))

        streamStatsManager = StreamStatsManager.newStatsManager(dnaClient, streamrootDnaStatsView)
    } catch (e: Exception) {
        Toast.makeText(applicationContext, e.message, Toast.LENGTH_LONG).show()
    }

    return dnaClient
}

            
                mDnaClient.manifestUrl : <Uri>
            
                import android.os.Looperimport com.kaltura.playkit.Player
import io.streamroot.dna.core.PlayerInteractor
import io.streamroot.dna.core.TimeRange
import java.util.*

class PlayKitInteractor(
        player : Player
) : PlayerInteractor {
    private val mPlayer = player

    override fun looper(): Looper? = Looper.getMainLooper()

    override fun playbackTime() : Long {
        return mPlayer.currentPosition
    }

    override fun loadedTimeRanges(): List<TimeRange> {
        val currentPosition = mPlayer.currentPosition
        val bufferedPosition = mPlayer.bufferedPosition
        return Collections.singletonList(TimeRange(currentPosition, bufferedPosition))
    }

    override fun bufferTarget(): Double {
        return mPlayer.bufferTarget ?: 0.0
    }

    override fun setBufferTarget(target: Double) {
        mPlayer.bufferTarget = target
    }
}
            
                import com.kaltura.playlkit.Player
import io.streamroot.dna.core.BandwidthListener

class PlaykitBandwidthListener(
    player: Player
): BandwidthListener {
    private val mPlayer = player

    override fun onBandwidthChange(estimatedBandwidth: Long) {
        mPlayer.estimatedBandwidth = estimatedBandwidth
    }
}
            
                DnaClient dnaClient = DnaClient.newBuilder()
     .context(<Context>)
     .playerInteractor(PlayKitInteractor(mPlayer))
     ...

     .bandwidthListener(PlaykitBandwidthListener(mPlayer))

     ...
     .start(<String>);
            
                import com.kaltura.playkit.PKEvent
import com.kaltura.playkit.Player
import com.kaltura.playkit.PlayerEvent
import com.kaltura.playkit.PlayerState
import io.streamroot.dna.core.PlaybackState
import io.streamroot.dna.core.QosModule

class PlayKitQoSModule(
        player: Player
) : QosModule() {
    private val mPlayer = player
    private var mLastVideoBitrate: Long? = null
    private var mLastAudioBitrate: Long? = null
    private var currentPlayerState: PlayerState? = null

    init {
        // Register useful player events
        mPlayer.addEventListener((PKEvent.Listener<PlayerEvent.PlaybackInfoUpdated> {
            val playbackInfo = it.playbackInfo

            if (mLastVideoBitrate != playbackInfo.videoBitrate
                    || mLastAudioBitrate != playbackInfo.audioBitrate) {
                trackSwitchOccurred()
            }

            mLastVideoBitrate = playbackInfo.videoBitrate
            mLastAudioBitrate = playbackInfo.audioBitrate
        }), PlayerEvent.Type.PLAYBACK_INFO_UPDATED)

        mPlayer.addEventListener((PKEvent.Listener<PlayerEvent> {
            playbackStateChange(PlaybackState.ENDED)
        }), PlayerEvent.Type.ENDED)

        mPlayer.addStateChangeListener {
            val eventDetails = it as PlayerEvent.StateChanged

            when (eventDetails.newState) {
                PlayerState.IDLE -> {
                    playbackStateChange(PlaybackState.IDLE)
                }
                PlayerState.BUFFERING -> {
                    playbackStateChange(PlaybackState.BUFFERING)
                }
                PlayerState.READY -> {
                    when (mPlayer.isPlaying) {
                        true -> playbackStateChange(PlaybackState.PLAYING)
                        false -> playbackStateChange(PlaybackState.PAUSING)
                    }
                }
            }

            currentPlayerState = it.newState
        }
    }
}
            
                DnaClient dnaClient = DnaClient.newBuilder()
     .context(<Context>)
     .playerInteractor(PlayKitInteractor(mPlayer))
     ...

     .qosModule(PlayKitQoSModule(mPlayer))

     ...
     .start(<String>);
            
                mDnaClient.close();
            
                <?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <application
        ...
        android:usesCleartextTraffic="true">
        ...
    </application>
</manifest>
            
                <?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">localhost</domain>
    </domain-config>
</network-security-config>
            
                <?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config">
        ...
    </application>
</manifest>
            
                private void loadMedia() {

    new KalturaOvpMediaProvider(BASE_URL, PARTNER_ID, this.ks)
            .setEntryId(entryId)
            .load(response -> runOnUiThread(() -> {
                if (response.isSuccess()) {
                    // Find the preferred source format and replace it with DNA URL
                    PKMediaEntry mediaEntry = response.getResponse();
                    PKMediaFormat preferredFormat = ((PlayerSettings) player.getSettings()).getPreferredMediaFormat();

                    for (PKMediaSource source : mediaEntry.getSources()) {
                        if (source.getMediaFormat().name().equals(preferredFormat.name())) {
                            source.setUrl(loadStreamroot(source));
                            break;
                        }
                    }

                    // Update with entryId and KS
                    player.updatePluginConfig(KavaAnalyticsPlugin.factory.getName(), getKavaConfig());

                    player.getSettings().setAllowCrossProtocolRedirect(true);

                    player.prepare(new PKMediaConfig().setMediaEntry(mediaEntry));
                    player.play();  // Will play when ready

                    startStatsView();
                } else {
                    Toast.makeText(PlayerActivity.this, "Failed loading media: " + response.getError(), Toast.LENGTH_SHORT).show();
                }
            }));
}
            
                DnaClient dnaClient = DnaClient.newBuilder()
     .context(<Context>)
     .playerInteractor(PlayKitInteractor(mPlayer))
     ...

     .contentId(source.getId())

     ...
     .start(<String>);