Media Player được gọi ở trạng thái 0, lỗi (-38,0)


105

Tôi hiện đang cố gắng thiết kế một ứng dụng đơn giản phát trực tuyến đài phát thanh internet. Tôi có URL cho đài và đang thiết lập Media Player như

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

Chương trình không bị lỗi khi giả lập, nhưng không có gì đang phát và tôi gặp lỗi sau:

start called in state 0

và ngay bên dưới nó là

Error (-38,0)

Có ai biết điều này?

Tôi đã đọc một chút về các lỗi trạng thái này, nhưng không thể tìm thấy bất kỳ điều gì áp dụng cho dự án của tôi.




@SmashCode vui lòng đánh dấu một câu trả lời khác vì câu trả lời được chấp nhận vì câu trả lời của tôi là hoàn toàn vô ích.
tidbeck

Câu trả lời:


119

Bạn cần gọi mediaPlayer.start()trong onPreparedphương thức bằng cách sử dụng một người nghe. Bạn nhận được lỗi này vì bạn đang gọi mediaPlayer.start()trước khi nó đạt đến trạng thái chuẩn bị.

Đây là cách bạn có thể làm điều đó :

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

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

Nếu chúng ta không muốn nó bắt đầu ngay lập tức thì sao? Ngay cả khi tôi khởi tạo cầu thủ của tôi và chờ đợi một phút hoặc lâu hơn, lần đầu tiên tôi cố gắng để chơi nó, nó có lỗi này trừ khi tôi gọi .start () trong onPrepared
elliptica

1
Bạn chuẩn bị trước đó và nhớ là bạn đã chuẩn bị. Song song đó, bạn cố gắng nhớ xem bạn có muốn chạy nó không. Khi cả hai đều được chuẩn bị và bạn muốn chạy nó, bạn khởi động nó.
Victor Paléologue,

33

Có vẻ như Lỗi -38 có nghĩa là một ngoại lệ (như thông báo lỗi chỉ ra). Ví dụ: nếu bạn gọi start(), trước khi bài hát sẵn sàng hoặc khi bạn gọi pause(), ngay cả khi bài hát không phát.

Để khắc phục sự cố này, hãy kiểm tra trạng thái của mediaPlayer trước khi gọi các phương thức. Ví dụ:

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

Ngoài ra, MediaPlayer đang gửi tin nhắn sự kiện. Ngay cả khi bạn không cần sự kiện đã chuẩn bị (mặc dù bạn không nên bắt đầu phát lại trước khi sự kiện này được kích hoạt), bạn phải đặt một bộ nghe gọi lại. Điều này cũng đúng vớiOnErrorListener , OnCompletionListener, OnPreparedListenerOnSeekCompletedListener(nếu bạn gọi phương thức tìm kiếm).

Người nghe có thể được đính kèm đơn giản bằng

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

gọi tạm dừng () khi không chơi trình phát là trường hợp của tôi
stevo.mit

gọi mediaPlayer.isPlaying () ở trạng thái không hợp lệ sẽ đưa trình phát media vào trạng thái lỗi. Tốt hơn nên duy trì một enum rõ ràng để duy trì các trạng thái.
Madeyedexter,

14

Tôi gặp lỗi này khi cố gắng lấy vị trí hiện tại (MediaPlayer.getCurrentPosition ()) của trình phát đa phương tiện khi nó không có trong trạng thái đã nêu. Tôi đã giải quyết vấn đề này bằng cách Theo dõi trạng thái của nó và chỉ gọi phương thức getCurrentPosition () sau khi onPreparedListener được gọi.


Làm thế nào bạn tìm ra nó là vì lý do đó?
AdamMc331

9

Đây là mã của tôi, đã được kiểm tra và hoạt động tốt:

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

tôi đã kiểm tra mã dưới đây. làm việc tốt

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

Để và cập nhật để SetAudioStreamType(..)sử dụngSetAudioAttributes(...)
Pierre

4

Tôi gặp phải vấn đề tương tự vài ngày trước. MediaPlayer âm thanh của tôi hoạt động tốt trên các thiết bị có sức mạnh xử lý cao, nhưng đối với các thiết bị chậm, trình phát đa phương tiện không phát được một thời gian và từ LogCat, nhiều người phàn nàn về việc gọi sai trạng thái. Vì vậy, tôi đã giải quyết nó bằng cách gọi đặt lệnh gọi start () , pause () , ... trong phương thức onPrepared () của OnPreparedListener () như bên dưới:

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

                        }
                    });
                }
            });

