How to use Exoplayer in Adapter/RecyclerView - android

This is my code that I wrote but when I click button to initialize ExpoPlayer it doesn't work.
private fun initializeExoplayer(){
simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(
DefaultRenderersFactory(context),
DefaultTrackSelector(adaptiveTrackSelectionFactory)
)
simpleExoPlayer.prepare(buildMediaSource())
itemView.simpleExoPlayerView.player = simpleExoPlayer
simpleExoPlayer.seekTo(playbackPosition)
simpleExoPlayer.playWhenReady = true
simpleExoPlayer.addListener(this)
}
private fun buildMediaSource(): MediaSource {
var uri: Uri = Uri.parse("https://player.vimeo.com/external/357507131.m3u8?s=17a1326569611e13080cbe99344549fcc6b5613d")
val dataSourceFactory: DataSource.Factory = DefaultHttpDataSourceFactory(Util.getUserAgent(context,"App Name"))
return HlsMediaSource.Factory(dataSourceFactory).createMediaSource(uri)
}
I've tried with above code but it does't work anyone can help me for this issue???

Related

using ExoPlayer with kotlin

I want to use ExoPlayer using kotlin, I saw code for that but my compiler can't recognize 'buildRenderersFactory' reference.
Can someone help?
I'm using android studio
and implement:
def exoPlayerVersion = "2.9.0"
implementation "com.google.android.exoplayer:exoplayer:$exoPlayerVersion"
private val defaultBandwidthMeter = DefaultBandwidthMeter.Builder(context).build()
private val dataSourceFactory: DefaultDataSourceFactory
private val extractorsFactory = DefaultExtractorsFactory()
private val renderersFactory = buildRenderersFactory(useExtensionRenderers = true, preferExtensionRenderer = true)
val exoPlayer :SimpleExoPlayer = ExoPlayerFactory.newSimpleInstance(context, renderersFactory, DefaultTrackSelector(), DefaultLoadControl())
val dataSourceFactory = DefaultDataSourceFactory(context, defaultBandwidthMeter, DefaultHttpDataSourceFactory(Util.getUserAgent(context, "MKDPlayer"), defaultBandwidthMeter))
val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory,extractorsFactory)
.setCustomCacheKey("ExoPlayerAdapter")
.createMediaSource(uri)
exoPlayer.prepare(mediaSource)
As Usama Altaf send me a link. The solution is using DefaultRenderersFactory constuctor.
so now it looks that way:
val renderersFactory = DefaultRenderersFactory(context)

Small laggy when prepare exoplayer

In my application, I had an infinite animation. Actually, it's a TextSwitcher animation running from left to right. However, whenever I tried to prepare the player, I got a jitter issue with the text's animation. Although it's just a few milliseconds, it caused my texts was like jumping from left to right. Here's the prepare video method:
private fun prepareVideo(uri: Uri): SimpleExoPlayer? {
val simpleExoPlayer = SimpleExoPlayer
.Builder(this) // .setLoadControl(defaultLoadControl)
.build()
val mediaItem = MediaItem.fromUri(uri)
simpleExoPlayer.setMediaItem(mediaItem)
val eventListener: Player.EventListener = object : Player.EventListener {
override fun onPlaybackStateChanged(state: Int) {
if (state == ExoPlayer.STATE_READY) {
playVideo(simpleExoPlayer)
}
}
}
simpleExoPlayer.addListener(eventListener)
simpleExoPlayer.playWhenReady = false
simpleExoPlayer.prepare()
showToast("Prepare video")
return simpleExoPlayer
}
Do you guys have any idea to fix it?
If you thinks problem in this part of code i can recommend you to try initialize your SimpleExoPlayer object in application class and use it's instance all across application.
Try with this code
var exoPlayer: SimpleExoPlayer? = null
private fun setupVideo(uriString: String) {
val appName = R.string.app_name
val trackSelector: TrackSelector = DefaultTrackSelector()
val userAgent = context.let { Util.getUserAgent(it, it.getString(appName)) }
val sourceFactory = DefaultDataSourceFactory(requireContext(), userAgent)
val uri = Uri.parse(uriString)
val mediaSource = ProgressiveMediaSource.Factory(sourceFactory).createMediaSource(uri)
exoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector)
exoPlayer?.prepare(mediaSource)
exoPlayer?.playWhenReady = false
pvPlayer.player = exoPlayer
}
After quite some time investigating, I found the issue is creating an ExoPlayer instance.
val simpleExoPlayer = SimpleExoPlayer
.Builder(this) // .setLoadControl(defaultLoadControl)
.build()
Just this simple blook took about 0.1 seconds to finish. As a result, it froze the animation for a short period of time. I decided to create it on splash screen and reused it whenever possible.

How to play encrypted video in exoplayer (android app) coming from HLS streamer?

I am right now using FFMPEG to stream mp4 file using HLS.
I am using this link to enable encryption: https://hlsbook.net/how-to-encrypt-hls-video-with-ffmpeg/
To play video in my android app, I am using exoplayer, below is my source code to play video:
Player player;
private MediaSource buildMediaSource(Uri uri) {
TrackSelection.Factory adaptiveTrackSelection = new AdaptiveTrackSelection.Factory(new DefaultBandwidthMeter());
player = ExoPlayerFactory.newSimpleInstance(
this,
new DefaultTrackSelector(adaptiveTrackSelection));
playerView.setPlayer(player);
// These factories are used to construct two media sources.
DefaultBandwidthMeter defaultBandwidthMeter = DefaultBandwidthMeter.getSingletonInstance(this);
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(mContext,
Util.getUserAgent(mContext, "cookvid"), defaultBandwidthMeter);
//DataSource.Factory dataSourceFactory =
// new DefaultDataSourceFactory(this, "exoplayer-codelab");
HlsMediaSource.Factory mediaSourceFactory = new HlsMediaSource.Factory(dataSourceFactory);
return mediaSourceFactory.createMediaSource(uri);
//return new ProgressiveMediaSource.Factory(dataSourceFactory)
// .createMediaSource(uri);
}
private void initializePlayer() {
Uri uri = Uri.parse(getString(R.string.media_url_hls));
MediaSource mediaSource = buildMediaSource(uri);
player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow, playbackPosition);
player.addListener(playbackStateListener);
player.prepare(mediaSource, false, false);
}
But with this code, I can not play video in app, If I am not using this encryption ,then exoplayer can play video without any issue.
Please help me on this, I am newbie on exoplayer side.
I created for you an example in Kotlin to make it work:
class MainActivity : AppCompatActivity() {
private var exoPlayer: SimpleExoPlayer? = null
private var trackSelector: DefaultTrackSelector? = null
var drmSessionManager: DefaultDrmSessionManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
trackSelector = DefaultTrackSelector(this)
exoPlayer = SimpleExoPlayer.Builder(this)
.setTrackSelector(trackSelector!!)
.build()
player_view.player = exoPlayer
var uri = Uri.fromFile( File("//android_asset/legend_enc.mp4"))
playVideo(uri, "zX65/4jzTK6wYYWwACTkwg", "Y8tfcYTdS2iaXF/xHuajKA")
}
private fun playVideo(url: Uri, id: String, value: String){
try {
drmSessionManager =
Util.getDrmUuid(C.CLEARKEY_UUID.toString())?.let { buildDrmSessionManager(
it,
true,
id,
value
) }
} catch (e: UnsupportedDrmException) {
e.printStackTrace()
}
exoPlayer?.setMediaSource(buildDashMediaSource(url))
exoPlayer?.prepare()
exoPlayer?.playWhenReady = true
}
private fun buildDashMediaSource(uri: Uri): MediaSource {
val dashChunkSourceFactory = DefaultDataSourceFactory(this, "agent")
return ProgressiveMediaSource.Factory(dashChunkSourceFactory)
.setDrmSessionManager(drmSessionManager ?: DrmSessionManager.DUMMY)
.createMediaSource(uri)
}
#Throws(UnsupportedDrmException::class)
private fun buildDrmSessionManager(uuid: UUID, multiSession: Boolean, id: String, value: String): DefaultDrmSessionManager {
val drmCallback = LocalMediaDrmCallback("{\"keys\":[{\"kty\":\"oct\",\"k\":\"${value}\",\"kid\":\"${id}\"}],\"type\":\"temporary\"}".toByteArray())
val mediaDrm = FrameworkMediaDrm.newInstance(uuid)
return DefaultDrmSessionManager(uuid, mediaDrm, drmCallback, null, multiSession)
}
}

Exoplayer2 Streaming HLS Videos , Sometimes plays video with sound only(video not played)

I implement exoplayer2 in my app for playing HLS Videos, but sometimes it plays just sound, and doesn't work correctly. What am I supposed to do? I couldn't find why this happens sometimes.
this is the code for initializing player :
fun initPalyer(){
val mainHandler = Handler()
val bandwidthMeter: BandwidthMeter = DefaultBandwidthMeter.Builder(context).build()
bandwidthMeter.addEventListener(mainHandler!!, this)
val trackSelectionFactory: TrackSelection.Factory = AdaptiveTrackSelection.Factory()
trackSelector = DefaultTrackSelector(context, trackSelectionFactory)
val builder = ParametersBuilder(context)
trackSelectorParameters = builder.build()
trackSelector!!.parameters = trackSelectorParameters
var rendersFactory: RenderersFactory = app.buildRenderersFactory(false)
player = SimpleExoPlayer.Builder(
context, renderersFactory
)
.setTrackSelector(trackSelector!!)
.setBandwidthMeter(bandwidthMeter)
//.setLoadControl(loadControl)
.build()
player!!.addListener(this)
loadState()
playerView.player = player!!
}
the code for preparing player :
private fun preparePlayer(uri: Uri) {
val mediaSource = MediaSourceBuilder().build(uri)
durationSet = false
player?.prepare(mediaSource, true, false)
}
and the code for creating mediaSources :
class MediaSourceBuilder {
//Build various MediaSource depending upon the type of Media for a given video/audio uri
fun build(uri: Uri): MediaSource {
val userAgent = PlayerConstants.USER_AGENT
val lastPath = uri.lastPathSegment?:""
val defaultHttpDataSourceFactory = DefaultHttpDataSourceFactory(userAgent)
if(lastPath.contains(PlayerConstants.FORMAT_MP3) || lastPath.contains(PlayerConstants.FORMAT_MP4)){
return ExtractorMediaSource.Factory(defaultHttpDataSourceFactory)
.createMediaSource(uri)
}else if(lastPath.contains(PlayerConstants.FORMAT_M3U8)){
return HlsMediaSource.Factory(defaultHttpDataSourceFactory)
.setAllowChunklessPreparation(true)
.createMediaSource(uri)
}else{
val dashChunkSourceFactory = DefaultDashChunkSource.Factory(defaultHttpDataSourceFactory)
return DashMediaSource.Factory(dashChunkSourceFactory, defaultHttpDataSourceFactory)
.createMediaSource(uri)
}
}
You might wanna change your DataSourceFactory, in case your URL are in HTTPS you might end up with an error, try using DefaultDataSourceFactory instead of DefaultHttpDataSourceFactory

How to implement ExoPlayer with Databinding?

I have a class activity_player layout in which I have exoplayer2.ui.PlayerView and I created exo_player_control_view so that it overrides default controls in ExoPlayer. So I wanted to use Databinding in newly created custom control view but don't know how to do it. Any advice?
It is actually an open issue over here, but yet to be solved. So is there anyone who had a workaround to make exo_player_control_view Databinding friendly?
Use Like this >>>>>
private val binding by lazy {
ActivityPipVideoPlayerBinding.inflate(layoutInflater)}
private val exoPLayerBinding by lazy {
VdoExoControlViewBinding.inflate(LayoutInflater.from(this), binding.root, true)
}
You can use binding variable inside fragment/activity to access the playerView inside fragment/activity and
val uri: Uri? = if (url is String) Uri.parse(url as String?) else url as Uri?
val trackSelector =
DefaultTrackSelector(AdaptiveTrackSelection.Factory(DefaultBandwidthMeter()))
val player: SimpleExoPlayer = ExoPlayerFactory.newSimpleInstance(view.context, trackSelector)
val dataSourceFactory = DefaultDataSourceFactory(view.context, "ua")
val mediaSource =
ExtractorMediaSource(uri, dataSourceFactory, DefaultExtractorsFactory(), null, null)
player.prepare(mediaSource)
player.apply {
volume = 0f
repeatMode = Player.REPEAT_MODE_ONE
playWhenReady = true
videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
}
binding.playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL)
binding.playerView.player = player

Categories

Resources