Android使用SurfaceView播放视频 简单介绍

原创 2016年05月30日 14:25:27

Android中播放视频,简单就直接用VideoView,这是系统集成的一个视频播放组件,使用起来还是比较方便的。

这里要写的是使用SurfaceView播放视频,SurfaceView的方便之处我不再多说,具体使用方法如下。

直接上代码:

布局文件长这样:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_black">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true">

        <SurfaceView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/video_surfaceview"
            android:layout_centerInParent="true">
        </SurfaceView>

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/layout_loading"
            android:gravity="center"
            android:visibility="visible"
            android:layout_centerInParent="true">

            <ProgressBar
                style="?android:attr/progressBarStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/progressBar3" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="正在加载..."
                android:id="@+id/tv_loading"
                android:textColor="@color/color_white"
                android:layout_marginLeft="5dp" />

        </LinearLayout>
    </RelativeLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="#88000000"
        android:padding="5dp"
        android:gravity="center_vertical">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btn_play"
            android:src="@mipmap/media_pause_ic" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="10dp"
            android:paddingRight="5dp"
            android:layout_marginLeft="10dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="00:00"
                android:id="@+id/tv_end_time"
                android:textColor="@color/color_white"
                android:layout_marginLeft="5dp"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true" />

            <SeekBar
                android:id="@+id/seekBar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/Widget.SeekBar.Normal"
                android:layout_toLeftOf="@+id/tv_end_time"
                android:layout_centerVertical="true" />


        </RelativeLayout>


    </LinearLayout>

</RelativeLayout>

然后在Activity中使用,用SurfaceHolder.Callback,不多说,直接上代码:

大致内容是这样的:

public class MediaPlayActivity extends Activity implements SurfaceHolder.Callback{
public static final String NATIVE_MEDIA_URLS = "native_media";
private  MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private SurfaceHolder mHolder;
private boolean isShow = false;

private ImageView btnPlay;
private SeekBar mSeekBar;
private TextView tvEndTime;
private Timer mTimer;
private int surfaceWidth,surfaceHeight;

private View loadingView;
private TextView tvLoading;
private  String mediaUrl;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    this.setContentView(R.layout.screen_media_player);
    isShow = true;
    mediaUrl = getIntent().getStringExtra("mediaUrl");
    registerComponent();


}
private void registerComponent(){

    mPreview = (SurfaceView)findViewById(R.id.video_surfaceview);
    mPreview.setFocusable(true);

    mHolder = mPreview.getHolder();
    mHolder.addCallback(this);
    btnPlay = (ImageView)this.findViewById(R.id.btn_play);
    btnPlay.setImageResource(R.mipmap.media_pause_ic);
    btnPlay.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (isPlaying()) {
                pauseMedia();
            } else {
                replayMedia();
            }
            setMediaPlayerStatus(isPlaying());
        }
    });

    mSeekBar = (SeekBar)this.findViewById(R.id.seekBar);
    mSeekBar.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 (mMediaPlayer != null) {
                mMediaPlayer.seekTo(seekBar.getProgress() * 1000);
            }
            setMediaPlayerStatus(isPlaying());
        }
    });
    tvEndTime = (TextView)this.findViewById(R.id.tv_end_time);


    loadingView = this.findViewById(R.id.layout_loading);
    loadingView.setVisibility(View.GONE);

    tvLoading = (TextView)this.findViewById(R.id.tv_loading);
}


private void setMediaPlayerStatus(boolean playing){
    if(playing){
        btnPlay.setImageResource(R.mipmap.media_pause_ic);
    }else{
        btnPlay.setImageResource(R.mipmap.media_play_ic);
    }
}
private void setProgress(int duration,int max){

    int time = (max-duration)/1000;
    mSeekBar.setMax(max / 1000);
    if(duration<50)
        mSeekBar.setProgress(0);
    else
    mSeekBar.setProgress((duration / 1000)+1);
    tvEndTime.setText(String.format("%02d", time / 60) + ":" + String.format("%02d", time));
}


private void startTimer(){

    if(mTimer == null){
        mTimer = new Timer();
    }
    setProgress(-1, mMediaPlayer.getDuration());
    mTimer.schedule(new TimerTask() {
        @Override
        public void run() {
            if (isPlaying()) {
                mHandler.sendEmptyMessage(0);
            }
        }
    }, 0, 1000);
}

private Handler mHandler = new Handler(){

    public void handleMessage(Message msg){
        setProgress(mMediaPlayer.getCurrentPosition(),mMediaPlayer.getDuration());
    }
};

private void initMedia(Uri uri){

    mMediaPlayer = new MediaPlayer();
    mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {

            setMediaPlayerStatus(false);
            setProgress(-1, mMediaPlayer.getDuration());
            //mMediaPlayer.seekTo(500);
        }
    });
    mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(MediaPlayer mediaPlayer, int whatError, int extra) {

            Toast("播放失败");
            releaseMedia();
            return true;
        }
    });


    mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mediaPlayer) {

            resetDisplay(mWidth, mHeight);
            //setProgress(mMediaPlayer.getCurrentPosition()+1, mMediaPlayer.getDuration());


            loadingView.setVisibility(View.GONE);
            setMediaPlayerStatus(true);
        }
    });

    mMediaPlayer.setDisplay(mHolder);
}