Cũng cố gắng phát hành bất kỳ trình phát đa phương tiện nào mà bạn không cần nữa. Ví dụ: nếu bạn không muốn phát âm thanh hoặc video trên nền thì bạn nên gọi mediaPlayer.release () trong onPause () .


3

Đôi khi tệp được mã hóa theo cách mà Android không thể giải mã. Thậm chí một số tệp mp4 không thể chơi được. Vui lòng thử một định dạng tệp khác (.3gp được phát hầu hết thời gian) và xem ..


46
Tôi không thể yêu cầu đài phát thanh internet thay đổi định dạng tệp của họ.
SmashCode

Bạn có nhận được cửa sổ bật lên "Không thể phát video này" không? Làm thế nào để bạn đối phó với nó? Tôi bắt lỗi nhưng nhận được phương thức này bất kể và tôi không kiểm soát được nguồn phương tiện vì nó đến từ một API công khai. Nếu có ai biết cách ngăn chế độ "Không thể phát video này", tôi sẽ rất biết ơn.
Krafty

Bạn đã thử thiết lập một trình nghe lỗi. MediaPlayer mp = new MediaPlayer () {@Override public void setOnErrorListener (android.media.MediaPlayer.OnErrorListener player) {// Thực hiện nội dung tại đây ..}}; mp.setDataSource (..
Rukmal Dias

1

nhập mô tả hình ảnh ở đây

ở trên hình ảnh, bạn có thể nhận được đúng cách.


0

Bạn nhận được thông báo này trong nhật ký vì bạn làm điều gì đó không được phép trong trạng thái hiện tại của phiên bản MediaPlayer của bạn.

Do đó, bạn nên luôn đăng ký một trình xử lý lỗi để bắt những thứ đó (như @tidbeck đã đề xuất).

Lúc đầu, tôi khuyên bạn nên xem tài liệu về MediaPlayerlớp học và hiểu ý nghĩa của điều đó với các trạng thái. Xem: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram

Lỗi của bạn ở đây có thể là một trong những lỗi phổ biến, những lỗi khác đã viết ở đây, nhưng nói chung, tôi sẽ xem tài liệu về những phương thức nào hợp lệ để gọi ở trạng thái: http://developer.android.com/ tham chiếu / android / media / MediaPlayer.html # Valid_and_Invalid_States

Trong ví dụ của tôi, đó là phương thức mediaPlayer.CurrentPositionmà tôi đã gọi khi trình phát đa phương tiện ở trạng thái không được phép gọi thuộc tính này.


0

Tôi đã giải quyết cả hai lỗi (-19,0) và (-38,0), bằng cách tạo một đối tượng mới của MediaPlayer mọi lúc trước khi phát và phát hành nó sau đó.

Trước :

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

}

}

Sau:

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

Nó đã rất nhiều thất vọng. Vì vậy, tôi đã có giải pháp phù hợp với tôi.

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

Tôi cũng gặp lỗi này. Tôi đã thử với onPreparedListener nhưng vẫn gặp lỗi này. Cuối cùng tôi đã nhận được giải pháp rằng lỗi là lỗi của tôi vì tôi quên quyền truy cập Internet trong xml Android Manifest. :)

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

Tôi đã sử dụng mã hóa mẫu cho trung gian. Tôi đã sử dụng trong phương thức StreamService.java
onCreate

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

-1

Tôi đã gặp vấn đề tương tự ngay trước đó, người bạn ở tầng đầu tiên đã đúng, bạn gọi start()sai thời điểm, bạn nên đặt một người nghe cho phương thức chuẩn bị () hoặc prepareSync()phương thức này mediaPlayer.setOnPreparedListener(this); trước khi chuẩn bị, trong cuộc gọi lại này start(). Nó có thể giải quyết sự cố của bạn. Tôi đã thử rồi.


Bạn có thể đặc sắc hơn không?
Karthik AMR

Xin lỗi, tiếng Anh không phải là ngôn ngữ mẹ đẻ của tôi, và tôi cũng không giỏi nó ... nhưng tôi chỉ muốn giúp những người khác có cùng câu hỏi, vậy thôi.
peerless2012

-1

Tôi là người mới trong lập trình Android và tôi đã gặp lỗi tương tự như lỗi này. vì vậy tôi chỉ cần xác định lại mp.createmediaPlayer = MediaPlayer.create (getApplicationContext (), Settings.System.DEFAULT_RINGTONE_URI). Nó có thể không phải là cách thực sự để làm điều đó nhưng nó đã hiệu quả đối với tôi:

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();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.