Android 播放SD卡视频 Demo

Android播放视频有好几种方式,比如VideoView,SurfaceView,Android自带的播放器,第三方播放器(比如vitamio等等 之前毕设用过,挺不错)
公司需要编写相关的测试代码,简单研究了一下。做做笔记,备忘。(注:部分代码来源于互联网)

使用VideoView播放视频:

布局文件:很简单,VideoView+几个button,用线性布局简单控制一下

<LinearLayout 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:orientation="vertical"
    tools:context=".MainActivity" >

    <VideoView
        android:id="@+id/videoview"
        android:layout_width="fill_parent"
        android:layout_height="200dp" />

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

        <Button
            android:id="@+id/play"
            android:text="play"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <Button
            android:id="@+id/pause"
            android:text="pause"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <Button
            android:id="@+id/replay"
            android:text="replay"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
    </LinearLayout>

</LinearLayout>

继续操作之前,先在SD卡根目录放置一个视频文件1.mp4(先使用固定路径,之后再使用动态设置的路径)
下面继续写MainActivity:

public class MainActivity extends Activity implements OnClickListener {

    private static final String TAG = "MainActivity";
    VideoView video;
    Button play;
    Button pause;
    Button replay;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        video = (VideoView) findViewById(R.id.videoview);
        play = (Button) findViewById(R.id.play);
        pause = (Button) findViewById(R.id.pause);
        replay = (Button) findViewById(R.id.replay);
        play.setOnClickListener(this);
        pause.setOnClickListener(this);
        replay.setOnClickListener(this);
        logcat("onCreate");
        initVediopath();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != video) {
            video.suspend();
        }
    }

    private void initVediopath() {
        logcat("initVediopath");
        File file = new File(Environment.getExternalStorageDirectory(), "1.mp4");
        logcat("" + Environment.getExternalStorageDirectory());
        if (file.exists()) {
            logcat("setPath");
            video.setVideoPath(file.getPath());
        } else {
            Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();
            logcat("file not exsit");
        }

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.play:
            if (!video.isPlaying()) {
                video.start();
            }
            break;
        case R.id.pause:
            if (video.isPlaying()) {
                video.pause();
            }
            break;
        case R.id.replay:
            if (video.isPlaying()) {
                video.resume();
            }
            break;

        default:
            break;
        }
    }

    public void logcat(String log) {
        Log.i(TAG, log);
    }
}

MainActivity也很简单,findv的iew,设置listener,设置视频路径,Activity销毁时将VideoView挂起。按钮 的点击事件也就简单的调用VideoView的相关方法。
最后别忘了添加读取SD卡的权限

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

使用 SurfaceView+MediaPlayer播放视频

MediaPlayer控制视频,SurfaceView负责显示(个人理解,有误请帮忙指出,另外此部分代码大部分参考某篇博客,但是暂时找不到原文了。。。)
布局文件:和上面类似,不过把VideoView换成SurfaceView,另外多了几个button

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="1"
    android:orientation="vertical" >
    <SurfaceView
        android:id="@+id/surfaceVIew"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="0.15"
        tools:context=".MainActivity" />
    <LinearLayout 
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="0.85">
        <Button 
            android:id="@+id/btn_play"
            android:text="开始"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button 
           android:id="@+id/btn_pause"
            android:text="暂停"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button 
          android:id="@+id/btn_stop"
            android:text="停止"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button 
           android:id="@+id/btn_low"
            android:text="调低"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button 
           android:id="@+id/btn_hight"
            android:text="调高"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</LinearLayout>

与上面一样,先使用死路径,在SD卡根目录放置1.mp4。同时先把访问SD卡的权限加上吧。

主Activity:
和上面的步骤类似,不过稍微复杂些。主要是SurfaceView有三个callback
surfaceCreated
surfaceChanged
surfaceDestroyed
在SurfaceView创建时做一些视频的初始化操作。
在SurfaceView销毁时释放资源
横竖屏的地方暂时可以忽略。大体上和上面还是一样的。

