ExoPlayer的简单demo

下载地址

点击下载demo

这里写图片描述

横屏效果

这里写图片描述

package qingyunbomei.com.xingtest.videos;

import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.KeyEvent;
import android.view.TextureView;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.LoadControl;
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.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
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.SimpleExoPlayerView;
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;

import java.lang.ref.WeakReference;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import butterknife.BindView;
import butterknife.ButterKnife;
import qingyunbomei.com.xingtest.R;
import qingyunbomei.com.xingtest.utils.PixelUtil;
import qingyunbomei.com.xingtest.utils.TimeUtils;

public class VideoActivity extends AppCompatActivity {

    @BindView(R.id.simpleExoPlayerView)
    SimpleExoPlayerView simpleExoPlayerView;
    @BindView(R.id.texture_view)
    TextureView textureView;
    @BindView(R.id.start_play)
    ImageView startPlay;
    @BindView(R.id.already_player_time)
    TextView alreadyPlayerTime;
    @BindView(R.id.seek_bar)
    SeekBar seekBar;
    @BindView(R.id.all_player_time)
    TextView allPlayerTime;
    @BindView(R.id.all_screen)
    ImageView allScreen;
    @BindView(R.id.constraintLayout)
    ConstraintLayout constraintLayout;
    @BindView(R.id.play_linear)
    LinearLayout playLinear;

    private static final int UP_TIME = 0;//更新播放时间
    private boolean screenFlag = false;//全屏标记
    private SimpleExoPlayer player;
    private boolean playFlag = false;//播放状态
    private ExecutorService executors = Executors.newSingleThreadExecutor();
    private final MyHandler myHandler = new MyHandler(this);

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video);
        ButterKnife.bind(this);
        initVideo();
    }

    //初始化视频
    private void initVideo() {
        //create a TrackSelector 选择MediaSource
        DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        //从MediaSource中选出media提供给可用的Render S来渲染,在创建播放器时被注入
        TrackSelection.Factory videoTrackSelectionFactor = new AdaptiveTrackSelection.Factory(bandwidthMeter);
        TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactor);
        //Create a default LoadControl 控制MediaSource缓存media
        LoadControl loadControl = new DefaultLoadControl();
        //Create the player
        player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);

        //produces DataSource instances through which media data is loaded
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
                Util.getUserAgent(this, "飞星"), bandwidthMeter);
        //Produces Extractor instances for parsing the media data 萃取剂
        ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
        MediaSource videoSource = new ExtractorMediaSource(Uri.parse("http://w5.dwstatic.com/54/3/1622/2166193-100-1464903053.mp4"),
                dataSourceFactory, extractorsFactory, null, null);
        //设置资源
        player.prepare(videoSource);

        //显示字幕
//        player.setTextOutput(new TextRenderer.Output() {
//            @Override
//            public void onCues(List<Cue> cues) {
//
//            }
//        });
        player.addListener(eventListener);
        player.setVideoTextureView(textureView);

