Pemutar Media dipanggil dalam keadaan 0, kesalahan (-38,0)

105

Saat ini saya mencoba merancang aplikasi sederhana yang mengalirkan stasiun radio internet. Saya memiliki URL untuk stasiun dan sedang menyiapkan Pemutar Media seperti

    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();

Program tidak macet ketika diemulasi, tetapi tidak ada yang diputar dan saya mendapatkan kesalahan berikut:

start called in state 0

dan tepat di bawahnya

Error (-38,0)

Adakah yang tahu apa artinya ini?

Saya telah membaca sedikit tentang kesalahan status ini, tetapi tidak dapat menemukan apa pun yang berlaku untuk proyek saya.

SmashCode
sumber
@SmashCode tolong tandai jawaban lain sebagai diterima karena jawaban saya sama sekali tidak berguna.
tidbeck

Jawaban:

120

Anda perlu menelepon mediaPlayer.start()dalam onPreparedmetode dengan menggunakan pendengar. Anda mendapatkan kesalahan ini karena Anda menelepon mediaPlayer.start()sebelum mencapai keadaan siap.

Inilah cara Anda melakukannya:

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

public void onPrepared(MediaPlayer player) {
    player.start();
}
pengguna1492955
sumber
Bagaimana jika kita tidak ingin itu langsung dimulai? Bahkan jika saya menginisialisasi pemutar saya dan menunggu sekitar satu menit, pertama kali saya mencoba memainkannya, ada kesalahan ini kecuali saya memanggil .start () di onPrepared
Elliptica
1
Anda mempersiapkannya sebelumnya dan ingat Anda mempersiapkannya. Secara paralel, Anda mencoba mengingat apakah Anda ingin menjalankannya. Saat keduanya disiapkan dan Anda ingin menjalankannya, Anda memulainya.
Victor Paléologue
33

Sepertinya Kesalahan -38 berarti pengecualian negara (seperti yang ditunjukkan oleh pesan kesalahan). Misalnya jika Anda menelepon start(), sebelum lagu siap, atau saat Anda menelepon pause(), meskipun lagu tidak diputar sama sekali.

Untuk memperbaiki masalah ini, periksa status mediaPlayer sebelum memanggil metode. Sebagai contoh:

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

Selain itu, MediaPlayer mengirimkan pesan-peristiwa. Meskipun Anda tidak membutuhkan acara-yang disiapkan (meskipun sebaiknya tidak memulai pemutaran sebelum acara ini dipicu) Anda harus menyetel pemroses panggilan balik. Hal ini juga berlaku untuk OnErrorListener, OnCompletionListener, OnPreparedListenerdan OnSeekCompletedListener(jika Anda memanggil mencari metode).

Pendengar dapat dilampirkan hanya dengan

mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        // Do something. For example: playButton.setEnabled(true);
    }
});
Alexander Pacha
sumber
menelepon pause () untuk tidak memainkan pemain adalah kasus saya
stevo.mit
memanggil mediaPlayer.isPlaying () dalam status tidak valid akan mengirim pemutar media ke status error. Lebih baik mempertahankan enum eksplisit untuk mempertahankan status.
Madeyedexter
14

Saya mendapat kesalahan ini ketika saya mencoba untuk mendapatkan posisi saat ini (MediaPlayer.getCurrentPosition ()) dari pemutar media ketika tidak dalam keadaan yang disiapkan. Saya menyiasatinya dengan Melacak statusnya dan hanya memanggil metode getCurrentPosition () setelah onPreparedListener dipanggil.

api di dalam lubang
sumber
Bagaimana Anda mengetahuinya karena alasan itu?
AdamMc331
9

Ini adalah kode saya, diuji dan berfungsi dengan baik:

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);
        }
      }
    });
  }
}
MAK
sumber
4

saya menguji kode di bawah ini. bekerja dengan baik

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;
}
}
Emran Hamza
sumber
Untuk dan perbarui untuk SetAudioStreamType(..)digunakanSetAudioAttributes(...)
Pierre
4

Saya mengalami masalah yang sama beberapa hari yang lalu. Audio MediaPlayer saya berfungsi dengan baik pada perangkat dengan daya pemrosesan tinggi, tetapi untuk perangkat yang lambat, pemutar media tidak dapat diputar beberapa waktu dan dari LogCat banyak keluhan tentang panggilan dalam kondisi yang salah. Jadi saya memutuskan itu dengan memanggil menempatkan panggilan untuk mulai () , pause () , ... di onPrepared () metode OnPreparedListener () seperti di bawah ini:

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) {
                            ............

                        }
                    });
                }
            });

Coba juga untuk melepaskan pemutar media yang tidak Anda perlukan lagi. Misalnya, jika Anda tidak ingin memutar audio atau video di latar belakang, Anda harus memanggil mediaPlayer.release () di onPause () .

