3

I'm using the more-or-less default ExoPlayer 2.1 SimpleExoPlayer to stream from either a url Uri or a local file Uri. The Uri is loaded into the MediaSource,

MediaSource mediaSource = new ExtractorMediaSource(url,
            dataSourceFactory, extractorsFactory, null, null);

The source is sometimes a Video, mp4 instead of mp3, so in the Activity I set it to the com.google.android.exoplayer2.ui.SimpleExoPlayerView

 mVideoView = (SimpleExoPlayerView) findViewById(R.id.media_player);
 mVideoView.setPlayer(player);
 mVideoView.requestFocus();

I've read in an article:

SimpleExoPlayerView has also been updated to look at ID3 metadata, and will automatically display embedded ID3 album art during audio playbacks. If not desired, this functionality can be disabled using SimpleExoPlayerView’s setUseArtwork method.

I've seen it answered for Files, How to get and set (change) ID3 tag (metadata) of audio files?,

But I'm hoping to set the ID3 metadata for a Uri derived from a url String. Is it possible? Otherwise, is it possible to set the artwork for an ExoPlayerView without editing the ID3 metafiles? Or possible to change the ID3 meta for a File without a dependency?

Edit

So I've found an Issue which says this is solved, and the issuer linked to an override of the exo_simple_player_view here

I've found in the blog post

When a SimpleExoPlayerView is instantiated it inflates its layout from the layout file exo_simple_player_view.xml. PlaybackControlView inflates its layout from exo_playback_control_view.xml. To customize these layouts, an application can define layout files with the same names in its own res/layout* directories. These layout files override the ones provided by the ExoPlayer library.

So I have to override the simpleview somehow.

Community
  • 1
  • 1
Nevermore
  • 7,141
  • 5
  • 42
  • 64

1 Answers1

0

You can use this function and pass mediaUri and thunbnailUri to it

private fun PlayerView.loadArtWorkIfMp3(mediaUri: Uri, thumbnailUri: Uri) {
    try {
        val imageView = this.findViewById<ImageView>(R.id.exo_artwork)
        if (mediaUri.lastPathSegment!!.contains("mp3")) {
            this.useArtwork = true
            imageView.scaleType = ImageView.ScaleType.CENTER_INSIDE
            imageView.loadImage(thumbnailUri) {
                this.defaultArtwork = it
            }
        }
    } catch (e: Exception) {
        Log.d("artwork", "exo_artwork not found")
    }
}

and You will use loadImage function

@BindingAdapter(value = ["imageUri", "successCallback"], requireAll = false)
fun ImageView.loadImage(imgUrl: Uri?, onLoadSuccess: (resource: Drawable) -> Unit = {}) {

    val requestOption = RequestOptions()
        .placeholder(R.drawable.ic_music)
        .error(R.drawable.ic_music)

    Glide.with(this.context)
        .load(imgUrl)
        .transition(DrawableTransitionOptions.withCrossFade())
        .apply(requestOption)
        .centerInside()
        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        .listener(GlideImageRequestListener(object : GlideImageRequestListener.Callback {
            override fun onFailure(message: String?) {
                Log.d("loadImage", "onFailure:-> $message")
            }

            override fun onSuccess(dataSource: String, resource: Drawable) {
                Log.d("loadImage", "onSuccess:-> load from $dataSource")
                onLoadSuccess(resource)
            }

        }))
        .into(this)
}

And last one

class GlideImageRequestListener(private val callback: Callback? = null) : RequestListener<Drawable> {

    interface Callback {
        fun onFailure(message: String?)
        fun onSuccess(dataSource: String, resource: Drawable)
    }

    override fun onLoadFailed(
        e: GlideException?,
        model: Any?,
        target: Target<Drawable>?,
        isFirstResource: Boolean
    ): Boolean {
        callback?.onFailure(e?.message)
        return false
    }

    override fun onResourceReady(
        resource: Drawable?,
        model: Any?,
        target: Target<Drawable>?,
        dataSource: DataSource?,
        isFirstResource: Boolean
    ): Boolean {

        resource?.let {
            target?.onResourceReady(
                it,
                DrawableCrossFadeTransition(1000, isFirstResource)
            )
        }
        callback?.onSuccess(dataSource.toString(),resource!!)
        return true
    }


}
Nitin Prakash
  • 927
  • 9
  • 16