zoukankan      html  css  js  c++  java
  • 【Android】20.1 音频播放

    分类:C#、Android、VS2015;

    创建日期:2016-03-11

    一、简介

    MediaPlayer:适合每次播放一个音频资源或者音频文件的场合。

    SoundPool:适合同时播放多个音频资源或者音频文件的场合。

    二、用MediaPlayer播放

    在安卓系统中,播放音频最简单的方法是使用内置的媒体播放器(MediaPlayer类)。MediaPlayer既可以播放本地文件,也可以播放来自URL的网络数据流。

    1、创建MediaPlayer实例

    有两种创建MediaPlayer实例的办法,

    办法1:

    MediaPlayer player = MediaPlayer.Create(this, Resource.Raw.test);

    用MediaPlayer.Create创建实例时可直接指定数据源。

    办法2:

    MediaPlayer player = new MediaPlayer();

    2、数据源

    有3种。

    (1)播放raw文件夹下的资源文件

    应用程序自带的音乐资源一般保存到raw文件夹下,下面的代码演示了如何播放Resource/raw下的媒体文件:

    MediaPlayer mPlayer=MediaPlayer.Create(this, Resource.Raw.MyAudio);

    mPlayer.Start();

    注意:这种方式主要适用于播放应用程序自带的容量较小的资源文件,例如接听电话时播放的音乐、按键音、开机启动音、信息提示音等都可以随应用程序一块发布。

    (2)播放来自文件系统的媒体文件

    指播放Android默认的系统标准文件夹下、Assets文件夹下、SD卡中的媒体文件,这些文件都属于文件系统。

    以下描述了使用MediaPlayer从文件系统中播放音频的步骤:

    • 初始化MediaPlayer对象。
    • 通过SetDataSource方法(同步方式)或者SetDataSourceAsync方法(异步方式)设置要播放的文件。
    • 调用Prepare方法(同步方式)或者PrepareAsync方法(异步方式)初始化播放器。
    • 调用Start方法开始音频播放。
    • 注意采用这种方式时,播放顺序非常重要:先设置数据源、同步播放设备,最后再调用Start方法播放。

    播放来自文件系统的媒体文件时,可通过MediaPlayer的SetDataSource()方法指定数据源,该方法的重载形式很多,常用有:

    SetDataSource (string path)

    SetDataSource (FileDescriptor fd)

    SetDataSource (Context context, Uri uri)

    SetDataSource (FileDescriptor fd, long offset, long length)

    (3)播放来自网络的媒体流

    对于用URL指定的媒体流,有两种播放形式。

    方式1:与播放本地资源文件的处理办法相似。

    方式2:与播放本地文件系统的处理办法相似。

    3、播放控制

    MediaPlayer只能从标准移动设备(扬声器、蓝牙耳机)中播放音频,不能从通话用的话筒中播放音频。

    调用Pause方法可暂停播放:player.Pause();

    调用Start方法恢复播放:player.Start();

    调用Stop方法停止播放:player.Stop();

    当不再需要播放器时,必须调用player.Release();将其从内存中释放。

    三、用SoundPool播放

    SoundPool适合同时播放多个音频资源或者音频文件的场合。比如游戏中同时出现的多个声音和背景音乐。

    四、例20-1--AudioPlayDemo

    下面通过例子说明播放音频文件最基本的用法。

    1、运行截图

    image

    2、设计步骤

    说明:SD卡Download文件夹下的音乐文件(ch2001dj2.mp3)是通过执行代码拷进去的(没有就复制,有了就不复制了)。其他铃声和音乐文件需要自己手工拖放到项目中对应的文件夹下。

    (1)在raw和Assets下分别添加一些音频文件

    由于是学习基本用法,所以文件自己随便找吧。

    本示例放到raw文件夹下的文件有:

    铃声:ch2001ringin1.wav

    开枪:ch2001ZR35.wav

    音乐:ch2001dj1.mp3

    本示例放到Assets文件夹下文的件有:

    音乐:ch2001dj2.mp3

    (2)添加ch2001Main.axml文件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <Button
            android:id="@+id/ch2001_btnRawRing"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="播放RAW下的铃声资源" />
        <Button
            android:id="@+id/ch2001_btnRawMusic"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="播放RAW下的音乐资源" />
        <Button
            android:id="@+id/ch2001_btnAssetsMusic"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="播放附件下的音乐文件" />
        <Button
            android:id="@+id/ch2001_btnDownloadMusic"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="播放SD卡中的音乐文件" />
      <Button
          android:id="@+id/ch2001_btnSoundPool"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:text="同时播放多个音乐" />
      <Button
            android:id="@+id/ch2001_btnStop"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="停止播放"
            android:layout_marginTop="30dp" />
    </LinearLayout>

    (3)添加ch2001MainActivity.cs文件

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using Android.App;
    using Android.Content;
    using Android.OS;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using Android.Media;
    using System.Threading.Tasks;
    using System.IO;
    
    namespace MyDemos.SrcDemos
    {
        [Activity(Label = "例20-1 音频播放基本用法")]
        public class ch2001MainActivity : Activity
        {
            private MediaPlayer player = null;
            private SoundPool soundPool;
            private SortedList<int, int> sounds;
            protected override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
                SetContentView(Resource.Layout.ch2001Main);
                soundPool = new SoundPool(maxStreams: 2, streamType: Android.Media.Stream.Music, srcQuality: 100);
                sounds = new SortedList<int, int>();
                //0:不循环,-1:循环
                sounds.Add(soundPool.Load(this, Resource.Raw.ch2001ringin1, 1), -1);
                sounds.Add(soundPool.Load(this, Resource.Raw.ch2001ZR35, 1), -1);
    
                var btnRawRing = FindViewById<Button>(Resource.Id.ch2001_btnRawRing);
                btnRawRing.Click += delegate
                {
                    StopPlayer();
                    try
                    {
                        player = MediaPlayer.Create(this, Resource.Raw.ch2001ringin1);
                        player.Start();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.StackTrace);
                    }
                };
    
                var btnRawMusic = FindViewById<Button>(Resource.Id.ch2001_btnRawMusic);
                btnRawMusic.Click += delegate
                {
                    StopPlayer();
                    try
                    {
                        player = MediaPlayer.Create(this, Resource.Raw.ch2001dj1);
                        player.Start();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.StackTrace);
                    }
                };
    
                var btnAssetsMusic = FindViewById<Button>(Resource.Id.ch2001_btnAssetsMusic);
                btnAssetsMusic.Click += delegate
                {
                    StopPlayer();
                    try
                    {
                        var fd = Assets.OpenFd("ch2001dj2.mp3");
                        player = new MediaPlayer();
                        player.Reset();
                        player.SetDataSource(fd.FileDescriptor);
                        player.Prepare();
                        player.Start();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.StackTrace);
                    }
                };
    
                var btnDownloadMusic = FindViewById<Button>(Resource.Id.ch2001_btnDownloadMusic);
                btnDownloadMusic.Click += delegate
                {
                    StopPlayer();
                    try
                    {
                        string path = GetDownloadFile("ch2001dj2.mp3");
                        player = new MediaPlayer();
                        player.Reset();
                        player.SetDataSource(path);
                        player.Prepare();
                        player.Start();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.StackTrace);
                    }
                };
    
                var btnSoundPool = FindViewById<Button>(Resource.Id.ch2001_btnSoundPool);
                btnSoundPool.Click += delegate
                {
                    StopPlayer();
                    AudioManager mgr = (AudioManager)GetSystemService(Context.AudioService);
                    float currentStreamVolume = mgr.GetStreamVolume(Android.Media.Stream.Music);
                    float maxStreamVolume = mgr.GetStreamMaxVolume(Android.Media.Stream.Music);
                    float volume = currentStreamVolume / maxStreamVolume;
                    foreach (var v in sounds)
                    {
                        soundPool.Play(v.Key, volume, volume, 1, v.Value, 1.0f);
                    }
                };
    
                var btnStop = FindViewById<Button>(Resource.Id.ch2001_btnStop);
                btnStop.Click += delegate
                {
                    StopPlayer();
                };
            }
    
            protected override void OnDestroy()
            {
                base.OnDestroy();
                StopPlayer();
                soundPool.Release();
            }
    
            /// <summary>
            /// 同时播放多个音频
            /// </summary>
            /// <param name="soundID">音频资源的id</param>
            /// <param name="loop">0:不循环,-1:循环</param>
            private void PlaySound(int soundID, int loop)
            {
                AudioManager mgr = (AudioManager)GetSystemService(Context.AudioService);
                float currentStreamVolume = mgr.GetStreamVolume(Android.Media.Stream.Music);
                float maxStreamVolume = mgr.GetStreamMaxVolume(Android.Media.Stream.Music);
                float volume = currentStreamVolume / maxStreamVolume;
                soundPool.Play(soundID, volume, volume, 1, loop, 1.0f);
            }
    
            private void StopPlayer()
            {
                if (player != null)
                {
                    if (player.IsPlaying)
                    {
                        player.Stop();
                    }
                    player.Release();
                    player = null;
                }
                if (soundPool != null)
                {
                    foreach (var v in sounds)
                    {
                        soundPool.Stop(v.Key);
                    }
                }
            }
    
            /// <summary>
            /// 该方法仅为了演示如何将Assets下的文件复制到SD卡上
            /// 如果SD卡的Download文件夹下不存在指定的文件,就将其复制到该文件夹下。
            /// 如果存在,直接返回路径
            /// </summary>
            /// <param name="fileName">Assets文件夹下的文件名</param>
            /// <returns>SD卡的Download文件夹下的文件路径</returns>
            private string GetDownloadFile(string fileName)
            {
                //注意此操作需要 android.permission.WRITE_EXTERNAL_STORAGE 权限
                //由于第3章已经添加过此权限,所以该例子不需要再添加了
    
                //SD卡Download文件夹下的文件路径
                string filePath = string.Format("{0}/{1}/{2}",
                    Android.OS.Environment.ExternalStorageDirectory.Path,
                    Android.OS.Environment.DirectoryDownloads,
                    fileName);
                if (File.Exists(filePath) == false)
                {
                    //如果不存在,就将Assets文件夹下的指定文件复制到SD卡的该文件夹下
                    var fromStream = Assets.Open(fileName);
                    int size = 32 * 1024;
                    using (FileStream toStream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite))
                    {
                        int n = -1;
                        byte[] buffer = new byte[size];
                        while ((n = fromStream.Read(buffer, 0, size)) > 0)
                        {
                            toStream.Write(buffer, 0, n);
                        }
                    }
                }
                return filePath;
            }
        }
    }
  • 相关阅读:
    VS2010、SQL Server 2008和SQL Server 2012安装详解
    IIS服务寄宿
    C#中错误:不包含适合于入 口点的静态“Main”方法 的解决方法
    硬件的一些性能指标
    SATA SAS SSD 硬盘介绍和评测
    mysql数据库锁定机制
    mysql日志设置优化
    MySQL硬件瓶颈分析
    可扩展性设计之数据切分
    硬件环境对系统性能的影响
  • 原文地址:https://www.cnblogs.com/rainmj/p/5265187.html
Copyright © 2011-2022 走看看