【问题标题】:Play audio file from the assets directory从资产目录播放音频文件
【发布时间】:2011-03-18 08:55:02
【问题描述】:

我有以下代码:

AssetFileDescriptor afd = getAssets().openFd("AudioFile.mp3");
player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor());
player.prepare();
player.start();

问题是,当我运行此代码时,它开始按字母顺序播放资产目录中的所有音频文件,而不是只播放我请求的音频文件。我究竟做错了什么?有没有更好的方法来播放资产目录中的音频文件?

后续问题: 将音频文件保存在 assets 目录中和将它们保存在 res/raw 目录中是否有区别?除了如果他们在资产目录中他们不会得到 id 的事实。如果我将音频文件移动到 res/raw 文件夹,那么我在重用 MediaPlayers 时会遇到问题,因为 setDataSource() 没有 id 参数。我找不到处理此类问题的好指南。

【问题讨论】:

    标签: android audio android-mediaplayer assets android-assets


    【解决方案1】:
    player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
    

    如果您的资产中只有一个文件,您的版本将可以工作 目录。资产目录内容实际上不是“真实文件” 在磁盘上。所有这些都一个接一个地放在一起。所以,如果你这样做 没有指定从哪里开始以及要读取多少字节,播放器将 读到最后(也就是说,将继续播放 assets 中的所有文件 目录)

    【讨论】:

    • 成功了。谢谢。但我认为我的版本也应该有效。
    • 如果资产目录中只有一个文件,您的版本将可以工作。资产目录内容实际上并不是磁盘上的“真实文件”。所有这些都一个接一个地放在一起。所以,如果你不指定从哪里开始以及读取多少字节,播放器会一直读到最后(即会一直播放 assets 目录下的所有文件)
    • 这是我正在使用但不起作用的代码路径:stackoverflow.com/questions/9124378/…
    • +1 回答了我关于资产文件的一个完全不相关的问题!
    • @SarwarErfan 被资产目录的执行惊呆了>_
    【解决方案2】:

    此功能将正常工作:)

    // MediaPlayer m; /*assume, somewhere in the global scope...*/
    
    public void playBeep() {
        try {
            if (m.isPlaying()) {
                m.stop();
                m.release();
                m = new MediaPlayer();
            }
    
            AssetFileDescriptor descriptor = getAssets().openFd("beepbeep.mp3");
            m.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
            descriptor.close();
    
            m.prepare();
            m.setVolume(1f, 1f);
            m.setLooping(true);
            m.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    【讨论】:

    • 什么是 m?您正在初始化 m = new MediaPlayer();之前用过吗?
    • 嗨@Umar,我有全局变量MediaPlayer m = null;然后我在 playBeep() 函数中分配了
    • 请记住MediaPlayer m 必须是static 或有另一个引用。如果您在没有任何引用的函数中有mGC 将“收集”它
    • 有时音频无法播放到最后
    • 循环到 true 是不是一直在播放?
    【解决方案3】:

    修复上述播放和暂停功能

      public void playBeep ( String word )
    {
        try
        {
            if ( ( m == null ) )
            {
    
                m = new MediaPlayer ();
            }
            else if( m != null&&lastPlayed.equalsIgnoreCase (word)){
                m.stop();
                m.release ();
                m=null;
                lastPlayed="";
                return;
            }else if(m != null){
                m.release ();
                m = new MediaPlayer ();
            }
            lastPlayed=word;
    
            AssetFileDescriptor descriptor = context.getAssets ().openFd ( "rings/" + word + ".mp3" );
            long                start      = descriptor.getStartOffset ();
            long                end        = descriptor.getLength ();
    
            // get title
            // songTitle=songsList.get(songIndex).get("songTitle");
            // set the data source
            try
            {
                m.setDataSource ( descriptor.getFileDescriptor (), start, end );
            }
            catch ( Exception e )
            {
                Log.e ( "MUSIC SERVICE", "Error setting data source", e );
            }
    
            m.prepare ();
            m.setVolume ( 1f, 1f );
            // m.setLooping(true);
            m.start ();
        }
        catch ( Exception e )
        {
            e.printStackTrace ();
        }
    }
    

    【讨论】:

      【解决方案4】:

      这是我的静态版本:

      public static void playAssetSound(Context context, String soundFileName) {
          try {
              MediaPlayer mediaPlayer = new MediaPlayer();
      
              AssetFileDescriptor descriptor = context.getAssets().openFd(soundFileName);
              mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
              descriptor.close();
      
              mediaPlayer.prepare();
              mediaPlayer.setVolume(1f, 1f);
              mediaPlayer.setLooping(false);
              mediaPlayer.start();
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
      

      【讨论】:

        【解决方案5】:

        开始声音

        startSound("mp3/ba.mp3");
        

        方法

        private void startSound(String filename) {
            AssetFileDescriptor afd = null;
            try {
                afd = getResources().getAssets().openFd(filename);
            } catch (IOException e) {
                e.printStackTrace();
            }
            MediaPlayer player = new MediaPlayer();
            try {
                assert afd != null;
                player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                player.prepare();
            } catch (IOException e) {
                e.printStackTrace();
            }
            player.start();
        }
        

        【讨论】:

        • 这在文件位于 assets 目录的子文件夹中时很有用。谢谢。
        【解决方案6】:

        这对我有用:

        public static class eSound_Def
        {
          private static Android.Media.MediaPlayer mpBeep;
        
          public static void InitSounds( Android.Content.Res.AssetManager Assets )
          {
            mpBeep = new Android.Media.MediaPlayer();
        
            InitSound_Beep( Assets );
          }
        
          private static void InitSound_Beep( Android.Content.Res.AssetManager Assets )
          {
            Android.Content.Res.AssetFileDescriptor AFD;
        
            AFD = Assets.OpenFd( "Sounds/beep-06.mp3" );
            mpBeep.SetDataSource( AFD.FileDescriptor, AFD.StartOffset, AFD.Length );
            AFD.Close();
        
            mpBeep.Prepare();
            mpBeep.SetVolume( 1f, 1f );
            mpBeep.Looping = false;
          }
        
          public static void PlaySound_Beep()
          {
            if (mpBeep.IsPlaying == true) 
            {
              mpBeep.Stop();
              mpBeep.Reset();
              InitSound_Beep(); 
            }
            mpBeep.Start();
          }
        }
        

        在主要活动中,创建时:

        protected override void OnCreate( Bundle savedInstanceState )
        {
          base.OnCreate( savedInstanceState );
          SetContentView( Resource.Layout.lmain_activity );
          ...
          eSound_Def.InitSounds( Assets );
          ...
        }
        

        如何在代码中使用(点击按钮):

        private void bButton_Click( object sender, EventArgs e )
        {
          eSound_Def.PlaySound_Beep();
        }
        

        【讨论】:

        • WWWWW什么是eUNIS?
        • eUNIS 是自定义静态类,带有变量 Assets,即对应用资产的引用。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-20
        • 1970-01-01
        相关资源
        最近更新 更多