Tony Vu
sumber
3

Beberapa file times dikodekan dengan cara yang tidak dapat didekode oleh Android. Bahkan beberapa file mp4 tidak bisa diputar. Silakan coba format file yang berbeda (.3gp dimainkan hampir sepanjang waktu) dan lihat ..

Rukmal Dias
sumber
46
Saya tidak bisa meminta stasiun radio internet untuk mengubah format file mereka.
SmashCode
Apakah Anda mendapatkan munculan "Tidak dapat memutar video ini"? Bagaimana Anda menghadapinya? Saya menangkap kesalahan tetapi mendapatkan modal ini terlepas dan saya tidak memiliki kendali atas sumber media karena berasal dari API publik. Jika ada yang tahu bagaimana mencegah modal "Tidak bisa memutar video ini", saya akan berterima kasih.
Krafty
Apakah Anda mencoba menyetel pemroses kesalahan. MediaPlayer mp = new MediaPlayer () {@Override public void setOnErrorListener (android.media.MediaPlayer.OnErrorListener listener) {// Lakukan sesuatu di sini ..}}; mp.setDataSource (..
Rukmal Dias
1

masukkan deskripsi gambar di sini

Di atas gambar, Anda bisa mendapatkan cara yang benar.

Longalei
sumber
0

Anda mendapatkan pesan ini di log, karena Anda melakukan sesuatu yang tidak diizinkan dalam status saat ini dari instance MediaPlayer Anda.

Oleh karena itu, Anda harus selalu mendaftarkan penangan kesalahan untuk menangkap hal-hal itu (seperti yang disarankan @tidbeck).

Pada awalnya, saya menyarankan Anda untuk melihat dokumentasi untuk MediaPlayerkelas dan mendapatkan pemahaman tentang apa artinya dengan negara bagian. Lihat: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram

Kesalahan Anda di sini bisa jadi salah satu yang umum, yang lain menulis di sini, tetapi secara umum, saya akan melihat dokumentasi tentang metode apa yang valid untuk dipanggil dalam status apa: http://developer.android.com/ referensi / android / media / MediaPlayer.html # Valid_and_Invalid_States

Dalam contoh saya, itu adalah metode mediaPlayer.CurrentPosition, yang saya panggil ketika pemutar media dalam keadaan, di mana ia tidak diizinkan untuk memanggil properti ini.

SimonSimCity
sumber
0

Saya memecahkan kesalahan (-19,0) dan (-38,0), dengan membuat objek baru MediaPlayer setiap kali sebelum bermain dan melepaskannya setelah itu.

Sebelum :

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();
        }
    });

}

}

Setelah:

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();
        }
    });

}

}

Saurabh Padwekar
sumber
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();
kamakshi
sumber
0

Itu sangat membuat frustrasi. Jadi, saya mendapatkan solusi yang cocok untuk saya.

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();
                    }
Aman Srii
sumber
0

Bagi saya ini berhasil

mp.seekTo(0);
mp.start();
Piyush Jajoo
sumber
0

Saya juga mendapatkan kesalahan ini saya mencoba dengan onPreparedListener tetapi masih mendapatkan kesalahan ini. Akhirnya saya mendapat solusi bahwa kesalahan adalah kesalahan saya karena saya lupa izin internet di Android Manifest xml. :)

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

Saya menggunakan pengkodean sampel untuk mediaplayer. Saya menggunakan metode StreamService.java
onCreate

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

Saya menemui masalah yang sama sebelumnya, teman di lantai pertama benar, Anda menelepon start()pada waktu yang salah, Anda harus menetapkan pendengar untuk preparasi () atau prepareSync()dengan metode ini mediaPlayer.setOnPreparedListener(this); sebelum bersiap, dalam panggilan panggilan balik inistart() . Ini mungkin menyelesaikan masalah Anda. Saya sudah mencoba.

tiada tara2012
sumber
Bisakah kamu lebih spesifik?
Karthik AMR
Maaf, bahasa Inggris bukan bahasa pertama saya, dan saya juga tidak pandai dalam hal itu ... tapi saya hanya ingin membantu orang lain yang memiliki pertanyaan yang sama, itu saja.
peerless2012
-1

Saya baru dalam pemrograman android dan saya memiliki kesalahan yang sama seperti ini. jadi saya cukup mendefinisikan ulang mp.createmediaPlayer = MediaPlayer.create (getApplicationContext (), Settings.System.DEFAULT_RINGTONE_URI). Ini mungkin bukan cara yang benar untuk melakukannya tetapi berhasil untuk saya:

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

mp.start();
Monsoon khadka
sumber
-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();
HuynhHan
sumber