【无标题】

视频播放器在App是很常见的,有哪些视频播放器呢?具体情况该用哪款呢?这里我总结了常用的视屏播放Videoview、mediaplayer+surfaceview、vitamio、jcplayer的使用方法并写了各自的播放示例。

代码在这里面
项目目录:

用到的视频地址:

http://rbv01.ku6.com/omtSn0z_PTREtneb3GRtGg.mp4
http://rbv01.ku6.com/7lut5JlEO-v6a8K3X9xBNg.mp4
https://key003.ku6.com/movie/1af61f05352547bc8468a40ba2d29a1d.mp4
https://key002.ku6.com/xy/d7b3278e106341908664638ac5e92802.mp4

Android自带播放器VideoView

播放效果:

常用方法:

videoView.start(); //开始播放
videoView.pause(); //暂停
videoView.stopPlayback(); //停止播放
videoView.isPlaying(); //获取是否在播放状态
videoView.setVideoURI(Uri uri); //设置视频播放uri
videoView.setVideoPath(String path); //设置视频播放路径
videoView.seekTo(int msec); //跳转到设置时间
videoView.getCurrentPosition(); //获取当前播放时间
videoView.getDuration(); //获取该视频播放时长
videoView.setMediaController(MediaController controller); //设置播放控制器
videoView.setOnPreparedListener(MediaPlayer.OnPreparedListener listener); //加载完成监听
videoView.setOnCompletionListener(MediaPlayer.OnCompletionListener listener); //设置播放完成监听
videoView.setOnErrorListener(MediaPlayer.OnErrorListener listener); //播放失败监听

代码:

import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.MediaController;
import android.widget.VideoView;

public class VideoViewActivity extends AppCompatActivity {
    private VideoView videoView;
    public final String videoUrl = "http://rbv01.ku6.com/omtSn0z_PTREtneb3GRtGg.mp4";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_view);

        init();
    }

    private void init(){
        videoView = (VideoView) findViewById(R.id.videoview);
        videoView.setVideoPath(videoUrl);
        videoView.setMediaController(new MediaController(this));
        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                videoView.start();
            }
        });
        videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                videoView.start();
            }
        });

    }
}

自定义Mediaplayer+Surfaceview播放器:

播放效果:

Mediaplayer状态图:

使用方式:

surfaceView.getHolder().addCallback(new HolderCallBack());
mediaPlayer.setDataSource(mediaUrl);
mediaPlayer.setDisplay(surfaceView.getHolder());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(OnPreparedListener listener);
mediaPlayer.start();

代码实现:

播放器类:

import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import com.example.videoplayers.R;
import java.io.IOException;
import java.util.HashMap;