private  void resetDisplay(int width,int height){

    int vWidth = mMediaPlayer.getVideoWidth();
    int vHeight = mMediaPlayer.getVideoHeight();

    float scale = 1.0f * width / vWidth;
    if (vWidth < vHeight) {
        scale = 1.0f * height / vHeight;
    }

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int) (vWidth * scale), (int) (vHeight * scale));
    params.addRule(RelativeLayout.CENTER_HORIZONTAL);
    params.addRule(RelativeLayout.CENTER_VERTICAL);
    mPreview.setLayoutParams(params);

    mMediaPlayer.setDisplay(mHolder);
}



private void playMedia(Uri uri){
    if(mMediaPlayer == null){
        initMedia(uri);
    }
    mMediaPlayer.reset();
    try {
        mMediaPlayer.setDataSource(this, uri);
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mMediaPlayer.prepare();
        startTimer();
        mMediaPlayer.start();


    }catch(Exception e){
        e.printStackTrace();
        Toast("播放失败");
    }
}


private void pauseMedia(){

    if (mMediaPlayer != null) {
        mMediaPlayer.pause();
    }
}

private void replayMedia(){

    if(mMediaPlayer != null){
        mMediaPlayer.start();
    }
}


private boolean isPlaying(){

    if(mMediaPlayer != null){
            return mMediaPlayer.isPlaying();
    }
    return false;
}


private void releaseMedia(){
    if(mTimer != null){
        mTimer.cancel();
        mTimer = null;
    }
    if (mMediaPlayer != null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
    }
}
public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
   //播放本地视频

       playMedia(Uri.fromFile(new File(mediaUrl)));
  //若是网络视频,可先下载,然后播放
}

public void surfaceChanged(SurfaceHolder arg0, int format, int width, int height) {
    // TODO Auto-generated method stub

    this.surfaceWidth = width;
    this.surfaceHeight = height;

}

public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    releaseMedia();
}
public void onPause(){
    isShow = false;
    super.onPause();
    pauseMedia();
    setMediaPlayerStatus(isPlaying());
}


public void onDestroy(){
    super.onDestroy();
    releaseMedia();
}
}

如此便可以使用surfaceview来播放视频了。其中细节不到位之处,只能自行补全。

版权声明:本文为博主原创文章,未经博主允许不得转载。

使用SurfaceView播放视频

说明: 看百思上面第一次启动时有个视频短片介绍,本来打算用VideoView播放视频呢!可扯淡的是怎么也不能控制与父控件的大小.....索性用SurfaceView进行播放期间也有可多坑!!!!...
  • u014360817
  • u014360817
  • 2016年04月05日 16:40
  • 2252

SurfaceView和Mediaplayer实现播放网络和本地视频 一

SurfaceView Mediaplayer
  • qq_33544860
  • qq_33544860
  • 2016年04月14日 13:04
  • 4868

使用SurfaceView播放视频,调节进度,滑动屏幕调节音量并显示音量。

效果展示: 首先在清单文件中注册: java代码: public class MainActivity extends AppCompatActivity implements Surfac...
  • Carry_Code
  • Carry_Code
  • 2016年06月06日 20:54
  • 1712

Android用SurfaceView播放本地视屏(音频)文件

我们知道Android中可以使用VideoView播放视频,而且操作简单、方便。除此之外,我们还可以利用MediaPlayer用来播放视频,不过MediaPlayer主要用于播放音频,没有提供输出图像...
  • true100
  • true100
  • 2015年03月06日 13:35
  • 1426

Android 多媒体应用:视频播放之VideoView与SurfaceView

为什么要学习VideoView与SurfaceView VideoView 主函数程序 布局 SurfaceView SurfaceView的介绍 SurfaceView使用 主函数 布局为什么要学习...
  • liujiaoruiIT
  • liujiaoruiIT
  • 2015年09月16日 10:15
  • 3033

Android开发06_VideoView、SurfaceView两种视频播放器

一、前言 Android中视频播放的方式有两种,一种是使用系统封装好的VideoView,使用起来比较方便,系统API把所有播放的内容都封在了这个类中,唯一不足的是无法自定义,比如你想修改播放的进度条...
  • baidu_17619859
  • baidu_17619859
  • 2016年12月22日 17:48
  • 2374

使用SurFaceView实现视频播放

前言:虽然ViedoView控件可以播放视频,但播放的位置和大小并不受我们的控制,为了对视频有更好的控制权,可以使用MediaPlayer配合SurfaceView来播放视频。 实现效果: ...
  • Menixle
  • Menixle
  • 2016年04月21日 20:26
  • 5722

简单的MediaPlayer+SurfaceView实现视频横竖屏播放

一.概述    目前就我的认知中,Android实现视频播放的话,有2中方式,第一种是MediaPlayer+surfaceView实现,第二种是直接用VideoView来实现,当然市面上也有一些主流...
  • twoStepFromHell
  • twoStepFromHell
  • 2016年08月22日 16:36
  • 2889

使用VIEWPAGER+SURFACEVIEW实现视频的循环滑动播放(一)

本文还是使用VIERPAGER来做视频切换。
  • yangchengtest
  • yangchengtest
  • 2017年02月19日 23:22
  • 1070

android Multimedia实战(一)详解SurfaceView,TextureView之播放视频的四种方式

在Android中,我们有四种方式来实现视频的播放: 1、使用其自带的播放器。指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型。2、使用VideoView来播放。...
  • King1425
  • King1425
  • 2017年04月25日 20:24
  • 2928
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android使用SurfaceView播放视频 简单介绍
举报原因:
原因补充:

(最多只允许输入30个字)