Skip to main content

LORA Short Video

LORA Short Video is an external LORA SDK module that can be used independently.

Features

  • Video Grid View
  • Video Carousel View
  • Video Story Block View
  • Video Detail Player (with landscape layout support)
  • Playlist
  • PiP

Getting started

Project setup

The Short Video module requires a LORA core module, LORA common module, and other third-party libraries to function properly.

In your build.gradle dependencies:

    // sdk aar files & required dependencies
implementation (name:'lora-core-release', ext:'aar')
implementation (name:'lora-common-release', ext:'aar')
implementation (name:'lora-shortvideo-release', ext:'aar')
implementation 'io.insert-koin:koin-android:3.4.0'
implementation 'androidx.media3:media3-exoplayer:1.0.2'
implementation 'androidx.media3:media3-ui:1.0.2'
implementation 'androidx.media3:media3-exoplayer-hls:1.0.2'
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.9.0"
implementation 'com.github.bumptech.glide:glide:4.15.1'
kapt 'com.github.bumptech.glide:compiler:4.15.1'

Initialize the SDK

The LORA SDK requires a license key for initialization. Please contact us for information about this key.

Use the following code to initialize the SDK. You can place it in the onCreate of the main screen or in the application class.

val loraSdkProvider = LoraSdkProvider(context)
loraSdkProvider.init(LICENSE_KEY)

ShortVideoView

ShortVideoView is a UI entry point designed to display a list of videos in various layout types such as grid, carousel, and story block.
When a video item is clicked, it opens the main player and plays the selected video.

Adding a ShortVideoView is as simple as adding a normal Android View.

<sg.belive.lib.shortvideo.view.ShortVideoView
android:id="@+id/short_video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

ShortVideoView loads video data from a Video Source defined by a View Config. This View Config defines the layout type and provides customization for the UI, as well as controls for basic player behaviors.

Grid layout

The grid layout displays videos vertically.

val cfBuilder = ViewConfig.Builder(this) // `this` is a context
// set the video source (SingleVideoSource, PlaylistVideoSource)
cfBuilder.videoSource(source)
val loCf = ShortVideoGridLayout.createDefaultConfig(this)
cfBuilder.layoutConfig(loCf)
shortVideoView.init(cfBuilder.build())

You can change the Grid span count (default value is 3):

val loCf = ShortVideoGridLayout.createDefaultConfig(this)
loCf.numberOfColumns = 2

Player behavior configuration:

val playerCf = PlayerItemConfiguration().apply {
enableAutoPlay()
actionOnCompleted = PlayerCompleteAction.STOP
}
cfBuilder.playerConfig(playerCf)

And other attributes:

  • Item background color
  • Spacing between items

Grid Item

For Grid items, you can customize the following UI components/attributes:

  • Item width and height ratio (recommended to use a portrait ratio)
  • Video title text view
  • Play button (set to null to hide)
  • Item's corner radius
  • Video thumbnail scale mode
val gridLoCf = ShortVideoGridLayout.createDefaultConfig(this)
gridLoCf.ratio = "9:16"
gridLoCf.itemConfiguration?.let { cf ->
cf.title = TitleConfiguration().apply {
this.color = ContextCompat.getColor(context, R.color.bls_sv_video_item_title_color)
this.backgroundRes = R.drawable.bls_sv_bg_carousel_video_item_title
this.textSize =
context.resources.getDimension(R.dimen.bls_sv_video_item_title_size)
this.font = Typeface.DEFAULT
this.gravity = Gravity.START or Gravity.CENTER_VERTICAL
}
cf.playButton = ButtonViewItemConfiguration().apply {
this.onStateIconRes = R.drawable.ic_play
}
cf.cornerRadius = 10F
cf.imageScaleMode = ImageView.ScaleType.CENTER
}

The Carousel layout displays videos horizontally in a single row.

val cfBuilder = ViewConfig.Builder(this) // `this` is a context
cfBuilder.videoSource(source)
val carouselLoCf = ShortVideoCarouselLayout.createDefaultConfig(this)
cfBuilder.layoutConfig(carouselLoCf)
shortVideoView.init(cfBuilder.build())

Some attributes that can be customized include:

  • Item background color
  • Spacing between items

For Carousel items, you can customize the following UI components/attributes:

  • Video title text view (the layoutGravity attr is ignored)
  • Item's corner radius
  • Progress bar
  • Play/pause, mute button
  • Video thumbnail scale mode
  • Video scale mode
