Media Player เรียกในสถานะ 0 ข้อผิดพลาด (-38,0)


105

ฉันกำลังพยายามออกแบบแอปง่ายๆที่สตรีมสถานีวิทยุอินเทอร์เน็ต ฉันมี URL สำหรับสถานีและกำลังตั้งค่า Media Player เช่น

    MediaPlayer mediaPlayer = new MediaPlayer();
    try {
        mediaPlayer.setDataSource(URL);
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        mediaPlayer.prepare();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    mediaPlayer.start();

โปรแกรมไม่หยุดทำงานเมื่อจำลอง แต่ไม่มีอะไรเล่นอยู่และฉันได้รับข้อผิดพลาดต่อไปนี้:

start called in state 0

และด้านล่างคือ

Error (-38,0)

ไม่มีใครรู้ว่านี่หมายถึงอะไร?

ฉันได้อ่านเล็กน้อยเกี่ยวกับข้อผิดพลาดสถานะเหล่านี้ แต่ไม่พบสิ่งใดที่เกี่ยวข้องกับโครงการของฉัน




@SmashCode โปรดทำเครื่องหมายคำตอบอื่นว่าเป็นที่ยอมรับเนื่องจากคำตอบของฉันไม่มีประโยชน์
tidbeck

คำตอบ:


120

คุณจะต้องเรียกmediaPlayer.start()ในonPreparedวิธีการโดยใช้ฟัง คุณได้รับข้อผิดพลาดนี้เนื่องจากคุณกำลังโทรหาmediaPlayer.start()ก่อนที่จะถึงสถานะที่เตรียมไว้

นี่คือวิธีที่คุณสามารถทำได้:

mp.setDataSource(url); 
mp.setOnPreparedListener(this);
mp.prepareAsync();

public void onPrepared(MediaPlayer player) {
    player.start();
}

จะเกิดอะไรขึ้นถ้าเราไม่ต้องการให้มันเริ่มทันที? แม้ว่าฉันจะเริ่มต้นเครื่องเล่นของฉันและรอสักครู่ในครั้งแรกที่ฉันลองเล่นมันก็มีข้อผิดพลาดนี้เว้นแต่ฉันจะโทร. start () ใน onPrepared
Elliptica

1
คุณเตรียมมันมาก่อนและจำไว้ว่าคุณเตรียมมัน ในแบบคู่ขนานคุณพยายามจำไว้ว่าคุณต้องการเรียกใช้หรือไม่ เมื่อพร้อมแล้วและคุณต้องการเรียกใช้คุณก็เริ่มได้เลย
Victor Paléologue

33

ดูเหมือนว่าข้อผิดพลาด -38 หมายถึงข้อยกเว้นของรัฐ (ตามที่ข้อความแสดงข้อผิดพลาดระบุ) ตัวอย่างเช่นหากคุณโทรstart()ก่อนที่เพลงจะพร้อมหรือเมื่อคุณโทรpause()แม้ว่าเพลงนั้นจะไม่เล่นเลยก็ตาม

ในการแก้ไขปัญหานี้ให้ตรวจสอบสถานะของ MediaPlayer ก่อนเรียกใช้เมธอด ตัวอย่างเช่น:

if(mediaPlayer.isPlaying()) {
    mediaPlayer.pause();
}

นอกจากนี้ MediaPlayer กำลังส่งข้อความเหตุการณ์ แม้ว่าคุณจะไม่ต้องการเหตุการณ์ที่เตรียมไว้ (แม้ว่าจะเป็นความคิดที่ดีที่จะไม่เริ่มเล่นก่อนที่เหตุการณ์นี้จะเริ่มทำงาน) คุณต้องตั้งค่าตัวเรียกกลับ - ฟัง นอกจากนี้ยังถือจริงสำหรับOnErrorListener, OnCompletionListener, OnPreparedListenerและOnSeekCompletedListener(ถ้าคุณเรียกวิธีแสวงหา)

ผู้ฟังสามารถแนบได้ง่ายๆโดย

mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        // Do something. For example: playButton.setEnabled(true);
    }
});

