zoukankan      html  css  js  c++  java
  • 一起学Android之音频视频

    概述

    Android多媒体框架支持各种常见的媒体类型,可以很容易地将音频、视频和图像集成到App中。通过MediaPlayer Api,可以从应用程序资源(RAW)、文件系统或网络上数据流资源来播放音频或视频。本文演示了如何通过Api播放音频和视频文件,来获得良好性能和愉快的用户体验,仅供学习分享使用,如有不足之处,还请指正。

    涉及知识点

    1.  MediaPlayer 可以用来控制audio/video文件或流播放的类。通过此类,可以方便的控制音频/视频文件的播放,暂停和停止等操作。
    2. Uri 统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。
    3. VideoView 自带的一种播放视频的组件。
    4. SurfaceView 可以通过后台绘制显示的视图组件。 

    Activity中播放音频

     页面上播放音频文件,步骤如下:

    1. 准备资源文件,并播放

     1 private MediaPlayer mMediaPlayer;
     2 
     3     /**
     4      * 开始
     5      * @param v
     6      */
     7     public void bn_start(View v){
     8         if(mMediaPlayer==null) {
     9             ready();
    10         }
    11         mMediaPlayer.start();
    12     }
    13 
    14  /**
    15      * 创建MediaPlayer并到prepare状态
    16      */
    17     private void ready(){
    18         if(mMediaPlayer==null){
    19             mMediaPlayer=new MediaPlayer();//Idle
    20             //Log.i("TAG", "ready: "+filePath);
    21             File file=new File(Environment.getExternalStorageDirectory(),"goldfallen.mp3");
    22             Log.i("TAG", "ready: "+file.getPath());
    23             Log.i("TAG", "ready: "+file.exists());
    24             Uri uri= Uri.fromFile(file);
    25             try {
    26                 mMediaPlayer.setDataSource(AudioActivity.this,uri);
    27                 mMediaPlayer.prepare();//Prepared
    28             } catch (IOException e) {
    29                 Log.i("TAG", "ready: "+ e.getMessage());
    30                 e.printStackTrace();
    31             }
    32         }
    33     }

    2. 暂停播放

    1 /**
    2      * 暂停
    3      * @param v
    4      */
    5     public void bn_pause(View v){
    6         if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
    7             mMediaPlayer.pause();
    8         }
    9     }

    3. 停止

     1   /**
     2      * 停止
     3      * @param v
     4      */
     5     public void bn_stop(View v){
     6         if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
     7             mMediaPlayer.stop();
     8             mMediaPlayer.release();
     9             mMediaPlayer=null;
    10         }
    11     }

    4. 释放资源(当页面销毁时,播放资源也要同时释放)

    1  @Override
    2     protected void onDestroy() {
    3         if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
    4             mMediaPlayer.stop();
    5             mMediaPlayer.release();
    6             mMediaPlayer=null;
    7         }
    8         super.onDestroy();
    9     }

    5. 通过静态函数创建对象

     1 /**
     2      * D:AndroidProjectDemoMediaappsrcmain
    es
    awA2012.mp3:
     3      * Error: 'A' is not a valid file-based resource name character:
     4      * File-based resource names must contain only lowercase a-z, 0-9, or underscore
     5      */
     6     private void ready2(){
     7         if(mMediaPlayer==null){
     8             mMediaPlayer= MediaPlayer.create(this,R.raw.ab2012);
     9         }
    10     }

    通过服务来播放音频

    当页面关闭时,音频文件还可以在后台播放。步骤如下:

    1. 定义后台服务,当服务启动时,创建MediaPlayer对象,并注册服务接收对象。

     1 public class AudioService extends Service {
     2 
     3     private MediaPlayer mMediaPlayer;
     4 
     5     private OperatorReceiver mReceiver;
     6 
     7     public AudioService() {
     8     }
     9 
    10     @Override
    11     public void onCreate() {
    12         super.onCreate();
    13         mMediaPlayer=new MediaPlayer();
    14         mReceiver=new OperatorReceiver();
    15         IntentFilter filter=new IntentFilter("operator.receiver");
    16         registerReceiver(mReceiver,filter);
    17     }
    18 
    19     @Override
    20     public IBinder onBind(Intent intent) {
    21         return null;
    22     }
    23 
    24     @Override
    25     public int onStartCommand(Intent intent, int flags, int startId) {
    26         Log.i("TAG", "onStartCommand: ----ready ");
    27         ready();
    28         return super.onStartCommand(intent, flags, startId);
    29     }
    30 
    31     @Override
    32     public void onDestroy() {
    33         if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
    34             mMediaPlayer.stop();
    35         }
    36         if(mMediaPlayer!=null){
    37             mMediaPlayer.release();
    38             mMediaPlayer=null;
    39         }
    40         unregisterReceiver(mReceiver);
    41         super.onDestroy();
    42     }
    43 
    44     private void start(){
    45         mMediaPlayer.start();
    46     }
    47 
    48     private  void pause(){
    49         mMediaPlayer.pause();
    50     }
    51 
    52     private void stop(){
    53         mMediaPlayer.stop();
    54         ready();
    55     }
    56 
    57     private void ready(){
    58         mMediaPlayer.reset();
    59         try {
    60             String filePath= Environment.getExternalStorageDirectory()+"/ab2012.mp3";
    61             Log.i("TAG", "ready: "+filePath);
    62             File file=new File(filePath);
    63             if(file.exists()) {
    64                 mMediaPlayer.setDataSource(filePath);
    65                 mMediaPlayer.prepare();
    66             }else{
    67                 Log.i("TAG", "ready: 文件不存在 ");
    68             }
    69         } catch (IOException e) {
    70             Log.i("TAG", "ready: "+e.getMessage());
    71             e.printStackTrace();
    72         }
    73     }
    74 }

    2. 操作接收者定义如下:

     1  /**
     2      * 操作接收器
     3      */
     4     class OperatorReceiver extends BroadcastReceiver
     5     {
     6         @Override
     7         public void onReceive(Context context, Intent intent) {
     8             int cmd=intent.getIntExtra("cmd",-1);
     9             Log.i("TAG", "onReceive: "+cmd);
    10             switch (cmd){
    11                 case Tools.PLAY:
    12                     start();
    13                     break;
    14                 case Tools.PAUSE:
    15                     pause();
    16                     break;
    17                 case Tools.STOP:
    18                     stop();
    19                     break;
    20                 default:
    21                     start();
    22                     break;
    23 
    24             }
    25         }
    26     }

    3. 启动服务

    1   Intent intent =new Intent(this,AudioService.class);
    2   startService(intent);

    4. 前台Activity通过发送广播命令进行控制音频的播放与暂停

     1 /**
     2      * 开始
     3      * @param v
     4      */
     5     public void bn_start(View v){
     6         Intent intent=new Intent("operator.receiver");
     7         intent.putExtra("cmd",Tools.PLAY);
     8         sendBroadcast(intent);
     9         Log.i("TAG", "bn_start: "+"service");
    10     }
    11 
    12     /**
    13      * 暂停
    14      * @param v
    15      */
    16     public void bn_pause(View v){
    17         Intent intent=new Intent("operator.receiver");
    18         intent.putExtra("cmd",Tools.PAUSE);
    19         sendBroadcast(intent);
    20     }
    21 
    22     /**
    23      * 停止
    24      * @param v
    25      */
    26     public void bn_stop(View v){
    27         Intent intent=new Intent("operator.receiver");
    28         intent.putExtra("cmd",Tools.STOP);
    29         sendBroadcast(intent);
    30     }

    5.通过后台服务的方式,需要在AndroidManifest.xml文件中进行注册

    1  <service
    2             android:name=".AudioService"
    3             android:enabled="true"
    4             android:exported="true">
    5         </service>

    通过VideoView来播放视频

     通过VideoView进行播放视频文件,只需要设置资源URI即可,具体如下:

     1  private VideoView mVideoView;
     2     @Override
     3     protected void onCreate(Bundle savedInstanceState) {
     4         super.onCreate(savedInstanceState);
     5         setContentView(R.layout.activity_video);
     6         mVideoView= (VideoView) this.findViewById(R.id.vv_info);
     7         //设置路径
     8         File file=new File(Environment.getExternalStorageDirectory(),"DCIM/Camera/VID20190629142614.mp4");
     9         Log.i("TAG", "onCreate: "+file.getPath());
    10         if(!file.exists()){
    11             Log.i("TAG", "onCreate: 文件不存在");
    12         }
    13         Uri uri=Uri.fromFile(file);
    14         mVideoView.setVideoURI(uri);
    15         //设置Media Controller
    16         MediaController controller=new MediaController(this);
    17         mVideoView.setMediaController(controller);
    18         //获取焦点
    19         mVideoView.requestFocus();
    20         mVideoView.start();
    21         //设置播放完成事件
    22         mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    23             @Override
    24             public void onCompletion(MediaPlayer mp) {
    25                 Toast.makeText(VideoActivity.this, "播放完毕", Toast.LENGTH_SHORT).show();
    26             }
    27         });
    28     }

    通过MediaPlayer来播放视频

    通过MediaPlayer来播放视频文件,然后通过SurfaceView来显示视频内容,具体步骤如下:

    1.启动,通过setDisplay来设置显示内容

     1 public  void bn_start(View view)  {
     2         mMediaPlayer.reset();//到Idle状态
     3         //设置路径
     4         File file=new File(Environment.getExternalStorageDirectory(),"DCIM/Camera/VID20190629142614.mp4");
     5         Log.i("TAG", "onCreate: "+file.getPath());
     6         if(!file.exists()){
     7             Log.i("TAG", "onCreate: 文件不存在");
     8         } else {
     9             Log.i("TAG", "onCreate: 文件存在 ");
    10         }
    11         Uri uri=Uri.fromFile(file);
    12         try {
    13             mMediaPlayer.setDataSource(this,uri);
    14             mMediaPlayer.setDisplay(mSurfaceView.getHolder());
    15             mMediaPlayer.prepare();
    16             mMediaPlayer.start();
    17         } catch (IOException e) {
    18             e.printStackTrace();
    19         }
    20     }

    2. 暂停与停止

     1  public  void bn_pause(View view){
     2         if(mMediaPlayer.isPlaying()){
     3             mMediaPlayer.pause();
     4         }
     5     }
     6 
     7     public  void bn_stop(View view){
     8         if(mMediaPlayer.isPlaying()){
     9             mMediaPlayer.stop();
    10         }
    11     }

    3. 资源释放

     1  @Override
     2     protected void onDestroy() {
     3         if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
     4             mMediaPlayer.stop();
     5         }
     6         if(mMediaPlayer!=null){
     7             mMediaPlayer.release();
     8             mMediaPlayer=null;
     9         }
    10         super.onDestroy();
    11     }

    权限设置

    如果要播放视频,需要相应的权限设置,并在安装时获取请求权限

    1     <uses-permission android:name="android.permission.INTERNET"/>
    2     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    3     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    4     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

    备注

    合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。

  • 相关阅读:
    vue-cli3.0
    windows服务器的误解
    redis实现消息队列-java代码实现
    Docker 修改容器内的时区
    Spring boot项目分环境Maven打包,动态配置文件,动态配置项目
    rsa公钥和私钥到底哪个才是用来加密,哪个用来解密?
    session和cookie的区别和联系详解,Cookie Session相关看这篇就够了。
    面试中的nginx高可用高并发!
    js正则表达式验证、匹配数字、匹配字符串、匹配中文、匹配任意字符备忘录
    thymeleaf模板、thymeleaf语法相关中文文档教程
  • 原文地址:https://www.cnblogs.com/hsiang/p/11181673.html
Copyright © 2011-2022 走看看