public class PlayVideo {
    private Context context;
    private View videoView;
    public MediaPlayer mediaPlayer;
    private boolean isDisplay = true;
    private ProgressBroadCast progressBroadCast;
    private SurfaceView surfaceView;
    private Button btPlay;
    private SeekBar seekBar;
    private TextView tvTime;
    private ImageView ivCover;
    private LinearLayout relaVideo,llLoading;
    /** 视频播放资源地址 */
    private String mediaUrl;
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(null != msg){
                ivCover.setImageBitmap((Bitmap) msg.obj);
            }
        }
    };

    public PlayVideo(Context context,String mediaUrl){
        this.context = context;
        this.mediaUrl = mediaUrl;
        videoView = LayoutInflater.from(context).inflate(R.layout.custom_videoplayer,null);
        initView(videoView);
        event();
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void initView(View view){
        surfaceView = (SurfaceView) view.findViewById(R.id.surfaceview);
        btPlay = (Button) view.findViewById(R.id.btn_play);
        seekBar = (SeekBar) view.findViewById(R.id.play_seekbar);
        tvTime = (TextView) view.findViewById(R.id.tv_video_time);
        relaVideo = (LinearLayout) view.findViewById(R.id.rela_video);
        llLoading = (LinearLayout) view.findViewById(R.id.ll_video_loading);
        ivCover = (ImageView) view.findViewById(R.id.iv_videoplayer_cover);
        MyClickListener listener = new MyClickListener();
        surfaceView.setOnClickListener(listener);
        btPlay.setOnClickListener(listener);

        progressBroadCast = new ProgressBroadCast();
        context.registerReceiver(progressBroadCast, new IntentFilter("play"));
        surfaceView.getHolder().setKeepScreenOn(true);
        surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceView.getHolder().addCallback(new HolderCallBack());

        avaterThread();
    }

    private void event() {
        //seekbar调节进度
        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 seekBar2) {
                if(null != mediaPlayer)
                    mediaPlayer.seekTo(seekBar2.getProgress());
            }
        });
    }

    public View getVideoView(){
        return videoView;
    }

    public BroadcastReceiver getReceiver(){
        return progressBroadCast;
    }

    private void avaterThread(){
        new Thread(){
            @Override
            public void run() {
                MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
                if(Build.VERSION.SDK_INT >= 14){    //需加入api判断,不然会报IllegalArgumentException
                    mediaMetadataRetriever.setDataSource(mediaUrl,new HashMap<String, String>());
                }else{
                    mediaMetadataRetriever.setDataSource(mediaUrl);
                }
                Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(1000,MediaMetadataRetriever.OPTION_CLOSEST);
                Message message = new Message();
                message.obj = bitmap;
                mHandler.sendMessage(message);
            }
        }.start();
    }

        class MyClickListener implements View.OnClickListener {

            @Override
            public void onClick(View v) {
                switch (v.getId()) {
                    case R.id.surfaceview:
                        if (isDisplay) {
                            relaVideo.setVisibility(View.GONE);
                        } else {
                            relaVideo.setVisibility(View.VISIBLE);
                        }
                        isDisplay = !isDisplay;
                        break;
                    case R.id.btn_play:
                        if (mediaPlayer == null) {
                            netWorkState();
                        } else {
                            //播放和暂停切换
                            if (mediaPlayer.isPlaying()) {
                                mediaPlayer.pause();
                                btPlay.setBackgroundResource(R.mipmap.video_btn_pause);
                            } else {
                                mediaPlayer.start();
                                ivCover.setVisibility(View.GONE);
                                new ProgressThread().start();
                                btPlay.setBackgroundResource(R.mipmap.video_btn_start);
                            }
                        }
                        break;
                }
            }
        }

            /**
             * 播放视频,先判断网络,是流量就要提示用户
             */
            private void netWorkState() {
                mediaPlayer = new MediaPlayer();
                new PrepareThread().start();
                llLoading.setVisibility(View.VISIBLE);

            }

            class HolderCallBack implements SurfaceHolder.Callback {

                @Override
                public void surfaceCreated(SurfaceHolder holder) {

                }

                @Override
                public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

                }

                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {

                }
            }

            class MyPrepareListener implements MediaPlayer.OnPreparedListener {

                @Override
                public void onPrepared(MediaPlayer mp) {
                    if (null != mediaPlayer) {
                        llLoading.setVisibility(View.GONE);
                        mediaPlayer.start();
                        new ProgressThread().start();
                    }
                }
            }

            class PrepareThread extends Thread {
                @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
                @Override
                public void run() {
                    super.run();
                    try {
                        mediaPlayer.reset();
                        mediaPlayer.setDataSource(mediaUrl);
                        mediaPlayer.setDisplay(surfaceView.getHolder());
                        mediaPlayer.prepareAsync();
                        mediaPlayer.setOnPreparedListener(new MyPrepareListener());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            /**
             * 时间进度广播
             */
            public class ProgressBroadCast extends BroadcastReceiver {

                @Override
                public void onReceive(Context context, Intent intent) {
                    int curPosition = intent.getIntExtra("position", 0);
                    int maxLen = intent.getIntExtra("max", 0);
                    seekBar.setProgress(curPosition);
                    seekBar.setMax(maxLen);

                    setTime(curPosition, maxLen);
                }

                /**
                 * 秒转化为00:00形式
                 * @param curPosition
                 * @param maxLen
                 */
                private void setTime(int curPosition, int maxLen) {
                    int cm = curPosition / 1000 / 60;
                    int cs = curPosition / 1000 % 60;
                    int mm = maxLen / 1000 / 60;
                    int ms = maxLen / 1000 % 60;
                    StringBuilder builder = new StringBuilder();
                    builder.append(cm / 10).append(cm % 10).append(":")
                            .append(cs / 10).append(cs % 10).append("/")
                            .append(mm / 10).append(mm % 10).append(":")
                            .append(ms / 10).append(ms % 10);
                    tvTime.setText(builder.toString());
                }

            }

            /**
             * 发送播放进度线程
             */
            class ProgressThread extends Thread {
                @Override
                public void run() {
                    while (null != mediaPlayer && mediaPlayer.isPlaying()) {
                        int currentProgress = mediaPlayer.getCurrentPosition();
                        int maxLen = mediaPlayer.getDuration();
                        //每隔一秒发送一次播放进度
                        Intent progressIntent = new Intent("play");
                        progressIntent.putExtra("position", currentProgress);
                        progressIntent.putExtra("max", maxLen);
                        context.sendBroadcast(progressIntent);
                        try {
                            sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

}

MediaPlayerActivity代码:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RelativeLayout;
import com.example.videoplayers.R;

public class MediaPlayerActivity extends AppCompatActivity {
    private RelativeLayout rlPlayer;
    private final String url = "http://rbv01.ku6.com/7lut5JlEO-v6a8K3X9xBNg.mp4";
    private PlayVideo playVideo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_media_player);

        init();
    }

    private void init() {
        rlPlayer = (RelativeLayout) findViewById(R.id.rl_player);
        playVideo = new PlayVideo(this,url);
        rlPlayer.addView(playVideo.getVideoView());
    }

    @Override
    public void onDestroy() {    //退出停止视频播放
        super.onDestroy();
        try {
            if (null != playVideo) {
                playVideo.mediaPlayer.release();
                playVideo.mediaPlayer = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();

        unregisterReceiver(playVideo.getReceiver());
    }
}

Vitamio播放器:

播放效果:

库下载地址: GitHub - yixia/VitamioBundleStudio

常用方法(与原生的Videoview使用方法极其类似):

videoView.setVideoPath(String path);
videoView.setMediaController(MediaController controller);
videoView.start();
videoView.pause();
videoView.isPlaying();
videoView.seekTo(long time);
videoView.getDuration();
videoView.stopPlayback();
videoView.getCurrentPosition();
videoView.setOnPreparedListener(MediaPlayer.OnPreparedListener listener);
videoView.setOnCompletionListener(MediaPlayer.OnCompletionListener listener);
videoView.setOnInfoListener(MediaPlayer.OnInfoListener listener);
videoView.setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener);

控件引用:
<io.vov.vitamio.widget.VideoView
android:id="@+id/videoview"
android:layout_width="match_parent"
android:layout_height="200dp"/>

代码实现:(加入缓冲状态和缓冲网速)

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.example.videoplayers.R;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.Vitamio;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoView;

public class VitamioPlayerActivity extends AppCompatActivity {
    private VideoView videoView;
    private TextView tvBuffer,tvNet;
    private String videoUrl = "https://key003.ku6.com/movie/1af61f05352547bc8468a40ba2d29a1d.mp4";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vitamio_player);

        init();

    }

    private void init() {
        videoView = (VideoView) findViewById(R.id.videoview);
        tvBuffer = (TextView) findViewById(R.id.tv_buffer);
        tvNet = (TextView) findViewById(R.id.tv_net);

        if (Vitamio.isInitialized(this)) {
            videoView.setVideoPath(videoUrl);
            videoView.setMediaController(new MediaController(this));
            videoView.start();
        }

        videoView.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
            @Override
            public void onBufferingUpdate(MediaPlayer mp, int percent) {
                tvBuffer.setText("已缓冲:" + percent + "%");
            }
        });

        videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
            @Override
            public boolean onInfo(MediaPlayer mp, int what, int extra) {
                switch (what) {
                    //开始缓冲
                    case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                        tvBuffer.setVisibility(View.VISIBLE);
                        tvNet.setVisibility(View.VISIBLE);
                        mp.pause();
                        break;
                    //缓冲结束
                    case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                        tvBuffer.setVisibility(View.GONE);
                        tvNet.setVisibility(View.GONE);
                        mp.start();
                        break;
                    //正在缓冲
                    case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
                        tvNet.setText("网速:" + extra + "kb/s");
                        break;
                }
                return true;
            }
        });

    }
}

(节操)JCVideoPlayer:

个人认为这是使用最简单且功能最完善的播放器,播放效果:

播放效果

特点:
1.自带全屏播放放和浮层小窗口播放
2.可以完全自定义UI
3.手势修改进度和音量
4.重力感应自动全屏
5.支持https和rtmp

引入库:

    compile 'fm.jiecao:jiecaovideoplayer:5.5.4'

使用控件:

    <fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard
        android:id="@+id/playerstandard"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

使用类:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.example.videoplayers.R;
import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard;

public class JcPlayerActivity extends AppCompatActivity {
    private JCVideoPlayerStandard playerStandard;
    private String videoUrl = "https://key002.ku6.com/xy/d7b3278e106341908664638ac5e92802.mp4";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jc_player);

        init();
    }

    private void init() {
        playerStandard = (JCVideoPlayerStandard) findViewById(R.id.playerstandard);
        playerStandard.setUp(videoUrl,JCVideoPlayerStandard.SCREEN_LAYOUT_NORMAL,"追龙");
        playerStandard.startVideo();
    }
}

以上是Android常用视频播放器,根据需求是仅仅要预览功能还是要各种操作引用哪款播放器。由于篇幅原因,功能强大的ijkplayer没加入到本篇博客,写完后会在此加入链接。哎呀妈呀,终于敲完了。



本文转载自:https://www.jianshu.com/p/d4ba5eb88b3f

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值