Skip to content

sportradar/SR_AVVPlayer_Android

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AVVPlayer-MARVIN-Android

Links

Developer Guide

Basic Integration

Adding AVVPL to your project

1. Add the maven repository to your project level build.gradle

allprojects {
    repositories {
        ...
        maven { url "https://avvpl-staging.sportradar.com/dist/android/latest/" }
        maven { url 'http://bitmovin.bintray.com/maven' }
        ...
    }
}

KNOWN ISSUE: Bitmovin Analytics integration demands adding the bitmovin maven repository. Fixing this issue is in progress.

2. Add the avvpl dependency to your app module build.gradle

implementation("ag.sportradar.android:avvplayermarvin:X.X.X")

The newest Version can be found here

Checking for a valid licence

    val licence = AVVLicence.Builder(this, "[your_licence_key]")
                .domain("[www.yourlicencedomain.com]") //if required
                .bundle("[com.your.appid]") //optional: it will pick the applictiationId per default 
                .listener(object : AVVLicenceCheckListener {
                    override fun onLicenceValidated(valid: Boolean) {
                        // player should not be built before licence is validated.
                    }
                })
                .build()

    AVVSettings.instance.checkLicence(licence)

Creating the AVVPlayer instance

1. Instantiate the Player

val player = AVVPlayerBuilder(context) //your Activity's context
            .setPlayerContainer(playerContainer) //the viewgroup that contains the player
            .build()

2. Start the video passing a video configuration to the player

player.setup(AVVConfigUrl("[URL to the OTT videoconfig]"))

or

player.setup(AVVStreamUrl("https://cdn.theoplayer.com/video/elephants-dream/playlist.m3u8"))

or

player.setup(AVVConfig.Builder(0)
                    .streamUrl("https://cdn.theoplayer.com/video/elephants-dream/playlist.m3u8")
                    .build())

Handle lifecycle events

The AVVPlayer instance needs to react to certain lifecycle events of the application, such as onPause(), onResume() and onDestroy().

class MainActivity : AppCompatActivity() {
    override fun onPause() {
        player.onActivityPause()
        super.onPause()
    }
 
    override fun onResume() {
        player.onActivityResume()
        super.onResume()
    }
 
    override fun onDestroy() {
        player.onActivityDestroy()
        super.onDestroy()
    }
}

POSSIBLE ISSUE: player.onActivityDestroy() calls Exoplayers stop() and release() method. As release() is known for blocking the UI Thread until all resources are released,some devices (especially lowend devices) might appear to freeze for 1-3 seconds. If you are experiencing these issues try calling

player.onActivityDestroy(killPlaybackThread = false)

instead.

Handle orientation change

In order for the AVVPlayer to continue playback through orientation changes you need to enable configChanges in the Activity that holds the player.

1. Add the following line to your activity in the AndroidManifest.xml

<activity 
    android:name=".YourPlayerActivity"
    android:configChanges="orientation|screenSize|screenLayout">
    ... 
</activity>

2. Override onConfigurationChanged in your Activity/Fragment that holds the player

override fun onConfigurationChanged(newConfig: Configuration) {
        player.onConfigurationChanged(newConfig)
        super.onConfigurationChanged(newConfig)
    }

Changing the player configuration (if required)

The player fetches its configuration from the URL that is passed in the setUp() call. The configuration determines the looks and the behavior of the player, however if you wish to change any of this behavior or need to add necessary information to the player configuration you can do so by implementing AVVConfigAdaptationCallback and adding it to the player.setup() call

player.setup(config, object : AVVConfigAdaptationCallback() {})
  • Adding request headers to streamaccess
player.setUp(config, object : AVVConfigAdaptationCallback() {
            override fun adaptConfig(config: AVVConfig) {
                //...
                config.streamUrlProviderInfo.requestData = AVVPostRequestData(mapOf(Pair("authorization", "your auth token")))
                //...
            }
})
  • Changing autoplay behavior
player.setUp(config, object : AVVConfigAdaptationCallback() {
             
            override fun adaptConfig(config: AVVConfig) {
                //...
                config.playbackOptions.autoPlay = true
                //...
            }
             
        })
  • Add heartbeat
player.setUp(config, object : AVVConfigAdaptationCallback() {
             
            override fun adaptConfig(config: AVVConfig) {
                //...
                config.heartbeat = AVVHeartbeat.Builder()
                    .enabled(true)
                    .time(30) //seconds
                    .ticket("[your heartbeat ticket]")
                    .validationPath("https://yourvalidation.com/validation")
                    .build()
                    
                 //...
            }
             
        })

Customizing UI

Customize Error Overlay

class MyErrorOverlay : AVVErrorOverlayDelegate {
    override fun onCreateErrorView(parent: ViewGroup, error: AVVError): View {
        val layoutInflater = LayoutInflater.from(parent.context)
        val view = layoutInflater.inflate(R.layout.my_error_layout, parent, false)
 
        // display the error data contained in the AVVError as you like.
        return view
    }
}
val player = AVVPlayerBuilder(activity)
            .setPlayerContainer(playerContainer)
            .setCustomErrorOverlay(MyErrorOverlay())
            .build()

Customize Control Overlay

class MyCustomControls : AVVControlOverlayDelegate {
    override fun onCreateErrorView(parent: ViewGroup, error: AVVError): View {
        val layoutInflater = LayoutInflater.from(parent.context)
        val view = layoutInflater.inflate(R.layout.layout_videoplayer_controls, parent, false)
 
         controlBinding.bindPlayPauseButton(
            view.findViewById(R.id.playPauseButton),
            R.drawable.ic_avv_play,
            R.drawable.ic_avv_pause, config.skin
        )

        controlBinding.bindFullscreenButton(
            view.findViewById(R.id.fullscreenButton),
            R.drawable.ic_avv_fullscreen_enter,
            R.drawable.ic_avv_fullscreen_exit
        )

        controlBinding.bindLiveIndicatorView(
            view.findViewById(R.id.liveindicator),
            R.drawable.ic_avv_live_indicator,
            config.skin
        )
 
        // for more bindings check MyCustomControls.kt in DemoApplication
        return view
    }
}
val player = AVVPlayerBuilder(activity)
            .setPlayerContainer(playerContainer)
            .setControlOverlay(MyCustomControls())
            .build()

Chromecast

Create CastOptionsProvider

class DemoCastOptionsProvider: AVVCastOptionsProvider() {
    override fun getReceiverApplicationId(context: Context): String {
        return "YOUR_CAST_RECEIVER_ID"
    }
}

Add the CastOptionsProvider to your AndroidManifest.xml

    <application>
        <meta-data
            android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
            android:value="path.to.your.AVVCastOptionsProvider"
            tools:replace="android:value" />
 
    </application>

Initiate CastContext

    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
        //...
        CastContext.getSharedInstance(this)
        //...
    }
    }

(Optional) Add a MiniController to your layout

    <fragment
        android:id="@+id/miniControllerFragment"
        class="ag.sportradar.avvplayer.player.chromecast.widgets.AVVDefaultCastMiniController"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages