谷歌的一个在线播放视频的框架,使用起来非常简单
1.官方地址:https://github.com/google/ExoPlayer 有兴趣的,可以去官方地址,看一下框架的源码,本例子只是介绍简单使用
2.我的项目地址:https://github.com/wrs13634194612/ExoPlayerTest
3.运行效果图:
4.首先就是引用,在builder.gradle引入框架,或者直接使用jar包,本例子是使用的jar包
implementation 'com.google.android.exoplayer:exoplayer-core:2.7.3'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.7.3'
implementation 'com.google.android.exoplayer:exoplayer-core:2.7.3'
引入jar:
implementation files('libs/exoplayer.jar')
5.清单文件,设置一下硬件加速解码和网络请求权限,并且设置activity横屏
6.布局:简单写一个播放器控件,展示视频播放内容
7.创建一个视频类,
package com.example.administrator.testz;
public class Video {
public static final String INTENT_EXTRA_VIDEO = "INTENT_EXTRA_VIDEO";
private long id;
private int year;
private int rating;
private String description;
private String title;
private String thumbUrl;
private String contentUrl;
private String category;
private String tags;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getThumbUrl() {
return thumbUrl;
}
public void setThumbUrl(String thumbUrl) {
this.thumbUrl = thumbUrl;
}
public String getContentUrl() {
return contentUrl;
}
public void setContentUrl(String contentUrl) {
this.contentUrl = contentUrl;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getTags() {
return tags;
}
public void setTags(String tags) {
this.tags = tags;
}
}
8.创建ExoPlayer对象,获取视频数据,展示,具体的网络请求,视频的编解码,都已经封装好了,记得退出activity需要清空ExoPlayer对象,避免内存泄漏
package com.example.administrator.testz;
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaCodec;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.MediaController;
import android.widget.Toast;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.FrameworkSampleSource;
import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
import com.google.android.exoplayer.MediaCodecTrackRenderer;
import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
import com.google.android.exoplayer.SampleSource;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.VideoSurfaceView;
import com.google.android.exoplayer.util.PlayerControl;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback,
ExoPlayer.Listener, MediaCodecVideoTrackRenderer.EventListener {
private static final int RENDERER_COUNT = 2;
private static final String TAG = "MainActivity";
private Video mViedeo;
private MediaController mediaController;
private View shutterView;
private VideoSurfaceView surfaceView;
private ExoPlayer player;
private MediaCodecVideoTrackRenderer videoRenderer;
private boolean autoPlay;
private String mUrl = "https://v-cdn.zjol.com.cn/280443.mp4";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
mViedeo = (Video)getIntent().getSerializableExtra(Video.INTENT_EXTRA_VIDEO);
View root = findViewById(R.id.root);
shutterView = findViewById(R.id.shutter);
surfaceView = (VideoSurfaceView)findViewById(R.id.surface_view);
mediaController = new MediaController(this);
mediaController.setPadding(48,27,48,27);
mediaController.setAnchorView(root);
surfaceView.getHolder().addCallback(this);
preparePlayer();
}
private void preparePlayer() {
SampleSource sampleSource = new FrameworkSampleSource(this, Uri.parse(mUrl),null,RENDERER_COUNT);
videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource,MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
player = ExoPlayer.Factory.newInstance(RENDERER_COUNT,1000,5000);
player.addListener(this);
mediaController.setMediaPlayer(new PlayerControl(player));
mediaController.setEnabled(true);
player.prepare(videoRenderer,audioRenderer);
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
requestVisibleBehind(true);
}
super.onPause();
}
// 当此activity的半透明activity变得不透明或正在启动另一个activity时调用。
@Override
public void onVisibleBehindCanceled() {
super.onVisibleBehindCanceled();
if (player!=null){
player.release();
player = null;
}
videoRenderer = null;
shutterView.setVisibility(View.VISIBLE);
}
@Override
protected void onStop() {
super.onStop();
if (player!=null){
player.release();
player = null;
}
videoRenderer = null;
shutterView.setVisibility((View.VISIBLE));
}
private void maybeStartPlayback(){
Log.d(TAG, "maybeStartPlayback");
Surface surface = surfaceView.getHolder().getSurface();
if (videoRenderer == null || surface == null || !surface.isValid()){
return;
}
player.sendMessage(videoRenderer,MediaCodecVideoTrackRenderer.MSG_SET_SURFACE,surface);
if (autoPlay){
player.setPlayWhenReady(true);
autoPlay = false;
}
}
private void onError(Exception e){
Log.e(TAG,"Player failed",e);
Toast.makeText(getApplicationContext(),"Playback failed",Toast.LENGTH_SHORT).show();
finish();
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.e(TAG,"maybeStartPlayback");
maybeStartPlayback();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
if (videoRenderer != null){
player.blockingSendMessage(videoRenderer,MediaCodecVideoTrackRenderer.MSG_SET_SURFACE,null);
}
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.e(TAG,"player state"+playbackState);
if (playbackState == ExoPlayer.STATE_READY){
shutterView.setVisibility(View.GONE);
mediaController.show(0);
}
}
@Override
public void onPlayWhenReadyCommitted() {
}
@Override
public void onPlayerError(ExoPlaybackException e) {
onError(e);
}
@Override
public void onDroppedFrames(int count, long elapsed) {
Log.e(TAG,"Dropped frames:"+count);
}
@Override
public void onVideoSizeChanged(int width, int height, float v) {
surfaceView.setVideoWidthHeightRatio(height==0?1:(float)width/height);
}
@Override
public void onDrawnToSurface(Surface surface) {
shutterView.setVisibility(View.GONE);
mediaController.show(0);
}
@Override
public void onDecoderInitializationError(MediaCodecTrackRenderer.DecoderInitializationException e) {
}
@Override
public void onCryptoError(MediaCodec.CryptoException e) {
}
@Override
public void onDecoderInitialized(String s, long l, long l1) {
}
}
end