Android MediaPlayer、原始资源、停止和启动的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2969242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:06:35  来源:igfitidea点击:

Problems with MediaPlayer, raw resources, stop and start

androidmedia-player

提问by arakn0

I'm new to Android development and I have a question/problem.

我是 Android 开发的新手,我有一个问题/问题。

I'm playing around with the MediaPlayer class to reproduce some sounds/music. I am playing raw resources (res/raw) and it looks kind of easy.

我正在使用 MediaPlayer 类来重现一些声音/音乐。我正在玩原始资源 ( res/raw),它看起来很简单。

To play a raw resource, the MediaPlayer has to be initialized like this:

要播放原始资源,必须像这样初始化 MediaPlayer:


MediaPlayer mp = MediaPlayer.create(appContext, R.raw.song);
mp.start();

Until here there is no problem. The sound is played, and everything works fine. My problem appears when I want to add more options to my application. Specifically when I add the "Stop" button/option.

直到这里没有问题。播放声音,一切正常。当我想向我的应用程序添加更多选项时,我的问题出现了。特别是当我添加“停止”按钮/选项时。

Basically, what I want to do is...when I press "Stop", the music stops. And when I press "Start", the song/sound starts over. (pretty basic!)

基本上,我想做的是......当我按下“停止”时,音乐停止。当我按“开始”时,歌曲/声音会重新开始。(非常基本!)

To stop the media player, you only have to call stop(). But to play the sound again, the media player has to be reseted and prepared.

要停止媒体播放器,您只需调用stop()。但是要再次播放声音,必须重新设置媒体播放器并做好准备。


mp.reset();
mp.setDataSource(params);
mp.prepare();

The problem is that the method setDataSource()only accepts as params a file path, Content Provider URI, streaming media URL path, or File Descriptor.

问题是该方法setDataSource()只接受文件路径、内容提供者 URI、流媒体 URL 路径或文件描述符作为参数。

So, since this method doesn't accept a resource identifier, I don't know how to set the data source in order to call prepare(). In addition, I don't understand why you can't use a Resouce identifier to set the data source, but you can use a resource identifier when initializing the MediaPlayer.

因此,由于此方法不接受资源标识符,因此我不知道如何设置数据源以调用prepare(). 另外,我不明白为什么不能使用Resouce 标识符来设置数据源,但是在初始化MediaPlayer 时可以使用资源标识符。

I guess I'm missing something. I wonder if I am mixing concepts, and the method stop()doesn't have to be called in the "Stop" button. Any help?

我想我错过了一些东西。我想知道我是否在混合概念,并且stop()不必在“停止”按钮中调用该方法。有什么帮助吗?

Thanks in advance!!!

提前致谢!!!

回答by adstro

Here is what I did to load multiple resources with a single MediaPlayer:

这是我使用单个 MediaPlayer 加载多个资源的操作:

/**
 * Play a sample with the Android MediaPLayer.
 *
 * @param resid Resource ID if the sample to play.
 */
private void playSample(int resid)
{
    AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);

    try
    {   
        mediaPlayer.reset();
        mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
        mediaPlayer.prepare();
        mediaPlayer.start();
        afd.close();
    }
    catch (IllegalArgumentException e)
    {
        Log.e(TAG, "Unable to play audio queue do to exception: " + e.getMessage(), e);
    }
    catch (IllegalStateException e)
    {
        Log.e(TAG, "Unable to play audio queue do to exception: " + e.getMessage(), e);
    }
    catch (IOException e)
    {
        Log.e(TAG, "Unable to play audio queue do to exception: " + e.getMessage(), e);
    }

mediaPlay is a member variable that get created and released at other points in the class. This may not be the best way (I am new to Android myself), but it seems to work. Just note that the code will probably fall trough to the bottom of the method before the mediaPlayer is done playing. If you need to play a series of resources, you will still need to handle this case.

mediaPlay 是一个成员变量,它在类中的其他点被创建和释放。这可能不是最好的方法(我自己是 Android 新手),但它似乎有效。请注意,在 mediaPlayer 完成播放之前,代码可能会下降到方法的底部。如果您需要播放一系列资源,您仍然需要处理这种情况。

回答by mishkin

this is how MediaPlayer.createmethod works to open a raw file:

这就是MediaPlayer.create方法打开原始文件的方式:

    public static MediaPlayer create(Context context, int resid) {
         try {
             AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
             if (afd == null) return null;

             MediaPlayer mp = new MediaPlayer();
             mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
             afd.close();
             mp.prepare();
            return mp;
        } catch (IOException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "create failed:", ex);
           // fall through
        } catch (SecurityException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        }
         return null;
    }

回答by petrica.martinescu

Or, you could access the resource in this way:

或者,您可以通过以下方式访问资源:

mediaPlayer.setDataSource(context, Uri.parse("android.resource://com.package.name/raw/song"));

where com.package.name is the name of your application package

其中 com.package.name 是您的应用程序包的名称

回答by Rectangle

You can use

您可以使用

mp.pause();
mp.seekTo(0);

to stop music player.

停止音乐播放器。

回答by MarcBilbo

Finally, the way it works for me:

最后,它对我有用的方式:

public class MainStart extends Activity {

    ImageButton buttonImage;
    MediaPlayer mp;
    Boolean playing = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main);

        buttonImage = (ImageButton)findViewById(R.id.ButtonID);


        buttonImage.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                if(playing){
                    mp.stop();
                    playing = false;
                }else{
                    mp = MediaPlayer.create(getApplicationContext(), R.raw.sound_u_want);
                    mp.start();
                    playing = true;
                }
            }
        });
    }
}

回答by Bay

MR. Rectangle, this message maybe too late for it, but I proudly write these codes to your idea: I have mpfor mediaplayerand sescal9is a button.

先生。矩形,这条消息可能为时已晚,但我很自豪地为您的想法编写了这些代码:I have mpfor mediaplayerand sescal9is a button.

....
if(btnClicked.getId() == sescal9_ornek_muzik.getId())
        {
            mp.start();
            mp.seekTo(380);
            mp2.start();
            mp2.seekTo(360);
            mp3.start();
            mp3.seekTo(340);
            ...
            }

回答by Ranjith Kumar

Recheck your passing parameters not null

重新检查您传递的参数不为空

Possible reasons

可能的原因

  1. Context may be null
  2. Your media file may be corrupted
  1. 上下文可能为空
  2. 您的媒体文件可能已损坏