val loCf = ShortVideoCarouselLayout.createDefaultConfig(this)
loCf.itemConfiguration?.let { cf ->
cf.videoScaleMode = BlsPlayerScaleMode.DEFAULT
}

Supported video scale modes:

Scale modeDescription
DEFAULTThe SDK will choose the best scale mode bases on video/device orientation. This is the default value and it is recommended to use this mode.
FITMake the video fit the view and keep the ratio in at least 1 dimension (width or height)
FILLZoom the video and do not keep the ratio to fit the view in both width and height
FIXED_WIDTHMake the video fit the view width and keep the ratio
FIXED_HEIGHTMake the video fit the view height and keep the ratio
ZOOMZoom the video and keep the ratio to fit the view in both width and height

Story Block layout

Similar to the Carousel layout, the Story Block layout displays videos horizontally, but only one video is visible at a time.

val cfBuilder = ViewConfig.Builder(this) // `this` is a context
cfBuilder.videoSource(source)
val storyBlockLoCf = ShortVideoStoryBlockLayout.createDefaultConfig(this)
cfBuilder.layoutConfig(storyBlockLoCf)
shortVideoView.init(cfBuilder.build())

You have the ability to disable scrolling and customize the next/previous buttons. Below are the attributes available for customization:

  • Enable/Disable scrolling
  • Container background color
  • Item background color
  • Previous button (set to null to hide)
  • Next button (set to null to hide)

Story Block Item

For Story Block items, you can customize the following UI components/attributes:

  • Video title text view (the layoutGravity attr is ignored)
  • Item's corner radius
  • Progress bar
  • Play/pause, mute, full screen, share button
  • Video thumbnail scale mode
  • Video scale mode
  • Product item view

Starting from LORA SDK 1.1.0, this layout type can display overlay data, including product lists, polls, and Q&A. For more information about overlay data, please refer to the Detail Player below.

Detail player

The Short Video module provides a detail player as an internal screen (activity) that opens when clicking on a video item. This screen includes a video player with various functions and an overlay data detail. You can navigate between items by swipe up and down gestures or using navigation buttons. The UI and player behavior can be configured when setting up the Grid, Carousel, or Story Block layout.

val gridCfBuilder = ViewConfig.Builder(this)
// Create the detail view config
val detailCfBuilder = DetailViewConfig.Builder(this)
detailCfBuilder.layoutConfig(ShortVideoDetailLayout.createDefaultConfig(this))
detailCfBuilder.playerConfig(PlayerItemConfiguration())
// Set the detail view config
gridCfBuilder.detailViewConfig(detailCfBuilder.build())
shortVideoView.init(gridCfBuilder.build())

The following attributes can be adjusted:

  • Enable/Disable scrolling
  • Item background color
  • Previous button (set to null to hide)
  • Next button (set to null to hide)

Detail Item

For detail items, you can customize the following UI components/attributes:

  • Video title, duration text view (the layoutGravity attr is ignored)
  • Item's corner radius
  • Seek bar
  • Play/pause, mute, pip, share, close button
  • Video thumbnail scale mode
  • Video scale mode
  • Product item view.

Product list

A list of products can be attached to a video item, displayed in the main player. Each product item might contain a Shop CTA button that opens the product URL in an external browser (this behavior can be overridden). The product item UI can also be customized.

For product item layout, you can customize the below UI components/attrs:

  • Product title text view (the layoutGravity attr is ignored)
  • Item's corner radius/background
  • Shop CTA text color and icon resource.
  • Shop CTA text content. If set, it will override the remote value.
  • Product thumbnail scale mode

Q&A item

A Q&A can be attached to a video item and displayed in the detail. Each Q&A item contains a Call to Action (CTA) button that submits an answer. The Q&A item UI can also be customized:

For Q&A item layout, you can customize the below UI components/attrs:

  • CTA button: Text Color, Background Color. Other UI components color will be generated from this CTA button colors

Poll item

A Poll can be attached to a video item and displayed in the detail. Each Poll item contains a Call to Action (CTA) button that submits an option. The Poll item UI can also be customized:

For Poll item layout, you can customize the below UI components/attrs:

  • CTA button: Text Color, Background Color. Other UI components color will be generated from this CTA button colors

Landscape layout

By default, the detail player renders the UI according to the orientation of the current user's device. The SDK smoothly transitions between orientation modes, switching from portrait to landscape and vice versa without interrupting the player. However, you can also enforce a fixed orientation (portrait or landscape) using the SDK.

val detailLoCf = ShortVideoDetailLayout.createDefaultConfig(this)
detailLoCf.orientationMode = ShortVideoDetailLayout.OrientationMode.LANDSCAPE

Supported orientation modes

  • AUTO: Automatically adjust the orientation based on the device's orientation.
  • LANDSCAPE: Enforce a landscape orientation.
  • PORTRAIT: Enforce a portrait orientation.

Picture in Picture (PiP)

The detail player supports playing a video in Picture in Picture (PiP) mode on devices that support PiP (Android 8+). You can disable this feature by hiding the PiP button. When a video is playing in this mode, it will always loop regardless of the player completion action.

Player behaviors

Auto play

This auto play flag causes a video to play when it becomes visible on the screen. If there are multiple visible videos, the first video will be played. The default value is true.

val playerCf = PlayerItemConfiguration().apply {
enableAutoPlay()
//
disableAutoPlay()
}

Player complete action

You can control the behavior when the player finishes playback.

val playerCf = PlayerItemConfiguration().apply {
actionOnCompleted = PlayerCompleteAction.STOP
}

Supported Actions:

ActionDescription
STOPThe player will always stop the video after playing it.
REPEATThe player will always loop the current video.
PLAY_NEXT_ITEMThe player will always play the next video in the list after playing the current video. If the current video is the last item, the player will stop playing. This is the default value.
PLAY_NEXT_ITEM_AND_LOOPThe player will always play the next video in the list after playing the current video. If the current video is the last item, the player will play the first item in the list. This behavior is same as the Loop from start setting at the CMS.

Video source

Playlist

The playlist video source fetches all available videos from a specific playlist by its ID. To create a playlist source, use the following API:

ShortVideoSource.playlist(playlistAlias, maxVideoItemsCount)

Setting a maxVideoItemsCount greater than 0 will limit the number of videos to load.

Single

The single video source fetches a single video by its video ID. To create a single source, use the following API:

ShortVideoSource.singleVideo(videoId)

Play and pause

You can pause and resume the video by calling the following APIs:

shortVideoView.pause()
//
shortVideoView.play()

Listeners

Error listener

When an error occurs, the Short Video module triggers an error callback with a code and a message. To listen to errors, set a BlsShortVideoErrorListener to the ShortVideoView.

shortVideoView.setErrorListener(object : BlsShortVideoErrorListener {
override fun onShortVideoError(code: Int, msg: String?) {
}
})

The error code can be found in the BlsShortVideoErrorCode.

Video item click listener

When a user clicks on a video item, it opens the main player and triggers a callback.

shortVideoView.setVideoItemClickedListener(object : BlsShortVideoItemClickListener {
override fun onShortVideoItemClicked(videoId: String) {
}

})

The implementation of the listener mainly serves analytics purposes and does not affect the flow.

Detail player action listener

This listener is different from other listeners as it's bound to a singleton handler. To avoid memory leaks, avoid implementing this interface as an anonymous class in the activity context. Instead, create a class and implement the interface.

class MainPlayerAction : BlsShortVideoMainPlayerActionListener {
override fun onProductItemClicked(
context: Context, item: ShortVideoProductModel
): Boolean {
context.openBrowser(item.productUrl.orEmpty())
return true
}

override fun onShareVideo(context: Context, videoId: String): Boolean {
context.shareText(videoId)
return true
}

override fun onSubmitPollError(context: Context, errorCode: Int) {
}

override fun onSubmitDefaultAnswerError(context: Context, errorCode: Int) {
}

override fun onSubmitFollowupAnswerError(context: Context, errorCode: Int) {
}
}

The onProductItemClicked method is triggered when a shop CTA button is clicked. Returning true in this method consumes the event and stops the flow. If false is returned, the SDK continues to handle the event.

The onShareVideo method is triggered when a share button is clicked (in both Carousel and Main player). Returning true consumes the event and stops the flow. If false is returned, the SDK continues to handle the event, and the default behavior is to open the system share dialog.

The onSubmitPollError method is triggered when submitting a poll option fails.

The onSubmitDefaultAnswerError method is triggered when submitting a default answer fails.

The onSubmitFollowupAnswerError method is triggered when submitting a follow-up answer fails.