Android 视频播放器SurfaceView+Mediaplayer

来源:互联网 发布:淘宝只能换绑不能解绑 编辑:程序博客网 时间:2024/05/16 17:43

项目简介:

该项目为视频播放器,使用MediaPlayer+SurfaceView实现
另外,使用VideoView实现视频播放请到这里去
使用别的开源框架vatimio实现视频播放的请到这里去

详细介绍:

用户点击 按钮后,进入播放界面,接下来将会播放一个视频,用的是MediaPlayer+SurfaceView实现

该应用涉及到的知识有:

  • 1.MediaPlayer的使用
      MediaPlayer的功能是强大的,但是同时又是弱小的。
      强大:既可以用于播放视频,也可以用于播放音频。
      弱小:播放音频仅支持 wmv 和 mp4 ;播放视频仅支持 3gp 和H.264编码的mp4格式
  • 2.SurfaceView的使用
      SurfaceView是一个重量级组件,它占用的资源十分多。
      SurfaceView使用的双缓冲技术,该技术常用在对UI刷新要求较高的场景中
      SurfaceView的特性是:当该控件可见时,就创建;当该控件不可见时,就销毁。所以,一旦点击返回键或者home,SurfaceView就会销毁并释放资源;再次进入播放界面,SurfaceView就会被重新创建

注意:

  • 1.SurfaceView 一定要可见并加载好的时候才能播放视频,所以,一定要等待SurfaceView创建好了之后再创建MediaPlayer。在SurfaceView 中无法设置侦听,所以用回调函数,功能与侦听一样
  • 2.MediaPlayer设置资源路径的时候一定要注意,如果出错可能会导致各种各样奇怪的错误。有的时候是路径设置对的,但是可能是文件格式不支持,也会出现各种奇葩错误。
  • 3.注意,在模拟器中可能出现视频播放时只有声音而没事图像的情况,这与代码无关。2.x的模拟器可以显示出来。但是最好使用真机。

步骤:

1.创建一个Android项目,创建两个布局文件,第一个布局文件为activity_mian.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="hhh.exercise.smultimedia_e3.MainActivity" >    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="click"        android:text="播放"        android:textColor="#00ff00"        android:textSize="30sp" /></RelativeLayout>

这个布局文件仅仅只有一个按钮,接下来创建第二个布局文件activity_first.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <SurfaceView        android:id="@+id/sv"        android:layout_width="match_parent"        android:layout_height="match_parent" /></LinearLayout>

这个文件仅仅只有一个SurfaceView控件。

2.创建MianActivity.java文件:

import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public void click(View view ) {        Intent it = new Intent(this, FirstActivity.class);        startActivity(it);    }}

MianActivity处理的业务非常简单,就是加载activity_main.xml布局文件,用户点击按钮后,跳转到FirstActivity,FirstActivity代码如下:

import android.app.Activity;import android.content.pm.ActivityInfo;import android.media.MediaPlayer;import android.media.MediaPlayer.OnPreparedListener;import android.os.Bundle;import android.os.Environment;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.Window;import android.view.WindowManager;import android.view.SurfaceHolder.Callback;/** * @author HHH * */public class FirstActivity extends Activity {    private SurfaceView sv;    private MediaPlayer player;    private static int currentPositon;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // 隐藏标题栏        requestWindowFeature(Window.FEATURE_NO_TITLE);        // 设置横屏        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);        // 设置屏幕常量        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);        setContentView(R.layout.activity_first);        sv = (SurfaceView) findViewById(R.id.sv);        // 拿到SurfaceView的控制器        final SurfaceHolder sh = sv.getHolder();        /**         * 设置SurfaceView的回调。 SurfaceView是个重量级组件,只要不可见就不会创建该组件。         * 所以要设置一个侦听,等待SurfaceView组件可见在播放视频,然而SurfaceView是没有侦听的,只要回调。         * 一定要注意,别导错了包(import android.view.SurfaceHolder.Callback;)         */        sh.addCallback(new Callback() {            // SurfaceView销毁时调用            @Override            public void surfaceDestroyed(SurfaceHolder holder) {                // 每次SurfaceView销毁时,同时停止播放视频                if (player != null) {                    // currentPositon如果是静态变量,则该变量与进程同存亡。所以不论是home还是返回键,只要进程不死,该变量就存在                    // currentPositon如果不是静态变量,仅仅是个全局变量,则该变量与Activity共存亡。即home建该变量存在;若返回键该变量死亡,视频从头播放。                    currentPositon = player.getCurrentPosition();                    player.stop();                    player.release();                    player = null;                }            }            // SurfaceView创建时调用            @Override            public void surfaceCreated(SurfaceHolder holder) {                // SurfaceView一旦不可见就会销毁。所以每次进入播放界面,就会创建一个SurfaceView.每次推出播放界面,就会销毁SurfaceView,但是MediaPlayer不会销毁,需要手动代码销毁                // 所以,要判断一下MediaPlayer的对象是不是空,是空就创建一个播放视频,不是空就什么也不做,继续播放前面的视频                if (player == null) {                    // 创建MediaPlayer对象                    player = new MediaPlayer();                    // 重置                    player.reset();                    try {                        // 设置需要加载的资源.加载网络资源需要异步准备,加载本地资源可以同步准备                        // player.setDataSource("http://222.20.39.47:8080/AllResourceWeb/s2.3gp");                        player.setDataSource(Environment.getExternalStorageDirectory().getPath() + "/s1.3gp");                        // 指定视频播放的组件。如果没有设置,视频是无法播放的                        player.setDisplay(sh);                        // 异步准备.如果是本地视频,可以直接同步准备后就播放,不需要设置监听                        player.prepareAsync();                        // 设置侦听,用来判断当前子线程是否加载资源完毕                        player.setOnPreparedListener(new OnPreparedListener() {                            @Override                            public void onPrepared(MediaPlayer mp) {                                player.start();                                // 寻找到上次播放的位置,继续播放                                player.seekTo(currentPositon);                            }                        });                    } catch (Exception e) {                        e.printStackTrace();                    }                }            }            // SurfaceView结构改变时调用            @Override            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {            }        });    }}

FristActivity处理的业务是:加载并播放视频。

1 0
原创粉丝点击