Android의 내장 MediaPlayer 클래스를 사용하여 http를 통해 mp3를 스트리밍하려고했습니다. 문서는 이것이 다음과 같이 쉬워야한다고 제안합니다.
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(URL_OF_FILE);
mp.prepare();
mp.start();
그러나 나는 다음과 같은 것을 반복적으로 얻고 있습니다. 다른 URL도 시도했습니다. 스트리밍이 mp3에서 작동하지 않는다고 말하지 마십시오.
E/PlayerDriver( 31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
W/PlayerDriver( 31): PVMFInfoErrorHandlingComplete
E/MediaPlayer( 198): error (1, -4)
E/MediaPlayer( 198): start called in state 0
E/MediaPlayer( 198): error (-38, 0)
E/MediaPlayer( 198): Error (1,-4)
E/MediaPlayer( 198): Error (-38,0)
많은 도움을 주셔서 감사합니다.
답변
스트리밍 예제가있는 간단한 미디어 플레이어. xml 부분의 경우 id button1이있는 버튼 하나와 이름이 button_pause 및 button_play 인 드로어 블 폴더에 두 개의 이미지가 필요하며 매니페스트에 인터넷 권한을 추가하는 것을 잊지 마십시오.
public class MainActivity extends Activity {
private Button btn;
/**
* help to toggle between play and pause.
*/
private boolean playPause;
private MediaPlayer mediaPlayer;
/**
* remain false till media is not completed, inside OnCompletionListener make it true.
*/
private boolean intialStage = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.button1);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
btn.setOnClickListener(pausePlay);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
private OnClickListener pausePlay = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
if (!playPause) {
btn.setBackgroundResource(R.drawable.button_pause);
if (intialStage)
new Player()
.execute("http://www.virginmegastore.me/Library/Music/CD_001214/Tracks/Track1.mp3");
else {
if (!mediaPlayer.isPlaying())
mediaPlayer.start();
}
playPause = true;
} else {
btn.setBackgroundResource(R.drawable.button_play);
if (mediaPlayer.isPlaying())
mediaPlayer.pause();
playPause = false;
}
}
};
/**
* preparing mediaplayer will take sometime to buffer the content so prepare it inside the background thread and starting it on UI thread.
* @author piyush
*
*/
class Player extends AsyncTask<String, Void, Boolean> {
private ProgressDialog progress;
@Override
protected Boolean doInBackground(String... params) {
// TODO Auto-generated method stub
Boolean prepared;
try {
mediaPlayer.setDataSource(params[0]);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
intialStage = true;
playPause=false;
btn.setBackgroundResource(R.drawable.button_play);
mediaPlayer.stop();
mediaPlayer.reset();
}
});
mediaPlayer.prepare();
prepared = true;
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
Log.d("IllegarArgument", e.getMessage());
prepared = false;
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
prepared = false;
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
prepared = false;
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
prepared = false;
e.printStackTrace();
}
return prepared;
}
@Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (progress.isShowing()) {
progress.cancel();
}
Log.d("Prepared", "//" + result);
mediaPlayer.start();
intialStage = false;
}
public Player() {
progress = new ProgressDialog(MainActivity.this);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
this.progress.setMessage("Buffering...");
this.progress.show();
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if (mediaPlayer != null) {
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
}
}
답변
Android MediaPlayer는 2.2까지 기본적으로 MP3 스트리밍을 지원하지 않습니다. 이전 버전의 OS에서는 기본적으로 3GP 만 스트리밍하는 것으로 보입니다. pocketjourney 코드가 오래되었지만 ( 여기에 새 버전이 있습니다 ) 사용해 볼 수 있습니다. 끈적하게 만드는 데 어려움이있었습니다. 버퍼를 다시 채울 때마다 끊김이 발생했습니다.
Android 용 NPR News 앱은 오픈 소스이며 로컬 프록시 서버를 사용하여 2.2 이전 OS 버전에서 MP3 스트리밍을 처리합니다. 199-216 행 (r94)의 관련 코드는 http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/ 에서 확인할 수 있습니다 . PlaybackService.java?r=7cf2352b5c3c0fbcdc18a5a8c67d836577e7e8e3
그리고 이것은 StreamProxy 클래스입니다 : http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java?r=e4984187f45c39a54ea6c88f71197762dbe10e72
NPR 앱은 스트리밍하는 동안 가끔 “오류 (-38, 0)”가 발생합니다. 스레딩 문제 또는 네트워크 변경 문제 일 수 있습니다. 이슈 트래커에서 업데이트를 확인하십시오 .
답변
나는 당신이 .pls를 직접 또는 비슷한 것을 재생하려고 시도하고 있다고 생각합니다.
이것을 시도하십시오 :
1 : 코드
mediaPlayer = MediaPlayer.create(this, Uri.parse("http://vprbbc.streamguys.net:80/vprbbc24.mp3"));
mediaPlayer.start();
2 : .pls 파일
이 URL은 예를 들어 BBC에서 가져온 것입니다. Linux에서 다운로드 한 .pls 파일이었습니다.
wget http://foo.bar/file.pls
그런 다음 vim (좋아하는 편집기 사용;)으로 열었고이 파일 내부의 실제 URL을 보았습니다. 불행히도 모든 .pls가 그런 일반 텍스트는 아닙니다.
1.6이 http를 통한 mp3 스트리밍을 지원하지 않는다고 읽었지만 Android 1.6 및 2.2에서 obove 코드를 테스트했으며 문제가 없었습니다.
행운을 빕니다!
답변
사용하다
mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaplayer.prepareAsync();
mediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaplayer.start();
}
});
답변
나는 당신과 같은 오류가 있었고 코드에 아무런 문제가 없다는 것이 밝혀졌습니다. 문제는 웹 서버가 잘못된 Content-Type 헤더를 보내고 있다는 것입니다.
wireshark 또는 이와 유사한 것을 시도하여 웹 서버가 보내는 콘텐츠 유형을 확인하십시오.
답변
내 프로젝트를 찾고 :
- https://github.com/master255/ImmortalPlayer http / FTP 지원, 읽기, 전송 및 캐시 데이터 저장을위한 하나의 스레드. 가장 간단한 방법과 가장 빠른 작업. 복잡한 논리-최선의 방법!
- https://github.com/master255/VideoViewCache 캐시가있는 간단한 Videoview. 재생 및 데이터 저장을위한 두 개의 스레드. 잘못된 논리이지만 필요한 경우 이것을 사용하십시오.
답변
로그에서 0 상태를 피하기 위해 OnPreparedListener로 mp.start를 호출하지 않습니다.