9.4--播放多媒体文件

手机上最常见的休闲方式毫无疑问就是听音乐和看电影了,随着移动设备的普及,越来越多的人都可以随时享受优美的音乐,以及观看精彩的电影。而Android在播放音频和视频方面也是做了相当不错的支持,它提供了一套较为完整的API,使得开发者可以很轻松地编写出一个简易的音频或视频播放器,下面我们就来具体地学习一下。

 

9.4.1 播放音频

在Android中播放音频文件一般都是使用MediaPlayer类来实现的,它对多种格式的音频文件提供了非常全面的控制方法,从而使得播放音乐的工作变得十分简单。下表列出了MediaPlayer类中一些较为常用的控制方法。

 

简单了解了上述方法后,我们再来梳理一下MediaPlayer 的工作流程。首先需要创建一个MediaPlayer对象,然后调用setDataSource() 方法设置音频文件的路径,再调用prepra() 方法使MediaPlayer 进入准备状态,接下来调用start() 方法就可以开始播放音频,调用pause() 方法就会暂停播放,调用reset() 方法就会停止播放。

下面我们就通过一个具体的例子来学习一下吧,新建一个PlayAudioTest 项目,然后修改activity_main.xml 中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/play"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Play"
        />
    <Button
        android:id="@+id/pause"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Pause"
        />
    <Button
        android:id="@+id/stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Stop"
        />

</LinearLayout>

布局文件中放置了3个按钮,分别用于对音频文件进行播放、暂停和停止操作。

MediaPlayer 可以用于播放网络、本地以及应用程序安装包中的音频。这里简单起见,就以播放应用程序安装包中的音频来距离吧。

Android Studio 允许我们在项目上创建一个assets 目录,并在这个目录下存放任意文件和子目录,车协文件和子目录在项目打包时会一并被打包到安装文件中,然后我们在程序中就可以借助AssetManager 这个类提供的接口对assets 目录下的文件进行读取。

它必须创建在app/src/main 这个目录下,也就是和java、res 这两个目录是平级的。右击app/src/main → New → Directory ,在弹出的对话框中输入“assets”,目录创建就完成了。

运输我们要播放音频文件,这里我提前准备好了一份music.mp3 资源将它放入assets 目录即可。

然后修改MainActivity 中的代码,如下所示:

class MainActivity : AppCompatActivity() {
    private val mediaPlayer = MediaPlayer()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initMediaPlayer()
        play.setOnClickListener {
            if (!mediaPlayer.isPlaying){
                mediaPlayer.start()
            }
        }
        pause.setOnClickListener {
            if (mediaPlayer.isPlaying){
                mediaPlayer.pause()
            }
        }
        stop.setOnClickListener {
            if (mediaPlayer.isPlaying){
                mediaPlayer.reset() // 停止播放 -- 重置
                initMediaPlayer()
            }
        }
    }

    private fun initMediaPlayer() {
        val assetManager = assets  // 拿到asset 管理者
        val fd = assetManager.openFd("music.mp3")
        mediaPlayer.setDataSource(fd.fileDescriptor,fd.startOffset,fd.length)
        mediaPlayer.prepare()
    }

    override fun onDestroy() {
        super.onDestroy()
        mediaPlayer.stop()
        mediaPlayer.release()
    }
}

可以看到,在类初始化的时候我们就先创建了一个MediaPlayer的实例,然后在onCreate()方法中调用initMediaPlayer() 方法,为MediaPlayer 对象进行初始化操作。在initMediaPlayer() 方法中,首先通过getAssets() 方法得到了一个AssetManager 的实例,AssetManager  可用于读取 assets 目录下的任何资源。接着我们调用了openFd() 方法将音频文件句柄打开,后面用依次调用了setDataSource() 方法和prepare() 方法,为MediaPlayer 做好了播放前的装备。

接下来我们看一下各个按钮的点击事件中的代码。当点击Play按钮时会进行判断,如果当前MediaPlayer没有正在播放音频,则调用start()方法开始播放。当点击Pause按钮时会判断,如果当前MediaPlayer正在播放音频,则调用pause()方法暂停播放。当点击Stop按钮时会判断,如果当前 MediaPlayer正在播放音频,则调用reset()方法将MediaPlayer重置为刚刚创建的状态,然后重新调用一遍initMediaPlayer()方法。

最后在onDestroy()方法中,我们还需要分别调用stop()方法和release()方法,将与MediaPlayer相关的资源释放掉。

这样一个简易版的音乐播放器就完成了,现在将程序运行到手机上。

点击一下Play按钮,优美的音乐就会响起,然后点击Pause按钮,音乐就会停住,再次点击Play按钮,会接着暂停之前的位置继续播放。这时如果点击一下Stop按钮,音乐也会停住,但是当再次点击Play按钮时,音乐就会从头开始播放了。

 

9.4.2 播放视频

播放视频文件其实并不比播放音频文件复杂,主要是使用VideoView类来实现的。这个类将视频的显示和控制集于一身,我们仅仅借助它就可以完成一个简易的视频播放器。VideoView 的用法和 MediaPlayer 也比较类似,常用方法如下所示:

我们还是通过一个实际的例子来学习一下吧,新建PlayVideoTest 项目,然后修改activity_main.xml中的代码,如下所示:

<?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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <Button
            android:id="@+id/play"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Play"
            />
        <Button
            android:id="@+id/pause"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Pause"
            />
        <Button
            android:id="@+id/replay"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Replay"
            />
    </LinearLayout>
    <VideoView
        android:id="@+id/videoView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

</LinearLayout>

这个布局文件中同样防止了3个按钮,分别用于控制食品的播放,暂停和重新播放。另外在按钮下面又防止了一个VideoView,稍后的视频就将在这里显示。

接下来的问题就是存放视频资料了,很可惜的是,VideoView不支持直接播放assets目录下的视频资源,所以我们只能寻找其他的解决方案。res目录下允许我们在创建一个raw 目录,像诸如音频、视频之类的资源文件也可以放在这里,并且VideoView 是可以直接播放这个目录下的视频资源的。

现在右击app/src/main/res → New → Directory,在弹出的对话框中输入 “raw”,完成raw 目录的创建,并把腰播放的视频资源放在里面。这里我提前准备了一个video.mp4 资源,你也可以自己准备资源。

然后修改MainActivity 中的代码,如下所示:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val uri = Uri.parse("android.resource://$packageName/${R.raw.video}")
        videoView.setVideoURI(uri)
        play.setOnClickListener {
            if (!videoView.isPlaying){
                videoView.start()
            }
        }
        pause.setOnClickListener {
            if (videoView.isPlaying){
                videoView.pause()
            }
        }
        replay.setOnClickListener {
            if (videoView.isPlaying){
                videoView.resume() // 重新播放
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        videoView.suspend()
    }
}

这段代码现在看起来接非常渐渐地了,因为它和前面播放音频的代码比较类似。我们首先在onCreate() 方法中调用了Uri.parse() 方法,将raw 目录下的video.mp4 文件解析成了一个Uri 对象,这里使用的写法是Android 要求的固定写法。然后调用VideoView 的setViedeoURI() 方法将刚才解析出来的Uri 对象传入,这样VideoView 就初始化完成了。

下面看一下各个按钮的点击事件中的代码。当点击Play按钮时会进行判断,如果当前并没有正在播放视频,则调用start() 方法开始播放。当点击Pause按钮时会判断,如果当前视频正在播放,则调用pause() 方法暂停播放。当点击Replay按钮时会判断,如果当前视频正在播放,则调用resume() 方法从头播放视频。

最后在onDestroy() 方法中,我们还需要调用一下suspend() 方法,将VideoView所占用的资源释放掉。

现在将程序运行到手机上,会先弹出一个权限申请对话框,同意授权之后点击一下Play按钮,就可以看到视频已经开始播放了。

点击Pause按钮可以暂停视频的播放,点击Replay 按钮可以从头播放视频。

这样的话,你就已经将VideoView的基本用法掌握得差不多了。不过,为什么它的用法和MediaPlayer 这么相似呢?其实VideoView只是帮我们做了一个很好的封装而已,它的背后仍然是使用MediaPlayer 来对视频文件进行控制的。另外需要注意,VideoView并不是一个万能的视频播放工具类,它在视频格式的支持以及播放效率方面都存在着较大的不足。所以,如果想要仅仅使用VideoView就编写出一个功能非常强大的视频播放器是不太现实的。但是如果只是用于播放一些游戏的片头动画,或者某个应用的视频宣传,使用VideoView还是绰绰有余的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值