//        simpleExoPlayerView.setPlayer(player);

    }

    //播放事件监听
    private ExoPlayer.EventListener eventListener = new ExoPlayer.EventListener()
    {
        @Override
        public void onTimelineChanged(Timeline timeline, Object manifest)
        {
            System.out.println("播放: onTimelineChanged 周期总数 " + timeline);
        }

        @Override
        public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
            System.out.println("播放: TrackGroupArray  ");
        }

        @Override
        public void onLoadingChanged(boolean isLoading) {
            System.out.println("播放: onLoadingChanged  " + TimeUtils.secToTime((int) (player.getBufferedPosition() / 1000)));
            //设置二级进度条
            seekBar.setSecondaryProgress((int) (player.getBufferedPosition() / 1000));
        }

        @Override
        public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
            switch (playbackState) {
                case PlaybackState.STATE_PLAYING:
                    //初始化播放点击事件并设置总时长
                    initPlayVideo();
                    System.out.println("播放状态: 准备 playing");
                    break;

                case PlaybackState.STATE_BUFFERING:
                    System.out.println("播放状态: 缓存完成 playing");
                    break;

                case PlaybackState.STATE_CONNECTING:
                    System.out.println("播放状态: 连接 CONNECTING");
                    break;

                case PlaybackState.STATE_ERROR://错误
                    System.out.println("播放状态: 错误 STATE_ERROR");
                    break;

                case PlaybackState.STATE_FAST_FORWARDING:
                    System.out.println("播放状态: 快速传递");
                    pausePlay();//暂停播放
                    break;

                case PlaybackState.STATE_NONE:
                    System.out.println("播放状态: 无 STATE_NONE");
                    break;

                case PlaybackState.STATE_PAUSED:
                    System.out.println("播放状态: 暂停 PAUSED");
                    break;

                case PlaybackState.STATE_REWINDING:
                    System.out.println("播放状态: 倒回 REWINDING");
                    break;

                case PlaybackState.STATE_SKIPPING_TO_NEXT:
                    System.out.println("播放状态: 跳到下一个");
                    break;

                case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
                    System.out.println("播放状态: 跳到上一个");
                    break;

                case PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM:
                    System.out.println("播放状态: 跳到指定的Item");
                    break;

                case PlaybackState.STATE_STOPPED:
                    System.out.println("播放状态: 停止的 STATE_STOPPED");
                    break;
            }
        }

        @Override
        public void onPlayerError(ExoPlaybackException error) {
            System.out.println("播放: onPlayerError  ");
        }

        @Override
        public void onPositionDiscontinuity() {
            System.out.println("播放: onPositionDiscontinuity  ");
        }
    };

    //初始化播放事件
    private void initPlayVideo()
    {
        allPlayerTime.setText(TimeUtils.secToTime((int) (player.getDuration() / 1000)));
        //设置总时长
        seekBar.setMax((int) (player.getDuration() / 1000));
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
        {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {}

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                //是暂停的开始播放
                if (!player.getPlayWhenReady()) {
                    continuePlay();//继续播放
                }
                player.seekTo(seekBar.getProgress() * 1000);
            }
        });

        //播放按钮
        startPlay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (player.getPlayWhenReady()) {
                    pausePlay();//暂停播放
                } else {
                    continuePlay();//继续播放
                }
            }
        });

        //全屏切换
        allScreen.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v) {
                if (screenFlag)//是全屏
                {
                    setHalfScreen();
                } else {
                    screenFlag = true;//设置为全屏
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    //设置控件大小
                    ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) textureView.getLayoutParams();
                    params.width = ConstraintLayout.LayoutParams.MATCH_PARENT;
                    System.out.println("屏幕: 控件 : " + constraintLayout.getHeight());
                    params.height = getHeight();
                    params.dimensionRatio = 0f;
                    playLinear.setPadding(0,0,0, PixelUtil.dp2px(VideoActivity.this,25));
                    textureView.setLayoutParams(params);
                }
            }
        });
    }

    //设置为半屏
    private void setHalfScreen()
    {
        screenFlag = false;//设置为半屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        //设置控件大小
        ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) textureView.getLayoutParams();
        params.width = ConstraintLayout.LayoutParams.MATCH_PARENT;
        params.dimensionRatio = 1.6f;
        playLinear.setPadding(0,0,0,0);
        textureView.setLayoutParams(params);
    }


    //暂停播放
    private void pausePlay() {
        player.setPlayWhenReady(false);
        startPlay.setBackgroundColor(Color.WHITE);
        playFlag = false;
    }

    //继续播放
    private void continuePlay()
    {
        player.setPlayWhenReady(true);
        startPlay.setBackgroundColor(Color.RED);
        //开始读取进度
        playFlag = true;
        executors.execute(runnable);
    }

    private static class MyHandler extends Handler
    {
        private final WeakReference<VideoActivity> mActivity;
        private MyHandler(VideoActivity mActivity)
        {
            this.mActivity = new WeakReference<>(mActivity);
        }
        @Override
        public void handleMessage(Message msg) {
            if (mActivity.get() == null)
            {
                return;
            }
            if (msg.what == UP_TIME) {
                //设置播放进度
                VideoActivity videoActivity = mActivity.get();
                videoActivity.seekBar.setProgress(msg.arg1);
                videoActivity.alreadyPlayerTime.setText(TimeUtils.secToTime(msg.arg1));
            }
        }
    }

    //开启线程读取进度
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {

            while (playFlag) {
                Message msg = new Message();
                msg.what = UP_TIME;
                //获取播放时间
                msg.arg1 = (int) (player.getCurrentPosition() / 1000);
                myHandler.sendMessage(msg);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };


    @Override
    protected void onDestroy() {
        super.onDestroy();
        //释放资源
        if (player != null) {
            playFlag = false;//停止线程
            executors.shutdown();
            player.stop();
            player.release();
            player = null;
        }
        myHandler.removeCallbacksAndMessages(null);
    }

    //获取屏幕高度
    private int getHeight() {
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.heightPixels;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK &&
                getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
        {
            //设置半屏
            setHalfScreen();
        }
        return super.onKeyDown(keyCode, event);
    }
}






























  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值