公司项目里面需要用到视频播放器,所以试了好多Android的视频播放器方案,最后试水结果是谷歌的exoplayer和哔哩哔哩的ijkplayer视频加载速度和播放性能比较好,由于exoplayer貌似和谷歌的激励视频广告的sdk里面用的exoplayer似乎有冲突,
所以只好换成了ijkplayer的方案,这里记录下exoplayer的使用过程,以便以后查阅使用。
在glide中依赖exoplyaer的库首先:
dependencies {
implementation 'com.google.android.exoplayer:exoplayer:r2.0.0'
}
布局中加入exoplayer的视频控件:
代码调用:
var playerView :PlayerView= view.video_wallpaper_img
// playerView!!.controllerShowTimeoutMs = 0
playerView!!.controllerAutoShow = false
player = PlayerManager(activity)
player!!.setContentUrl(bean!!.url)
player!!.setImgPreview(view.iv_wallpaper_video_preview)
PlayerManager类的代码:
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import com.blossom.ripple.R;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.C.ContentType;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.LoopingMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
/** Manages the {@link ExoPlayer}, the IMA plugin and all video playback. */
/* package */public final class PlayerManager implements AdsMediaSource.MediaSourceFactory {
private final DataSource.Factory dataSourceFactory;
String contentUrl = "";
private String TAG = "PlayerManager";
ImageView imgPreview = null;
public void setContentUrl(String contentUrl) {
this.contentUrl = contentUrl;
}
private SimpleExoPlayer player;
private long contentPosition;
public void setImgPreview(ImageView imgPreview) {
this.imgPreview = imgPreview;
}
public PlayerManager(Context context) {
dataSourceFactory =
new DefaultDataSourceFactory(
context, Util.getUserAgent(context, context.getString(R.string.app_name)));
}
public void init(Context context, PlayerView playerView) {
// Create a default track selector.
TrackSelection.Factory videoTrackSelectionFactory;
videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(new DefaultBandwidthMeter());
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
// Create a player instance.
player = ExoPlayerFactory.newSimpleInstance(context, trackSelector);
// Bind the player to the view.
playerView.setPlayer(player);
// This is the MediaSource representing the content media (i.e. not the ad).
// String contentUrl = context.getString(R.string.content_url);
// String contentUrl = "https://html5demos.com/assets/dizzy.mp4";
// MediaSource contentMediaSource = buildMediaSource(Uri.parse(contentUrl));
// Compose the content media source into a new AdsMediaSource with both ads and content.
// MediaSource mediaSourceWithAds =
// new AdsMediaSource(
// contentMediaSource,
// /* adMediaSourceFactory= */ this,
// adsLoader,
// playerView.getOverlayFrameLayout());
// Measures bandwidth during playback. Can be null if not required.
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
// Produces Extractor instances for parsing the media data.
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource source = new ExtractorMediaSource(Uri.parse(contentUrl),dataSourceFactory, extractorsFactory, null, null);
// Loops the video indefinitely.
LoopingMediaSource loopingSource = new LoopingMediaSource(source);
// Prepare the player with the source.
player.addListener(eventListener);
player.seekTo(contentPosition);
player.prepare(loopingSource);
player.setPlayWhenReady(true);
// 静音播放
player.setVolume(0);
}
public void reset() {
if (player != null) {
contentPosition = player.getContentPosition();
player.release();
player = null;
}
}
public void release() {
if (player != null) {
player.release();
player = null;
}
}
// AdsMediaSource.MediaSourceFactory implementation.
@Override
public MediaSource createMediaSource(Uri uri) {
return buildMediaSource(uri);
}
@Override
public int[] getSupportedTypes() {
// IMA does not support Smooth Streaming ads.
return new int[] {C.TYPE_DASH, C.TYPE_HLS, C.TYPE_OTHER};
}
// Internal methods.
private MediaSource buildMediaSource(Uri uri) {
@ContentType int type = Util.inferContentType(uri);
switch (type) {
// case C.TYPE_DASH:
// return new DashMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
// case C.TYPE_SS:
// return new SsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
case C.TYPE_HLS:
return new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
case C.TYPE_OTHER:
return new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
default:
throw new IllegalStateException("Unsupported type: " + type);
}
}
private ExoPlayer.EventListener eventListener = new ExoPlayer.EventListener() {
@Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
@Override
public void onLoadingChanged(boolean isLoading) {
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case ExoPlayer.STATE_ENDED:
Log.i(TAG, "Playback ended!");
//Stop playback and return to start position
break;
case ExoPlayer.STATE_READY:
if (imgPreview!=null){
imgPreview.setVisibility(View.GONE);
}
break;
case ExoPlayer.STATE_BUFFERING:
Log.i(TAG, "Playback buffering!");
break;
case ExoPlayer.STATE_IDLE:
Log.i(TAG, "ExoPlayer idle!");
break;
}
}
@Override
public void onRepeatModeChanged(int repeatMode) {
}
@Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
@Override
public void onPlayerError(ExoPlaybackException error) {
}
@Override
public void onPositionDiscontinuity(int reason) {
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
@Override
public void onSeekProcessed() {
}
};
}
记得在fragment的生命周期中做好player的管理和释放销毁,activity中使用的话也是这样
override fun onResume() {
super.onResume()
player?.init(activity, playerView)
}
override fun onPause() {
super.onPause()
player?.reset()
}
override fun onDestroyView() {
player?.release()
super.onDestroyView()
}
然后就可以播放视频了