public class MainActivity extends Activity implements OnClickListener {
    /* 功能按钮 */
    private Button btn_play, btn_pause, btn_stop, btn_low, btn_height;
    /* SurfaceView */
    private SurfaceView mSurfaceView;
    /* 播放视频对象 */
    private MediaPlayer mediaPlayer;
    /* 系统声音 */
    private AudioManager audioManager;
    /* 记录播放位置 */
    private int position;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /* 设置窗口无title */
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        /* 全屏显示 */
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        findViews();
        setListeners();
        mediaPlayer = new MediaPlayer();
        setSurfaceView();

    }

    // 横竖屏切换时的处理
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {// 如果在播放的时候切换屏幕则保存当前观看的位置
            outState.putInt("position", mediaPlayer.getCurrentPosition());
        }
        super.onSaveInstanceState(outState);
    }

    // 横竖屏切换后的处理
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        if (savedInstanceState.containsKey("position")) {
            position = savedInstanceState.getInt("position");// 取得切换屏幕时保存的位置
        }
        super.onRestoreInstanceState(savedInstanceState);
    }

    /* 实例化UI */
    private void findViews() {
        btn_play = (Button) findViewById(R.id.btn_play);
        btn_pause = (Button) findViewById(R.id.btn_pause);
        btn_stop = (Button) findViewById(R.id.btn_stop);
        btn_low = (Button) findViewById(R.id.btn_low);
        btn_height = (Button) findViewById(R.id.btn_hight);
        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceVIew);
        audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
    }

    /* 为5个按钮设置监听 */
    private void setListeners() {
        btn_play.setOnClickListener(this);
        btn_pause.setOnClickListener(this);
        btn_stop.setOnClickListener(this);
        btn_low.setOnClickListener(this);
        btn_height.setOnClickListener(this);
    }

    /* 播放视频 */
    private void playMedia() {
        /* 初始化状态 */
        mediaPlayer.reset();
        /* 设置声音流类型 */
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        /* 设置mp3\mp4加载路径 */
        File file = new File(Environment.getExternalStorageDirectory(), "1.mp4");
        try {
            mediaPlayer.setDataSource(file.getAbsolutePath());
            // 缓冲
            mediaPlayer.prepare();
            // 开始播放
            mediaPlayer.start();
            // 具体位置
            Log.i("position", position + "------");
            mediaPlayer.seekTo(position);
            // 视频输出到View
            mediaPlayer.setDisplay(mSurfaceView.getHolder());
            // 重置位置为0
            position = 0;
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /* 设置surfaceView视图 */
    private void setSurfaceView() {
        // creates a "push" surface
        mSurfaceView.getHolder().setType(
                SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        // 设置事件,回调函数
        mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            /* SurfaceView创建时 */
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                if (position > 0) {
                    playMedia();
                    position = 0;
                }
            }

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

            /* SurfaceView销毁视图 */
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.stop();
                }
                /* Activity销毁时停止播放,释放资源。不做这个操作,即使退出,还是能听到视频的声音 */
                mediaPlayer.release();
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btn_play:// 播放
            if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                return;
            } else {
                playMedia();
            }
            break;
        case R.id.btn_pause:// 暂停
            if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                position = mediaPlayer.getCurrentPosition();
                mediaPlayer.pause();
            } else {
                return;
            }
            break;
        case R.id.btn_stop:// 停止
            if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
                position = 0;
            } else {
                return;
            }
            break;
        case R.id.btn_low:// 调小音量
            // 获取当前的音乐音量
            int volume = audioManager
                    .getStreamVolume(AudioManager.STREAM_MUSIC);
            Log.v("Volume", "volume" + volume);
            // 音量>0
            if (volume > 0) {
                audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
                        AudioManager.ADJUST_LOWER, 0);
            } else {
                return;
            }
            break;
        case R.id.btn_hight:// 调大音量
            volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
            // 音量<100
            if (volume < audioManager
                    .getStreamMaxVolume(AudioManager.STREAM_MUSIC)) {
                audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
                        AudioManager.ADJUST_RAISE, 0);
            } else {
                return;
            }
            break;
        }
    }

}

下一篇说下如何扫描SD卡的视频文件,并会附上本文中的案例和一个播放MP3的demo

以下是一个Android音乐播放demo,支持本地sd卡路径下.mp3文件播放,上下歌曲切换,暂停、播放功能,手动控制进度条,支持安卓8.1+(需要apk访问sd卡权限)。具体实现可以参考以下步骤: 1.在AndroidManifest.xml文件中添加读写SD卡权限: ```xml <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> ``` 2.在布局文件中添加音乐播放相关的控件: ```xml <Button android:id="@+id/btn_previous" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="上一首" /> <Button android:id="@+id/btn_play_pause" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="播放" /> <Button android:id="@+id/btn_next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下一首" /> <SeekBar android:id="@+id/seek_bar" android:layout_width="match_parent" android:layout_height="wrap_content" /> ``` 3.在Activity中实现音乐播放相关的逻辑: ```java public class MainActivity extends AppCompatActivity implements View.OnClickListener { private MediaPlayer mediaPlayer; private Button btnPrevious; private Button btnPlayPause; private Button btnNext; private SeekBar seekBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnPrevious = findViewById(R.id.btn_previous); btnPlayPause = findViewById(R.id.btn_play_pause); btnNext = findViewById(R.id.btn_next); seekBar = findViewById(R.id.seek_bar); btnPrevious.setOnClickListener(this); btnPlayPause.setOnClickListener(this); btnNext.setOnClickListener(this); mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { seekBar.setMax(mediaPlayer.getDuration()); mediaPlayer.start(); } }); mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { btnPlayPause.setText("播放"); } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_previous: // 上一首 break; case R.id.btn_play_pause: // 播放/暂停 if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); btnPlayPause.setText("播放"); } else { mediaPlayer.start(); btnPlayPause.setText("暂停"); } break; case R.id.btn_next: // 下一首 break; } } @Override protected void onDestroy() { super.onDestroy(); mediaPlayer.release(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值