【问题标题】:playing sounds on simultaneous button presses在同时按下按钮时播放声音
【发布时间】:2017-02-27 04:16:09
【问题描述】:

在我的Launchpad Simulator 中,主要活动上有很多按钮。
我想在每次按下按钮时播放声音。如果同时按下按钮,我想同时播放声音。从我到现在为止,似乎每当我按下按钮时它都会播放声音,但因为第一个声音是 3 秒长(例如,拍手声音文件的播放时间是 3 秒)。

在通过按钮发出任何其他声音之前,它会等待 3 秒,如果在 3 秒后按下任何按钮,则会播放下一个声音,与其他 32 个按钮相同。

就像启动板一样,只要我按下按钮,我就想要播放声音。在这种情况下,拍手声。

这里是 Java 代码:

MainActivity.java

package com.oniichansblog.launchpadify;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.media.MediaPlayer;

public class MainActivity extends AppCompatActivity {
    private MediaPlayer clap1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        clap1 = MediaPlayer.create(this, R.raw.clap1);
    }

    public void clap1(View v){
        clap1.start();
    }

}

我只有一个函数clap1(),每次按下按钮时都会被一遍又一遍地调用。

如果你想自己检查一下,我有一个存储库: GitHub Repository for LaunchPadify

【问题讨论】:

    标签: java android android-studio audio


    【解决方案1】:

    我建议不要在上面定义 MediaPlayer。 只需在每次 ButtonClick 时创建一个新的临时 MediaPlayer

    new MediaPlayer.create(this, R.raw.clap).start();
    

    它会同时播放声音

    更新

    如果你想在播放完声音后销毁一个 MediaPlayer,你可以使用这个代码来做到这一点

    new MediaPlayer.create(getApplicationContext(), R.raw.test)
                .start()
                .setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                     public void onCompletion(MediaPlayer mediaPlayer) {
                        mediaPlayer.release();
                    }
                });
    

    【讨论】:

    • 是的,效果很好,但是在按了几下按钮后,它停止了鼓掌。我会留下一个应用程序的链接。如果您能亲眼看到它在击打 10-15 次后如何停止发出声音。 drive.google.com/open?id=0B5whGfbIoM7KVE56clVXY2dSUFU
    • 是的,这是由媒体播放器对象溢出引起的。您需要添加一个 onCompletionListener,然后在声音播放完毕后释放(销毁)一个 MediaPlayer。
    • 能否详细说明。我是新来的声音
    【解决方案2】:

    要同时播放多个曲目,您应该使用AsyncTask 并在 THREAD_POOL_EXECUTOR 上执行它。
    如何做到这一点:
    线程类

    class PlayThread extends AsyncTask<MediaPlayer, Void, Void>
    {
        @Override
        protected Void doInBackground(MediaPlayer... player) {
    
            player[0].start();          
            return null;
        }
    }
    

    媒体播放器

    MediaPlayer[] players = new MediaPlayer[5];
    //Then set source to each player...
    //...
    //Create objects of Thread class
    PlayThread[] playThreads = new PlayThread[5];
    for (int i = 0; i < 5; i++)
        playThreads[i] = new PlayThread();
    //Set Media Players there and start play
    for (int i = 0; i < 5; i++)
        playThreads[i].executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, players[i]);
    

    AsyncTask只能同时执行5个线程,其他的要排队。


    SoundPool 缓冲区限制为 1Mb,因此根本不是解决方案。


    这很重要:
    要同时播放更多音轨,您应该将它们混合到 1 个缓冲区中。
    实现方式:将mp3解码为pcm(流模式下到小缓冲区),混合成一个字节的缓冲区,放到AudioTrack播放。

    【讨论】:

    • 其实我有几个问题:这条线是什么意思 doInBackground(MediaPlayer... player) ,我不明白为什么会有三个点?接下来你说要为玩家添加一些资源。我可以设置源。但在下一部分你说设置 Mediaplayer 并开始播放。老实说,我对声音和线程很陌生。因此,如果您可以像一对一的教程一样阐明您的代码,我可以将其用作示例并根据自己的需要对其进行编辑。我也不明白这是非常重要的部分
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-02
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多