视频播放器在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());
}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播放器:
播放效果:
库下载地址: https://github.com/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);
控件引用:
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'
使用控件:
使用类:
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没加入到本篇博客,写完后会在此加入链接。哎呀妈呀,终于敲完了。