使用VideoView播放视频文件

在上一篇写完使用MediaPlayer播放音乐之后,布局中有个可以播放视频文件的按钮,这一篇来把它完成。在这里说明一下:使用VideoView的好处是:如果你只是想要从手机中拿出视频文件来播放,VideoView自带快进快退,播放暂停的功能(它也可以用来播放音乐),还可以直接加入MediaController对象作为播放控制接口。虽然MediaPlayer也可以用来播放视频,但是必须自己准备视频的组件、播放进度条以及控制按钮。这一点,对于只需要播放视频文件来说,很麻烦。

videoview流程图

首先我们还是来看布局文件(虽然基本没怎么改...):
activity布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.myapplication.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btnPickAudio"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onPick"
            android:text="选取音乐" />

        <Button
            android:id="@+id/btnPickVideo"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onPick"
            android:text="选取视频" />

    </LinearLayout>

    <TextView
        android:id="@+id/txvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="文件名" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btnPlay"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="onMpPlay"
                android:text="播放"

                />

            <Button
                android:id="@+id/btnStop"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="onMpStop"
                android:text="停止" />

            <CheckBox
                android:id="@+id/ckbLoop"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="false"
                android:onClick="onMpLoop"
                android:text="重复播放" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:orientation="horizontal">

            <Button
                android:id="@+id/lgbInfo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="onMpInfo"
                android:text="当前播放位置" />

            <Button
                android:id="@+id/lgbBackForward"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="onMpBackWard"
                android:text="后退" />

            <Button
                android:id="@+id/lgbForward"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="onMpForward"
                android:text="前进" />

        </LinearLayout>

    </LinearLayout>

    <TextView
        android:id="@+id/txvUri"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="路径" />
</LinearLayout>

这里新建了一个VideoActivity,用来控制视频文件的播放
video布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_video"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    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="com.example.myapplication.Video">
    <VideoView
        android:id="@+id/videoView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:onClick="onMpStop" />
</LinearLayout>

万年不变的MainActivity

public class MainActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {

    Uri uri;
    TextView txvName, txvUri;
    boolean isVideo = false;

    Button btnPlay, btnStop;
    CheckBox ckbLoop;
    MediaPlayer mper;
    Toast tos;

    String uri2="";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        txvName = (TextView) findViewById(R.id.txvName);
        txvUri = (TextView) findViewById(R.id.txvUri);

        btnPlay = (Button) findViewById(R.id.btnPlay);
        btnStop = (Button) findViewById(R.id.btnStop);
        ckbLoop = (CheckBox) findViewById(R.id.ckbLoop);


        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);//屏幕不随手机旋转
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//屏幕竖屏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//保持屏幕不休眠

        uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.diantaiqingge);
        txvName.setText("电台情歌");
        txvUri.setText("程序内曲目:" + uri.toString());

        mper = new MediaPlayer();
        mper.setOnPreparedListener(this);
        mper.setOnErrorListener(this);
        mper.setOnCompletionListener(this);
        tos = Toast.makeText(this, "", Toast.LENGTH_SHORT);
        prepareMusic();
    }

    private void prepareMusic() {
        btnPlay.setText("播放");
        btnPlay.setEnabled(false);
        btnStop.setEnabled(false);
        try {
            mper.reset();
            mper.setDataSource(this, uri);
            mper.setLooping(ckbLoop.isChecked());
            mper.prepareAsync();
        } catch (IOException e) {
            tos.setText("指定音乐文件错误!" + e.toString());
            tos.show();
        }

    }

    public void onPick(View view) {
        Intent it = new Intent(Intent.ACTION_GET_CONTENT);
        if (view.getId() == R.id.btnPickAudio) {
            it.setType("audio/*");
            startActivityForResult(it, 100);
        } else {
            it.setType("video/*");
            startActivityForResult(it, 101);
        }

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == 100) {
                isVideo = false;
                uri = convertUri(data.getData());
                txvName.setText(isVideo ? "视频" : "音频" + uri.getLastPathSegment());
                txvUri.setText("文件位置:" + uri.getPath());
                if (!isVideo) {
                    prepareMusic();
                }
            } else {
                isVideo = true;
                uri2=UriUtils.getPath(this,data.getData());
                uri2="file://"+uri2;
                //uri = convertUri(data.getData());
                txvName.setText(isVideo ? "视频" : "音频" + uri2.toString());
                txvUri.setText("文件位置:" + uri2.toString());
            }
        }
    }

    Uri convertUri(Uri uri) {
        if (uri.toString().substring(0, 7).equals("content")) {//以content开头的图像文件需要转换成file开头的文件路径
            String[] colName = {MediaStore.MediaColumns.DATA};//声明要查询的字段
            Cursor cursor = getContentResolver().query(uri, colName, null, null, null);
            cursor.moveToFirst();//移到查询结果的第一个记录
            uri = Uri.parse("file://" + cursor.getString(0));//将路径转化为uri
            cursor.close();
        }
        return uri;
    }

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        //当准备好时,让播放按钮起作用
        btnPlay.setEnabled(true);
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
//当播放完毕时
        mper.seekTo(0);//播放位置归0
        btnPlay.setText("播放");
        btnStop.setEnabled(false);

    }

    @Override
    public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
        tos.setText("发生错误,停止播放");
        tos.show();
        return true;
    }

    public void onMpPlay(View v) {
        //视频播放
        if (isVideo) {
            Intent it = new Intent(this, Video.class);
            it.putExtra("uri", uri2);
            startActivity(it);
            return;
        }


        //音乐播放
        if (mper.isPlaying()) {//正在播放就暂停
            mper.pause();
            btnPlay.setText("继续");
        } else {
            mper.start();
            btnPlay.setText("暂停");
            btnStop.setEnabled(true);


        }
    }

    public void onMpStop(View v) {
        //音乐停止
        mper.pause();
        mper.seekTo(0);
        btnPlay.setText("播放");
        btnStop.setEnabled(false);
    }

    public void onMpLoop(View v) {
        //是否循环
        if (ckbLoop.isChecked()) {
            mper.setLooping(true);
        } else {
            mper.setLooping(false);
        }
    }

    public void onMpBackWard(View v) {
        //前进
        if (!btnPlay.isEnabled()) {
            return;
        }
        int len = mper.getDuration();
        int pos = mper.getCurrentPosition();
        pos -= 10000;
        if (pos < 0) {
            pos = 0;
        }
        mper.seekTo(pos);
        tos.setText("倒退10秒:" + pos / 1000 + "/" + len / 1000);
        tos.show();

    }

    public void onMpForward(View v) {
        //后退
        if (!btnPlay.isEnabled()) {
            return;
        }
        int len = mper.getDuration();
        int pos = mper.getCurrentPosition();
        pos += 10000;
        if (pos > len) {//不可大于音频长度
            pos = len;
        }
        mper.seekTo(pos);
        tos.setText("前进10秒:" + pos / 1000 + "/" + len / 1000);
        tos.show();

    }

    public void onMpInfo(View v) {
        //当前播放位置
        if (!btnPlay.isEnabled()) {//
            return;
        }
        int len = mper.getDuration();
        int pos = mper.getCurrentPosition();

        mper.seekTo(pos);
        tos.setText("当前位置:" + pos / 1000 + "/" + len / 1000);
        tos.show();

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mper.isPlaying()) {
            btnPlay.setText("继续");
            mper.pause();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mper.release();

    }
}

本例中新建的VideoActivity

public class Video extends AppCompatActivity implements MediaPlayer.OnCompletionListener {
    VideoView vdv;
    int pos = 0;

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

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//隐藏系统状态栏
        getSupportActionBar().hide();//隐藏Activity标题栏

        setContentView(R.layout.activity_video);

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        Intent it = getIntent();
        Uri uri = Uri.parse(it.getStringExtra("uri"));
        if (savedInstanceState != null) {
            //如果因为旋转启动了activity
            pos = savedInstanceState.getInt("pos", 0);//获取旋转钱的位置
        }
        vdv = (VideoView) findViewById(R.id.videoView);
        MediaController mediaCtrl = new MediaController(this); //建立播放控制对象
        vdv.setMediaController(mediaCtrl);//设置播放控制对象
        vdv.setVideoURI(uri);
        vdv.setOnCompletionListener(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //重启或者暂停后启动
        vdv.seekTo(pos);
        vdv.start();

    }

    @Override
    protected void onPause() {
        super.onPause();
        //暂停时
        pos = vdv.getCurrentPosition();//获取当前的位置
        vdv.stopPlayback();//停止播放
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //当屏幕旋转时,会销毁当前的activity再重启一个activity,可在此方法中存储销毁之前的视频播放位置
        outState.putInt("pos", pos);

    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        finish();
    }
}

大家可以看到,在这一篇中获取文件的uri我选用了一个工具类UriUtils,这个方法取自Jenly_Yu的http://blog.csdn.net/jenly121/article/details/48373861的博客,大家可以去看看。至于使用这个方法的原因:在我获取视频、音频文件的uri的时候,我使用360手机和华为手机隐式调用获取uri,同样的方法,在360N4手机下的视频(或音频)分类中可以获取到完整uri,而使用华为Mate7手机一直返回null,但是如果同样在系统管理器中打开,都可以获取uri。刚开始怀疑手机的问题,后来使用了上述那位朋友的方式,就都可以获取到,这个工具类还是蛮好用的,推荐给大家。
音频、视频我分别采用了不同的获取uri的方式,大家可以好好看看,自己选择想使用的方式。就到这里。
转载注明出处http://blog.csdn.net/u011771800/article/details/54091027

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值