การโทรหยุดชั่วคราว () เมื่อไม่เล่นผู้เล่นเป็นกรณีของฉัน
stevo.mit

การเรียก mediaPlayer.isPlaying () ในสถานะที่ไม่ถูกต้องจะทำให้เครื่องเล่นสื่อเข้าสู่สถานะข้อผิดพลาด ดีกว่าที่จะรักษา enum ที่ชัดเจนเพื่อรักษาสถานะ
Madeyedexter

14

ฉันได้รับข้อผิดพลาดนี้เมื่อฉันพยายามรับตำแหน่งปัจจุบัน (MediaPlayer.getCurrentPosition ()) ของโปรแกรมเล่นสื่อเมื่อไม่ได้อยู่ในที่ระบุไว้ ฉันได้รับสิ่งนี้โดยการติดตามสถานะของมันและเรียกเฉพาะเมธอด getCurrentPosition () หลังจากเรียก onPreparedListener


คุณคิดออกได้อย่างไรว่าเพราะเหตุนี้?
AdamMc331

9

นี่คือรหัสของฉันผ่านการทดสอบและใช้งานได้ดี:

package com.example.com.mak.mediaplayer;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.app.Activity;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final MediaPlayer mpp = MediaPlayer.create(this, R.raw.red); //mp3 file in res/raw folder

    Button btnplay = (Button) findViewById(R.id.btnplay); //Play
    btnplay.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View vone) {
        mpp.start();
      }
    });

    Button btnpause = (Button) findViewById(R.id.btnpause); //Pause
    btnpause.setOnClickListener(new View.OnClickListener() {

      @Override
      public void onClick(View vtwo) {
        if (mpp.isPlaying()) {
          mpp.pause();
          mpp.seekTo(0);
        }
      }
    });
  }
}

4

ฉันทดสอบด้านล่างรหัส ทำงานได้ดี

public class test extends Activity implements OnErrorListener, OnPreparedListener {

private MediaPlayer player;

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


    player = new MediaPlayer();
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);
    try {
        player.setDataSource("http://www.hubharp.com/web_sound/BachGavotte.mp3");
        player.setOnErrorListener(this);
        player.setOnPreparedListener(this);
        player.prepareAsync();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }       
}
@Override
public void onDestroy() {
    super.onDestroy();
    player.release();
    player = null;
}
@Override
public void onPrepared(MediaPlayer play) {
    play.start();
}
@Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
    return false;
}
}

สำหรับและอัปเดตเพื่อSetAudioStreamType(..)ใช้SetAudioAttributes(...)
Pierre

4

ฉันพบปัญหาเดียวกันเมื่อสองสามวันก่อน MediaPlayer เสียงของฉันทำงานได้ดีบนอุปกรณ์ที่มีพลังในการประมวลผลสูง แต่สำหรับอุปกรณ์ที่ทำงานช้าเครื่องเล่นสื่อไม่ได้เล่นในบางครั้งและจาก LogCat ก็มีหลายคนบ่นเกี่ยวกับการเรียกในสถานะที่ไม่ถูกต้อง ดังนั้นฉันจึงแก้ไขโดยการโทรวางสายเพื่อเริ่ม () , หยุดชั่วคราว () , ... ในonPrepared ()วิธีการของOnPreparedListener ()ดังต่อไปนี้:

mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    ........
                    mediaPlayer.start();
                    ....
                    songControlBtn.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (mediaPlayer.isPlaying()) {
                                mediaPlayer.pause();

                            } else {
                                mediaPlayer.start();

                            }
                        }
                    });

                    mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            ............

                        }
                    });
                }
            });

พยายามปล่อยเครื่องเล่นสื่อที่คุณไม่ต้องการอีกต่อไป ตัวอย่างเช่นถ้าคุณไม่ต้องการที่จะเล่นเสียงหรือวิดีโอบนพื้นหลังแล้วคุณควรจะเรียกmediaPlayer.release ()ในonPause ()


