簡體   English   中英

ANDROID:MediaPlayer 顯示錯誤 (1, -19)

[英]ANDROID: MediaPlayer shows error (1, -19)

我正在開發一個播放從ArrayList挑選的歌曲的Service 當我使用prepare()prepareAsync()方法時問題就出現了,所以這里是代碼:

public class MusicService extends Service implements MediaPlayer.OnPreparedListener{
    private final static int DEF_VALUE = -1;
    private Context mContext;
    private ArrayList<Song> mSongsList;
    private MediaPlayer mPlayer;
    private boolean isPlaying = false;
    private int mPosition;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate(){
        super.onCreate();
        mContext = getApplicationContext();
        mSongsList = new ArrayList<Song>();
        mPlayer = new MediaPlayer();
        setMusicPlayer();
    }

    public void setMusicPlayer(){
        //Setting player properties
        mPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
        mPlayer.setAudioSessionId(AudioManager.STREAM_MUSIC);
        mPlayer.setOnPreparedListener(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int mCommand = intent.getIntExtra("CMD", DEF_VALUE);
        int mTrackSelected = intent.getIntExtra("TRACK_CLICKED", DEF_VALUE);

        /** SERVICE COMMANDS
         *  0 = SERVICE PERMISSIONS
         *  1 = PLAY_PAUSE
         *  2 = NEXT TRACK
         *  3 = PREV TRACK
         *  4 = SONG IN LIST
         */

        switch (mCommand){
            case 0:
                GetTracks mGetSongs = new GetTracks();
                mSongsList = mGetSongs.listAllSongs(mContext);
                Log.d("test size arrayList", ""+mSongsList.size());
                break;
            case 1:
                setPlayPause();
                break;
            case 2:
                skipNextTrack();
                break;
            case 3:
                skipPrevTrack();
                break;
            case 4:
                if(mTrackSelected != DEF_VALUE){
                    mPosition = mTrackSelected;
                    setSongToPlay(mPosition);
                }
                break;
            default:
                Log.d("error cmd", "You shouldn't be here!");
                break;
        }

        return START_STICKY;
    }

    private void skipPrevTrack() {
        Log.d("method called:", "skipPrevTrack()");
        if(mPosition == 0){
            setSongToPlay(mPosition = mSongsList.size()-1);
        } else setSongToPlay(--mPosition);
        Log.d("test mPosition service", ""+mPosition);
    }

    private void skipNextTrack() {
        Log.d("method called:", "skipNextTrack()");
        if(mPosition == mSongsList.size()-1){
            setSongToPlay(mPosition = 0);
        } else setSongToPlay(++mPosition);
        Log.d("test mPosition service", ""+mPosition);
    }


    private void setSongToPlay(int pos) {
        Log.d("method called:", "setSongToPlay("+pos+")");
        startSong(mSongsList.get(pos).getSongUri());
    }
    private void startSong(Uri uri){

        try{
            mPlayer.reset();
            mPlayer.setDataSource(mContext, uri);
            mPlayer.prepareAsync();

            /** +++WORKS FINE WITH THIS CODE+++
             mPlayer = MediaPlayer.create(mContext, uri);
             mPlayer.start();
             */

        } catch (Exception e){
            e.printStackTrace();
        }
    }

    private void setPlayPause() {
        Log.d("method called:", "setPlayPause()");
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.start();
    }
}

日志:

 12-19 16:12:18.325 4013-4013/sebbsoft.myApp D/method called:: setSongToPlay(3)
12-19 16:12:18.341 4013-4013/sebbsoft.myApp D/test song playing: Fiori del male ft. Sfera Ebbasta
12-19 16:12:18.363 4013-4013/sebbsoft.myApp D/MediaPlayer: setSubtitleAnchor in MediaPlayer
12-19 16:12:18.428 4013-4028/sebbsoft.myApp E/MediaPlayer: error (1, -19)

我該如何解決?

終於解決了! 經過大量的試驗和錯誤!! 這是我的原因:

mMediaPlayer.setAudioSessionId(AudioManager.STREAM_MUSIC);

setAudioSessionId 的 API 文檔沒有指出任何替代方案或任何問題,仍然使用它使調試變得困難。 但是我在它的下方看到了 setAudioStreamType,它已被棄用,並建議使用setAudioAttributes,而在 API 21 中添加了 w/c。

所以我把上面的代碼改成這樣:

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        mMediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .build());
} else {
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}

現在它起作用了!

順便說一句,正如您所看到的,我只檢查了版本 N(API 24)及更高版本,而不是 LOLLIPOP,即使在 API 21 中添加了setAudioAttributes ,因為我只在牛setAudioSessionId糖設備上遇到這個問題, setAudioSessionId適用於 Marshmallow 設備對我來說......不想破壞任何已經在工作的東西。

我確實希望有人能停下來解釋為什么會發生這種情況以及錯誤的真正含義。

希望這可以節省任何人的頭痛天:)

編輯:對於任何在谷歌上搜索的人,我也將原來的mMediaPlayer.setAudioSessionId更改為mMediaPlayer.setAudioStreamType ,正如Eugen Pechanec所指出的。 有關詳細信息,請參閱他的評論和答案。 您還想從檢查Build.VERSION_CODES.N更改為Build.VERSION_CODES.LOLLIPOP

您錯誤地使用了setAudioSessionId

音頻會話 ID 是此 MediaPlayer 實例播放的音頻流的系統范圍唯一標識符

[...]

創建后, MediaPlayer 實例會自動生成自己的音頻會話 ID 但是,可以通過調用此方法強制此播放器成為現有音頻會話一部分 必須在重載的setDataSource方法之一之前調用此方法。

您將通過調用AudioManager.generateAudioSessionId()獲取音頻會話 ID。


如果您想設置流類型,您可能正在尋找的是MediaPlayer.setAudioStreamType(int)

自 Android 5 以來可用的較新 API 是MediaPlayer.setAudioAttributes(AudioAttibutes)

確保您沒有同時激活過多的MediaPlayer對象。

實現OnCompletionListener並將其注冊到您的MediaPlayer實例。 onCompletion在播放過程中到達媒體源的末尾時調用。

void onCompletion(MediaPlayer mp){
   //Here you stop it.
   mp.stop();
   mPlayer.reset()
   //Reset the data source path to the new file
   mp.setDataSource(<uri>);
   mPlayer.prepare(); // or mPlayer.prepareAsync();
   // start the mediaplayer after the prepare has completed.
}

播放完所有文件后,釋放mediaplayer實例。


可能是你的聽眾只聽了一次,然后當它在沒有准備的情況下嘗試播放下一個時,它會崩潰..也試試這個

添加這個 --> mPlayer.setOnPreparedListener(this); prepareAsync之前的startSong()方法中

我有同樣的問題。 將許多不同的音頻上傳到媒體播放器。

15 次后它停止工作。

我只是在每次在同一個媒體播放器中上傳新音頻之前添加發布,這對我有用!

不再有錯誤 (1, -19)

希望有幫助!

我遇到了同樣的問題,我通過添加以下代碼來釋放播放器來解決它:

1-獲取音頻使用資產文件

MediaPlayer mediaPlayer = new MediaPlayer();
AssetFileDescriptor afd;  
mediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
         mediaPlayer.prepare();
          mediaPlayer.start();
        mp1.setOnCompletionListener(new OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
                mp.release();}; });

2-獲取音頻使用 res/raw 文件夾。

mp1 = MediaPlayer.create(sound.this, R.raw.pan1);
mp1.start();
mp1.setOnCompletionListener(new OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {
        mp.release();

    }; });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM