마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

E/MediaPlayer: Error (-38,0) 경고가 뜨고 재생이 안됩니다.

0 추천

재생 버튼을 클릭시에 -38 ( 재생을 준비할 완료가 되지 않았을경우 뜨는 에러 )
가 뜨더군요..

최신 SDK 업데이트 이후 이런 문제가 생겨요..

 

import android.media.MediaPlayer;
import android.media.MediaPlayer.OnInfoListener;

public class PlayerFunctions {

	/* 글로벌 선언 */
	static Boolean FirstLoad = true;
	static TimerTask MyTimerTask;

	public static boolean FromChart = true;
	public static int CurrentMusicIndex = -1;
	public static boolean PlayerLoop = false;
	public static boolean PlayerShuffle = false;
	public static boolean IsPreparing = false;
	public static boolean IsBuffering = false;

	/* 음악 목록 및 플레이어 선언 */
	public static ArrayList<Music> MusicArrayList;
	public static MediaPlayer MyMediaPlayer = new MediaPlayer();

	/* 잠금 화면 리모트 컨트롤러 선언 */
	public static RemoteController RemoteController = null;

	public static void PlayerPlay(final Activity MyActivity, final Music MyMusic, final boolean fromChart) {
		FromChart = fromChart;
		if (IsPreparing == false) {
			try {
				// 플레이어 설정
				MyMediaPlayer.stop();
				MyMediaPlayer.reset();
				MyMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
				if (Build.MANUFACTURER.toLowerCase(Locale.getDefault()).equals("samsung")) {
					MyMediaPlayer.setDataSource(MyMusic.Source);
				} else {
					Map<String, String> headers = new HashMap<String, String>();
					headers.put("Range", "bytes=0-0");
					MyMediaPlayer.setDataSource(MyActivity, Uri.parse(MyMusic.Source), headers);
				}

				// 플레이어 준비
				IsPreparing = true;

				// - For MainActivity
				if (MainActivity.MyActivity != null) {
					MainActivity.TextTitle.setText(MyMusic.Name);
					MainActivity.TextTime.setText("버퍼링 중...");
				}

				// - For ChartActivity
				if (ChartActivity.MyActivity != null) {
					ChartActivity.TextTitle.setText(MyMusic.Name);
					ChartActivity.TextTime.setText("버퍼링 중...");
				}

				MyMediaPlayer.prepareAsync();

				// 리모트 컨트롤러 설정
				if (RemoteController == null && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
					RemoteController = new RemoteController();
					RemoteController.register(MyActivity);
				}

				// 재생 정보 변경 이벤트 초기화
				MyMediaPlayer.setOnInfoListener(new OnInfoListener() {
					@Override
					public boolean onInfo(MediaPlayer mp, int what, int extra) {
						if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
							IsBuffering = true;
						} else if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
							IsBuffering = false;
						}

						return true;
					}
				});

				// 재생 준비 완료 이벤트 초기화
				MyMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
					@Override
					public void onPrepared(MediaPlayer mp) {
						MyMediaPlayer.start();

						// 정보 기본값 설정
						int Duration = MyMediaPlayer.getDuration();
						int CurrentPosition = MyMediaPlayer.getCurrentPosition();

						// - For MainActivity
						if (MainActivity.MyActivity != null) {
							MainActivity.MusicSeekBar.setMax(Duration);
							MainActivity.TextTime.setText(getTimeString(CurrentPosition) + " / " + getTimeString(Duration));
						}

						// - For ChartActivity
						if (ChartActivity.MyActivity != null) {
							ChartActivity.MusicSeekBar.setMax(Duration);
							ChartActivity.TextTime.setText(getTimeString(CurrentPosition) + " / " + getTimeString(Duration));
						}

						if (FirstLoad == true) {
							MyTimerTask = new TimerTask() {
								@Override
								public void run() {
									if (MyMediaPlayer.isPlaying()) {
										MyActivity.runOnUiThread(new Runnable() {
											@Override
											public void run() {
												int Duration = PlayerFunctions.MyMediaPlayer.getDuration();
												int CurrentPosition = PlayerFunctions.MyMediaPlayer.getCurrentPosition();

												// - For MainActivity
												if (MainActivity.MyActivity != null) {
													MainActivity.MusicSeekBar.setMax(Duration);
													MainActivity.MusicSeekBar.setProgress(CurrentPosition);
													MainActivity.TextTime.setText(getTimeString(CurrentPosition) + " / " + getTimeString(Duration));
												}

												// - For ChartActivity
												if (ChartActivity.MyActivity != null) {
													ChartActivity.MusicSeekBar.setMax(Duration);
													ChartActivity.MusicSeekBar.setProgress(CurrentPosition);
													ChartActivity.TextTime.setText(getTimeString(CurrentPosition) + " / " + getTimeString(Duration));
												}

												// 권한 검사 이벤트
												if (CurrentPosition >= 120000 && MainActivity.currentHTML != null) {
													// - LOGIN CHECK
													if (MainActivity.currentHTML.contains("isLogged:true")) {
														if (MainActivity.currentHTML.contains("isCoupon:false") && MainActivity.currentHTML.contains("isActiveMember:false")) {
															PlayerNext(MyActivity, fromChart);
														}
													} else {
														PlayerNext(MyActivity, fromChart);
													}
												}
											}
										});
									}
								}
							};
							Timer MyTimer = new Timer();
							MyTimer.schedule(MyTimerTask, 0, 1000);
							FirstLoad = false;
						}

						// 재생 완료 이벤트 초기화
						MyMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
							@Override
							public void onCompletion(MediaPlayer mp) {
								if (IsPreparing == false && IsBuffering == false) {
									// 재생 형식 설정
									if (PlayerLoop) {
										PlayerLoop(MyActivity, fromChart);
									} else if (PlayerShuffle) {
										PlayerShuffle(MyActivity, fromChart);
									} else {
										PlayerNext(MyActivity, fromChart);
									}
								}
							}
						});

						// 정보 갱신
						UpdatePlayer(false);

						// 준비 완료
						IsPreparing = false;
					}
				});

 

botserv (210 포인트) 님이 2019년 9월 5일 질문

1개의 답변

0 추천
 
채택된 답변

맨위 MyMediaPlayer.stop(); 부르는데가 문제인 듯 합니다

-38 은 invalid state를 의미 하는 것으로  

https://developer.android.com/reference/android/media/MediaPlayer#StateDiagram 에 나오듯

MediaPlayer를 new 하면 idle 상태이며, stop을 부르면 

https://developer.android.com/reference/android/media/MediaPlayer#Valid_and_Invalid_States 에 보시듯 에러가 납니다.

reset 만 해도 되니 해당 부분을 빼고 돌려 보시는게 좋을 듯 합니다.

 

PS. prepareAsync 이후에 setOnPreparedListener 를 부르면 가능성이 낮긴 하지만. 이벤트 리스너등록하는 타이밍보다 실제 OnPrepared 이벤트가 발생하는 시간이 빨라  OnPrepared 이벤트를 받지 못 할 수 있을 듯 합니다. setOnInfoListener, setOnPreparedListener, setOnCompletionListener 같은 이벤트 리스너는 prepareAsync 이전에 호출하시는걸 추천합니다.

 

 

익명사용자 님이 2019년 9월 5일 답변
botserv님이 2019년 9월 6일 채택됨
안녕하세요. 귀한 시간 내주셔서 확인하시고 답변 남겨주셔서 감사합니다.

저는 프로그래밍을 할줄모르는데 답답한 마음에 구글 이곳저곳을찾아다니면서
해결 방법을 찾고 있습니다.

제작업데이트를 드렸더니 해결보다 지속적으로 추가금을 요구하시는 터에 ㅠ_ㅠ

MyMediaPlayer.stop();  이 부분의 코드를 주석처리하고 프로그램을 돌려보시란 말씀이신거죠?
해당 부분을 주석하고 재생 버튼을 눌러보니
이번에 코드가 조금 다르게 바뀌었어요..

V/MediaHTTPService: makeHTTPConnection: CookieManager created: java.net.CookieManager@8af826
    makeHTTPConnection(android.media.MediaHTTPService@c8c6f81): cookieHandler: java.net.CookieManager@8af826 Cookies: null
I/Choreographer: Skipped 65 frames!  The application may be doing too much work on its main thread.
E/eglCodecCommon: glUtilsParamSize: unknow param 0x000085b5
E/eglCodecCommon: glUtilsParamSize: unknow param 0x000085b5
I/OpenGLRenderer: Davey! duration=1204ms; Flags=0, IntendedVsync=1160666267264, Vsync=1161749600554, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=1161751033560, AnimationStart=1161751123640, PerformTraversalsStart=1161751171840, DrawStart=1161819969130, SyncQueued=1161824780980, SyncStart=1161824859990, IssueDrawCommandsStart=1161824945720, SwapBuffers=1161867640080, FrameCompleted=1161871031290, DequeueBufferDuration=416000, QueueBufferDuration=815000,
D/: PlayerBase::stop() from IPlayer
D/AudioTrack: stop() called with 480388 frames delivered
E/MediaPlayerNative: error (1, -2147483648)
E/MediaPlayer: Error (1,-2147483648)
아 디버그 상에서만 이렇게 뜨는거고 실제로 앱에선 잘 재생되네요

넘나 감사합니다 ㅠ_ㅠ
...