3

บางครั้งไฟล์มีการเข้ารหัสในลักษณะที่ Android ไม่สามารถถอดรหัสได้ แม้แต่ไฟล์ mp4 บางไฟล์ก็ไม่สามารถเล่นได้ โปรดลองใช้รูปแบบไฟล์อื่น (เล่น. 3gp เป็นส่วนใหญ่) และดู ..


46
ฉันขอให้สถานีวิทยุอินเทอร์เน็ตเปลี่ยนรูปแบบไฟล์ไม่ได้
SmashCode

คุณได้รับป๊อปอัป "ไม่สามารถเล่นวิดีโอนี้" หรือไม่ คุณจัดการกับมันอย่างไร? ฉันตรวจพบข้อผิดพลาด แต่ได้รับโมดอลนี้โดยไม่คำนึงถึงและฉันไม่สามารถควบคุมแหล่งที่มาของสื่อได้เนื่องจากมาจาก API สาธารณะ หากใครรู้วิธีป้องกันโมดอล "ไม่สามารถเล่นวิดีโอนี้ได้" ฉันจะขอบคุณ
Krafty

คุณลองตั้งค่าตัวฟังข้อผิดพลาดหรือไม่ MediaPlayer mp = MediaPlayer ใหม่ () {@Override โมฆะสาธารณะ setOnErrorListener (ผู้ฟัง android.media.MediaPlayer OnErrorListener) {// ทำสิ่งต่างๆที่นี่ .. }}; mp.setDataSource (..
Rukmal Dias

1

คุณได้รับข้อความนี้ในบันทึกเนื่องจากคุณทำสิ่งที่ไม่ได้รับอนุญาตในสถานะปัจจุบันของอินสแตนซ์ MediaPlayer ของคุณ

ดังนั้นคุณควรลงทะเบียนตัวจัดการข้อผิดพลาดเพื่อตรวจจับสิ่งเหล่านั้นเสมอ (ตามที่ @tidbeck แนะนำ)

ในตอนแรกฉันแนะนำให้คุณดูเอกสารประกอบของMediaPlayerชั้นเรียนและทำความเข้าใจว่ารัฐหมายถึงอะไร ดู: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram

ข้อผิดพลาดของคุณที่นี่อาจเป็นหนึ่งในข้อผิดพลาดทั่วไปที่คนอื่นเขียนไว้ที่นี่ แต่โดยทั่วไปฉันจะดูเอกสารว่ามีวิธีใดบ้างที่สามารถเรียกใช้ในสถานะใดได้: http://developer.android.com/ reference / android / media / MediaPlayer.html # Valid_and_Invalid_States

ในตัวอย่างของฉันมันเป็นวิธีการmediaPlayer.CurrentPositionที่ฉันเรียกในขณะที่เครื่องเล่นสื่ออยู่ในสถานะซึ่งไม่ได้รับอนุญาตให้เรียกคุณสมบัตินี้



0

ฉันแก้ไขทั้งข้อผิดพลาด (-19,0) และ (-38,0) ด้วยการสร้างวัตถุใหม่ของ MediaPlayer ทุกครั้งก่อนเล่นและปล่อยหลังจากนั้น

ก่อน:

void play(int resourceID) {
if (getActivity() != null) {

     //Using the same object - Problem persists
    player = MediaPlayer.create(getActivity(), resourceID);
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);

    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            player.release();
        }
    });

    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });

}

}

หลังจาก:

void play(int resourceID) {

if (getActivity() != null) {

    //Problem Solved
    //Creating new MediaPlayer object every time and releasing it after completion
    final MediaPlayer player = MediaPlayer.create(getActivity(), resourceID);
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);

    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            player.release();
        }
    });

    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });

}

}


0
  if(length>0)
        {
            mediaPlayer = new MediaPlayer();
            Log.d("length",""+length);
            try {
                mediaPlayer.setDataSource(getApplication(),Uri.parse(uri));
            } catch(IOException e) {
                e.printStackTrace();
            }
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    mediaPlayer.seekTo(length);
                    mediaPlayer.start();

                }
            });
            mediaPlayer.prepareAsync();

0

ทุกครั้งที่ผิดหวังมาก ดังนั้นฉันจึงมีวิธีแก้ปัญหาที่เหมาะกับฉัน

try {
                        if (mediaPlayer != null) {
                            mediaPlayer.release();
                            mediaPlayer = null;

                        }
                        mediaPlayer = new MediaPlayer();
                        mediaPlayer.setDataSource(file.getAbsolutePath());
                        mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
                        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                            @Override
                            public void onPrepared(MediaPlayer mediaPlayer) {
                                mediaPlayer.start();
                                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                                    @Override
                                    public void onCompletion(MediaPlayer mediaPlayer) {
                                        mediaPlayer.stop();
                                        mediaPlayer.release();
                                        mediaPlayer = null;
                                    }
                                });
                            }
                        });
                        mediaPlayer.prepare();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }


0

ฉันยังได้รับข้อผิดพลาดนี้ฉันลองใช้ onPreparedListener แต่ยังคงได้รับข้อผิดพลาดนี้ ในที่สุดฉันก็ได้วิธีแก้ปัญหาว่าข้อผิดพลาดเป็นความผิดของฉันเพราะฉันลืมสิทธิ์อินเทอร์เน็ตใน Android Manifest xml :)

<uses-permission android:name="android.permission.INTERNET" />

ฉันใช้ตัวอย่างการเข้ารหัสสำหรับ mediaplayer ฉันใช้ในเมธอด StreamService.java
onCreate

String url = "http://s17.myradiostream.com:11474/";
mediaPlayer = new MediaPlayer();            
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();

0

ฉันได้เปลี่ยน setAudioStreamType เป็น setAudioAttributes;

mediaPlayer.setAudioAttributes(AudioAttributes.Builder()
                .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
                .setLegacyStreamType(AudioManager.STREAM_ALARM)
                .setUsage(AudioAttributes.USAGE_ALARM)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build());

-1

ผมได้พบกับปัญหาเดียวกันก่อนเพื่อนในชั้นแรกเป็นสิทธิที่คุณเรียกว่าstart()ในเวลาที่ผิดคุณควรตั้งค่าฟังสำหรับการเตรียมความพร้อม (ก) หรือprepareSync()ด้วยวิธีนี้mediaPlayer.setOnPreparedListener(this); ก่อนจัดเตรียมในการโทรติดต่อกลับนี้start()อาจช่วยแก้ปัญหาของคุณได้ ฉันได้ลองแล้ว


คุณสามารถเจาะจงมากขึ้นได้ไหม
Karthik AMR

ขออภัยภาษาอังกฤษไม่ใช่ภาษาแรกของฉันและฉันก็ไม่เก่งด้วย ... แต่ฉันแค่อยากช่วยคนอื่นที่มีคำถามเหมือนกันนั่นคือทั้งหมดที่
peerless2012

-1

ฉันเป็นคนใหม่ในการเขียนโปรแกรม Android และฉันมีข้อผิดพลาดเดียวกันกับอันนี้ ดังนั้นฉันจึงกำหนด mp.createmediaPlayer = MediaPlayer.create (getApplicationContext (), Settings.System.DEFAULT_RINGTONE_URI ใหม่) มันอาจไม่ใช่วิธีที่แท้จริงที่จะทำ แต่มันได้ผลสำหรับฉัน:

try {
  mp = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI);
} catch (Exception e) {
  e.printStackTrace();
}

mp.start();

-2
mp = new MediaPlayer();
AssetFileDescriptor afd = mContext.getAssets().openFd(fileName);
mp.reset();
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
  public void onPrepared(MediaPlayer mp) {
    mp.start();
  }
});

mp.prepareAsync();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.